Skip to content

pyproject.toml justifies suppressing Sonar S8565 (lock file) with a determinism premise that does not hold, plus a lapsed v0.6.x lock-file commitment (CR-A16-086) #532

Open

Description

@cemililik

Wave 2 · theme D2-7: Next-release technology updates · highest severity Low · 5 finding(s) · effort medium

Summary

A maintainer or Sonar reviewer reads the NOSONAR rationale and accepts the claim of 'supply-chain determinism'. Two release-matrix runs of the same tag, or a re-run a week later, resolve different torch/transformers/trl versions inside the ranges. Previously reported findings show that in-range versions break trainers (warmup_ratio, GRPO max_prompt_length, peft/torch floor). The pip-audit scan and the SBOM only describe the drift after it happens, the analyser rule that would flag the missing lock stays suppressed, and the v0.6.x commitment has silently expired.

Primary finding

CR-A16-086 — pyproject.toml justifies suppressing Sonar S8565 (lock file) with a determinism premise that does not hold, plus a lapsed v0.6.x lock-file commitment

severity Low · reachability default · intent intended-but-harmful · confidence likely · independently confirmed · not reproduced (code trace)

What happens. pyproject.toml:1-7 suppresses Sonar text:S8565 ("Sonar wants a deterministic uv.lock / poetry.lock"). Its stated reason is that "supply-chain determinism is provided instead by (a) bounded dependency ranges ..., (b) pip-audit nightly gating ..., (c) per-OS CycloneDX SBOM emission in publish.yml". It adds that a requirements.lock workflow is "tracked ... (v0.6.x)". This is a category error, and it is not the same defect as M5r1-A16-010 or M-A16-021. Those findings say that (c) records the wrong environment and that (b) scans too few extras. This one says that even a perfect SBOM and a full-coverage audit would not make resolution deterministic. A scanner detects vulnerabilities and an SBOM records what was installed. Neither fixes which versions pip resolves. (a) Bounded ranges admit a whole major line for each of the 12 core dependencies (pyproject.toml:45-61, e.g. torch>=2.4.0,<3.0.0). Six extras (unsloth, wandb, mlflow, deepspeed, llama-cpp-python, rich) and the dev deps carry no upper bound. The build requirement wheel is unbounded and setuptools uncapped. No lock or constraints file exists, and no workflow installs with constraints or --require-hashes (publish.yml:72-85; nightly.yml:46-57 and 296-307). The lock-file target 'v0.6.x' lies five minor lines behind the shipping version 0.11.1rc1 (pyproject.toml:19), and no lock exists in the snapshot. Even as planned, the lock would cover only 'development environments', not the release or test environment. The suppression therefore rests on a false premise and silences the one analyser rule that points at the real gap, while keeping an expired commitment.

Where.

Evidence.

  • Static: pyproject.toml lines 1-7 quoted above. A tomllib/packaging scan of the snapshot's pyproject (deps.py run via fpy) gave: core 12 deps with 0 unbounded; unbounded = ['unsloth>=2024.3.0; linux', 'wandb>=0.16.0', 'mlflow>=2.9.0', 'deepspeed>=0.14.0; !win32', 'llama-cpp-python>=0.2.90; !win32', 'rich>=13.0.0', 'pytest>=8.0.0', 'pytest-cov>=5.0.0', 'packaging>=23.0', 'tomli>=2.0.0']; build requires ['setuptools>=83.0.0', 'wheel']. The snapshot root contains only requirements.txt, requirements…

Recommended fix. Do not describe pip-audit or the SBOM as determinism controls. Either generate a pip-compile/uv lock or constraints file and use it in CI and publish, or drop the suppression or reword it as an accepted risk with an owner and a current target version.

Other findings with the same root cause

