Skip to content

Slopmeter v0.3.0

Choose a tag to compare

@fdsprod fdsprod released this 19 Sep 00:17
· 153 commits to main since this release

Slopmeter v0.3.0 adds configured clone boundaries and persistent review decisions. It also makes clone-driven rankings and callable complexity easier to interpret.

No scoring change: the default remains py-2026.3 / M4 version 3. Calibration resources, weights, thresholds, and default exclusions are unchanged. Running v0.2.0 and this implementation on identical source produced identical raw metrics, scores, callable facts, coverage, clone groups, and pattern findings. No project-specific tuning was applied.

Configure architectural boundaries

Create slop.toml in the directory you use as the scan root:

[[boundaries]]
name = "provider-a"
prefix = "src/providers/a"

[[boundaries]]
name = "provider-b"
prefix = "src/providers/b"

Or put the declarations in pyproject.toml:

[[tool.slop.boundaries]]
name = "provider-a"
prefix = "src/providers/a"

[[tool.slop.boundaries]]
name = "provider-b"
prefix = "src/providers/b"
  • Prefixes are project-relative paths, not globs. Names and normalized prefixes must each be unique. Absolute paths, parent traversal, and glob syntax are rejected.
  • The longest matching path-component prefix wins. A declaration for src/providers/a overrides a broader declaration for src/providers. A prefix for src/providers/a does not match src/providers/another.
  • Config is loaded from the scan root. A subdirectory scan does not inherit its parent's config. Adjust declarations to the root used by that scan.
  • When both files define boundaries, the slop.toml list replaces the pyproject.toml list.

Clone reports then show:

Relation Meaning
within-boundary Every occurrence belongs to the same declared boundary.
cross-boundary Every occurrence is assigned, across two or more boundaries.
unknown At least one occurrence is unassigned.

View the labels with slop findings --root . --lang py --metric m3 or slop explain PATH --root ..

Labels annotate real duplicates. They do not suppress findings, lower scores, change rankings, or establish whether extraction is appropriate. Preserve deliberate isolation when the architecture requires it, with a review reason.

Retain clone review decisions

First inspect a clone group and copy its ID from findings. Replace CLONE_ID below:

slop findings --root . --lang py --metric m3
slop review set CLONE_ID --root . --store reviews.json --disposition no-change --reason "These adapters evolve under separate contracts." --next-step "Recheck each adapter when the contract changes."
slop score . --lang py --reviews reviews.json
slop findings --root . --metric m3 --reviews reviews.json --json
slop review show --root . --store reviews.json --json
  • Dispositions: actionable, defer, or no-change. A reason is required; the next step is optional.
  • Only review set writes. Ordinary scans and review show read the explicitly selected store. Stores are not discovered or created automatically.
  • current means the retained clone evidence, member-file hashes, boundary policy, and clone measurement definition still match.
  • stale means the previous decision needs review. Even a comment-only change can invalidate it. This release hashes whole member files, so an unrelated edit in one can also require review.
  • missing means evidence is absent or unavailable. It is not proof of a fix.
  • Re-running review set for the same group ID replaces its saved decision. Reinspect changed evidence before doing this.

Review annotations do not hide evidence or change scores. Persistence currently covers clone groups on the current snapshot side. Use separate stores for independent scan roots. Stores contain relative locations, hashes, and review text, not source code. Keep private review stores local unless separately approved for sharing.

Clearer evidence presentation

  • File and tree rankings include clone percentages, including at narrow widths.
  • Callable rows label retained mass as full-CC mass. Explanations separately show effective CC, effective mass, the M4 numerator, threshold, and selected basis.
  • Pattern findings (0) explicitly counts pattern rules; it does not imply that complexity or clone evidence is absent.
  • A production callable whose threshold crossing comes from assertions gets a classification-review hint. It remains production-classified, and its score is unchanged. Inspect intent before moving tests or changing file-level classification.

Report compatibility and limitations

New JSON reports add exact source_sha256 values to file results. Configured clone groups gain boundary_context; loading a review store adds review_results. Older reports remain readable, but reports without source hashes cannot create or confirm a current source-bound decision. The existing callable mass field retains its full-CC meaning.

Python remains the only implemented language. The reference corpus still has the same six historical projects. These features improve review context; they do not establish a representative service-specific calibration or turn the score into a CI quality gate.

Validation

GitHub CI passed static checks and all nine test/package jobs across Windows, macOS, and Linux with Python 3.12, 3.13, and 3.14. A cross-platform golden fixture was corrected to use explicit LF source bytes; production source hashing remains byte-exact.

  • 1,290 deterministic tests passed with 96.98% branch-inclusive coverage before the version-only release update.
  • 50 dependency-learning tests passed. The 73 new workflow and integrity checks also passed on Python 3.13 and 3.14.
  • All 40 release-version, boundary-config, and review-CLI checks passed.
  • The v0.3.0 wheel and source archive passed four isolated installation checks.
  • Regression tests cover unchanged scores, current/stale/missing reviews, source edits, policy changes, imported-report tampering, locks, and atomic-write failures.

Install

Download the wheel below and run:

python -m pip install --upgrade ./slop_measure-0.3.0-py3-none-any.whl
slop score . --lang py --scope all --top 10

Requires Python 3.12 or later. SHA256SUMS.txt covers the wheel and source archive. This is a GitHub release, not a PyPI publication.

Full usage and configuration