These close with the same fix; update them in the same pull request.

  • CR-A16-095 (code, Low) — Docker docs promise reproducible runs ('same image, same behaviour'), but every build resolves a mutable base tag and unlocked latest dependencies, and run artefacts record no dependency versions
    severity Low · reachability default · intent intended-but-harmful · confidence likely · independently confirmed · reproduced (plumbing only)
    Failure scenario. Team A builds the image in January and team B rebuilds the same commit in October for an on-prem cluster. The images contain, for example, transformers 5.3 and 5.18 and different trl/peft/accelerate. Training and benchmark-gate results differ, and the compliance manifest of both runs reads forgelm_version=0.11.1rc1 with no way to tell which stack ran. The docs promised 'same behaviour'.
    Where. docs/usermanuals/en/operations/docker.md:8, docs/usermanuals/tr/operations/docker.md:8, Dockerfile:52-67, Dockerfile:33-39
    Recommended fix. Either soften docker.md:3,8 (and the TR mirror) to 'containerised runs; build once and push to your registry for reproducibility', or back the claim: pin the base by digest, install from a constraints/lock file with hashes, emit an image SBOM, and record the resolved versions of key libraries (torch, transformers, trl, peft, accelerate, datasets, CUDA) in the training manifest.

  • TECH-T12-009 (technology, Next release) — Supply-chain tooling, network dependencies and vulnerability scanning: Lock file and reproducibility (no lockfile; PEP 751 pylock.toml) (aging)
    severity Next release
    Item. Lock file and reproducibility (no lockfile; PEP 751 pylock.toml) · verdict: aging · urgency: Next release
    State in ForgeLM. pyproject.toml:1-7 suppresses Sonar S8565 and says a pip-tools requirements.lock is tracked as F-PR29-A6-lock-file for v0.6.x (docs/roadmap/risks-and-decisions.md:99, status TBD); no lockfile exists; the project is at 0.11.1rc1; CI, release and SBOM jobs resolve unpinned latest; requirements.txt is a stale, unreferenced list.
    State of the ecosystem on 2026-10-01. PEP 751 (pylock.toml) has been Final since 2025-03-31 and is a PyPA specification. pip 26.1 (2026-04-26) added experimental pip install -r pylock.toml and pip lock; pip 26.2.1 is current. pip-audit audits pylock files (--locked). OpenSSF Scorecard tells applications to check in lock files. No PyPA text requires libraries to commit a lock file.
    Recommendation. Commit a generated pylock.toml (or hash-pinned constraints) for the release/CI environment and the Docker image, generate the SBOM from it, keep the range-based nightly, and update the stale v0.6.x note; delete or regenerate requirements.txt.
    Sources.

  • DOC-D2B09-035 (docs, Low) — docs/roadmap/risks-and-decisions.md: stale — F-PR29-A5-anchor-slugifier — local checker collapses -+ → -; duplicate-heading disambiguation missing
    severity Low
    Where. docs/roadmap/risks-and-decisions.md:96 · type: stale
    The document says. F-PR29-A5-anchor-slugifier — local checker collapses -+ → -; duplicate-heading disambiguation missing
    What the code does. The multi-dash collapse was removed (the checker now mirrors GFM, F-P8-C-14). Duplicate-heading -1/-2 disambiguation is still absent, so only half of the row remains open.
    Code references. tools/check_anchor_resolution.py:143-163
    Proposed correction. Addendum: "(i) fixed; (ii) duplicate-heading suffixing still open."

  • DOC-D2B09-036 (docs, Low) — docs/roadmap/risks-and-decisions.md: stale — F-PR29-A2-13 — library-api-design.md ... ~7 downstream sentences still reference forgelm/api.py
    severity Low
    Where. docs/roadmap/risks-and-decisions.md:97 · type: stale
    The document says. F-PR29-A2-13 — library-api-design.md ... ~7 downstream sentences still reference forgelm/api.py
    What the code does. No library-api-design.md exists. The design doc is docs/design/library_api.md and it has zero forgelm/api.py references.
    Code references. docs/design/library_api.md
    Proposed correction. Add an addendum closing the row (the file was renamed to library_api.md and the references were swept).

Acceptance criteria

  • A regression test reproduces the failure scenario and asserts the corrected behaviour.
  • Documentation listed above is corrected in English and in its Turkish mirror in the same PR.
  • Every finding in this issue is resolved or explicitly closed with a reason.

Found by the October 2026 ForgeLM code and documentation review against commit cab2947. Code links point at that commit; line numbers may have moved since. Finding IDs (CR-…, DOC-…, TECH-…) are stable references for this backlog.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: packaging-ciCode area: packaging-cibugSomething isn't workingdependenciesDependency or ecosystem currencydocumentationImprovements or additions to documentationsecuritySecurity-relevantseverity: lowMinor defect, inaccuracy or rough edgesource: review-2026-10Found by the October 2026 code and documentation reviewurgency: next-releaseTechnology currency: fix in the next releasewave: 2Roadmap wave 2: high severity, larger effort; next-release tech

    Type

    No type

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions