Skip to content

fix: single source of truth for version — closes #37#77

Merged
Wolfvin merged 1 commit into
mainfrom
fix/37-version-drift
Jun 28, 2026
Merged

fix: single source of truth for version — closes #37#77
Wolfvin merged 1 commit into
mainfrom
fix/37-version-drift

Conversation

@Wolfvin

@Wolfvin Wolfvin commented Jun 28, 2026

Copy link
Copy Markdown
Owner

What changed

Establishes scripts/utils.py:CODELENS_VERSION as the single source of truth for the CodeLens version. All other version mentions now match this constant or are stripped entirely.

Issue #37 reported 4 different version values across 6 files (pyproject.toml=7.2.0, skill.json=7.2.0, utils.py=8.0.0, README.md=v8.2, SKILL.md=v8.1, SKILL-QUICK.md=v8.2) while CHANGELOG.md already advertised [8.2.0] Unreleased. This PR synchronizes everyone to 8.2.0 and adds a CI guard test so future drift fails CI immediately.

Why

The drift had four concrete impacts (per issue #37):

  1. MCP clients see wrong version — the initialize response's serverInfo.version reads from utils.CODELENS_VERSION = "8.0.0", but the actual feature set (compact format, graph-schema, git-aware, architecture, hybrid-type-resolver) is 8.2.0-level. Clients that gate behavior on version mis-route.
  2. Packaging metadata liespip install codelens (if it ever ships to PyPI) would report 7.2.0 while the code is at 8.2.0.
  3. CHANGELOG credibility[8.2.0] — Unreleased advertises features that the version constants didn't acknowledge.
  4. Contributor confusion — new contributors couldn't tell which file was the source of truth.

Files touched

# File Change
1 scripts/utils.py:393 CODELENS_VERSION = "8.0.0""8.2.0" (canonical source going forward)
2 pyproject.toml:7 version = "7.2.0""8.2.0"
3 skill.json:3 "version": "7.2.0""8.2.0"
4 README.md:1 # CodeLens v8.2 — AI-Native Code Intelligence# CodeLens — AI-Native Code Intelligence
5 SKILL.md:12 # CodeLens v8.1# CodeLens
6 SKILL-QUICK.md:1 # CodeLens v8.2 — Quick Reference# CodeLens — Quick Reference
7 tests/test_version_consistency.py NEW — 3 tests (CI guard)

Design decisions

  • Dynamic vs. hardcoded pyproject.toml version: pyproject.toml supports dynamic = ["version"] with attr = "utils.CODELENS_VERSION", but the simpler hardcoded approach was chosen per the task brief — JSON (skill.json) cannot be dynamic anyway, so keeping pyproject.toml hardcoded matches the skill.json pattern and gives a uniform "edit one constant + grep-bump two mirrors" workflow. The CI guard test makes the hardcoded values safe.
  • Doc headings stripped, not templated: the live version is now queried via codelens --version (returns 8.2.0). README/SKILL/SKILL-QUICK no longer embed version literals in their H1, eliminating the third source of truth that caused the original drift. Templating markdown at build time was considered and rejected as over-engineering for a 3-file doc set.
  • CHANGELOG.md intentionally NOT touched: its [8.2.0] — Unreleased section was already correct and is the target value everyone else was bumped to match.

Verification

DoD check #9 — runtime version constant

$ python3 -c "from utils import CODELENS_VERSION; print(CODELENS_VERSION)"
8.2.0

DoD check #8pytest tests/test_version_consistency.py -v

============================= test session starts ==============================
platform linux -- Python 3.12.13, pytest-9.0.2, pluggy-1.6.0
rootdir: /home/z/my-project/CodeLens
configfile: pytest.ini
plugins: Faker-40.1.2, metadata-3.1.1, asyncio-1.3.0, ddtrace-4.2.2, cov-7.0.0, json-report-5.1.0, anyio-4.13.0
asyncio: mode=Mode.STRICT, debug=False, asyncio_default_fixture_loop_scope=None, asyncio_default_test_loop_scope=function
collected 3 items

tests/test_version_consistency.py::test_pyproject_version_matches_utils PASSED [ 33%]
tests/test_version_consistency.py::test_skill_json_version_matches_utils PASSED [ 66%]
tests/test_version_consistency.py::test_no_version_in_doc_headings PASSED [100%]

============================== 3 passed in 0.06s ==============================

Negative verification — tests fail when drift is reintroduced

I verified the tests actually catch drift by temporarily reverting each file to its old value and re-running:

FAILED tests/test_version_consistency.py::test_pyproject_version_matches_utils
  AssertionError: Version drift: pyproject.toml declares version='8.0.0' but
  scripts/utils.py:CODELENS_VERSION='8.2.0'. Bump pyproject.toml to match
  (CODELENS_VERSION is the single source of truth).

FAILED tests/test_version_consistency.py::test_skill_json_version_matches_utils
  AssertionError: Version drift: skill.json declares version='7.2.0' but
  scripts/utils.py:CODELENS_VERSION='8.2.0'. Bump skill.json to match
  (CODELENS_VERSION is the single source of truth).

FAILED tests/test_version_consistency.py::test_no_version_in_doc_headings
  AssertionError: Doc H1 headings must not embed version literals —
  CODELENS_VERSION='8.2.0' is the single source of truth. Readers should
  run `codelens --version` for the live version. Drift found in:
    - README.md:1 — H1 contains version literal 'v8.2' in line:
      '# CodeLens v8.2 — AI-Native Code Intelligence'

3 failed in 0.06s

After restoration, all 3 tests pass cleanly.

Full test suite (excluding slow tests/test_integration.py)

Run Failed Passed Skipped
Baseline (pre-PR, on main) 40 668 14
With this PR 37 671 14

Net delta: +3 passed (the 3 new consistency tests), 0 regressions. Every test that failed pre-PR fails identically post-PR — none of the pre-existing failures are caused by these changes.

Test portability

tests/test_version_consistency.py works on Python 3.8+ (the floor declared in pyproject.toml). It uses tomllib when available (3.11+) and falls back to a regex on the version = "..." line for 3.8-3.10, so it doesn't add tomli as a test-only dependency.

Findings (out of scope, not fixed)

Per the verification checklist (report what was found but not fixed):

  • tests/test_vuln_staleness.py::TestScanVulnerabilitiesCacheInfo::test_vulnerable_app_has_stale_cache_info — fails pre-PR too. It's a date-based staleness test (the built-in VULN_DB was last updated 2025-02-28, now 485 days old); the test asserts is_stale is True but the engine returns False. Pre-existing, unrelated to version metadata. Likely needs either a refresh of VULN_DB or a test fixture that mocks the wall-clock date.
  • 36 other pre-existing failures across test_architecture, test_compact_format, test_graph_incremental, test_graph_model, test_hybrid_type_resolver — all fail identically pre-PR and post-PR. Spot-checks suggest these are environmental (graph DB file path / fixture setup), not version-related. None of them touch version metadata, so they're outside this PR's scope.

Issue link

Closes #37#37

Establishes scripts/utils.py:CODELENS_VERSION as the single source of
truth for the CodeLens version. All other version mentions now match
this constant or are stripped entirely.

Issue #37 reported 4 different version values across 6 files:
  pyproject.toml=7.2.0, skill.json=7.2.0, utils.py=8.0.0,
  README.md=v8.2, SKILL.md=v8.1, SKILL-QUICK.md=v8.2,
  CHANGELOG.md=[8.2.0] Unreleased.

This PR synchronizes everyone to 8.2.0 (the value CHANGELOG.md
already advertises as the unreleased version) and adds a CI guard
test so future drift fails CI immediately.

Changes (6 existing files + 1 new test file):
  - scripts/utils.py:393 — CODELENS_VERSION "8.0.0" -> "8.2.0"
    (this is the canonical source going forward)
  - pyproject.toml:7 — version "7.2.0" -> "8.2.0"
    (PyPI / packaging metadata)
  - skill.json:3 — version "7.2.0" -> "8.2.0"
    (MCP / AI-host manifest)
  - README.md:1 — strip "v8.2" from H1 heading
    (# CodeLens — AI-Native Code Intelligence)
  - SKILL.md:12 — strip "v8.1" from H1 heading
    (# CodeLens)
  - SKILL-QUICK.md:1 — strip "v8.2" from H1 heading
    (# CodeLens — Quick Reference)
  - tests/test_version_consistency.py (NEW) — 3 tests:
      test_pyproject_version_matches_utils
      test_skill_json_version_matches_utils
      test_no_version_in_doc_headings

Why dynamic versioning was NOT used: pyproject.toml supports
dynamic = ["version"] with attr-based lookup, but the simpler
hardcoded approach was chosen per task brief (JSON cannot be dynamic
anyway, and keeping pyproject hardcoded matches the skill.json
pattern). The CI guard test makes the hardcoded values safe.

Doc headings: the live version is now queried via `codelens --version`
(returns 8.2.0). README/SKILL/SKILL-QUICK no longer embed version
literals in their H1, eliminating the third source of truth that
caused the original drift.

CHANGELOG.md intentionally NOT touched — its `[8.2.0] — Unreleased`
section was already correct and is the target value everyone else
was bumped to match.

Verification:
  - python3 -c "from utils import CODELENS_VERSION; print(CODELENS_VERSION)"
    outputs 8.2.0
  - pytest tests/test_version_consistency.py -v
    3 passed
  - Full test suite (excluding slow test_integration.py):
    baseline (pre-PR): 40 failed, 668 passed, 14 skipped
    with this PR:     37 failed, 671 passed, 14 skipped
    (3 net new passes = the 3 new consistency tests; no regressions)

Findings (out of scope, not fixed):
  - tests/test_vuln_staleness.py::TestScanVulnerabilitiesCacheInfo::test_vulnerable_app_has_stale_cache_info
    fails pre-PR too — it's a date-based staleness test
    (VULN_DB last-updated 2025-02-28, now 485 days old); the test
    expects is_stale=True but the engine returns False. Pre-existing.
  - 36 other pre-existing failures in test_architecture,
    test_compact_format, test_graph_incremental, test_graph_model,
    test_hybrid_type_resolver — all fail identically pre-PR and
    post-PR. None touch version metadata.

Closes #37.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@Wolfvin

Wolfvin commented Jun 28, 2026

Copy link
Copy Markdown
Owner Author

Review - APPROVE

Reviewed full diff (7 files, +175/-6). Clean, focused, matches issue #37 spec exactly.

Strengths

  1. Single source of truth: scripts/utils.py:393 CODELENS_VERSION = "8.2.0" (from "8.0.0").
  2. All 5 other files synced: pyproject.toml, skill.json (both "8.2.0"), README/SKILL/SKILL-QUICK H1 stripped of version literal.
  3. 3 CI guard tests in tests/test_version_consistency.py:
    • test_pyproject_version_matches_utils - parses pyproject.toml version (tomllib for 3.11+, regex fallback for 3.8-3.10), asserts == CODELENS_VERSION
    • test_skill_json_version_matches_utils - loads skill.json, asserts version == CODELENS_VERSION
    • test_no_version_in_doc_headings - scans first line of README/SKILL/SKILL-QUICK, fails if v\d+.\d+ pattern found
  4. Python 3.8-3.10 fallback: uses regex when tomllib unavailable (stdb in 3.11+). Thoughtful - no tomli test dependency needed.
  5. Actionable assert messages: each failure tells maintainer exactly what to fix and which file is canonical.
  6. Excellent docstrings: explain WHY (issue [BUG-03] Version drift across 6 files — pyproject=7.2.0, utils.py=8.0.0, README=v8.2, SKILL.md=v8.1 #37 reference, single source of truth rationale, drift prevention).

Minor observation (non-blocking)

pyproject.toml and skill.json descriptions still say "45 commands" - this is part of issue #38 (command count), not #37. Out of scope for this PR. Acceptable.

Verdict

Merging. CI guard test ensures future drift is caught immediately.

Reviewed by BOS (orchestrate-workers skill) - diff read in full before approval.

@Wolfvin Wolfvin merged commit a7b2294 into main Jun 28, 2026
3 of 8 checks passed
@sonarqubecloud

Copy link
Copy Markdown

@Wolfvin Wolfvin deleted the fix/37-version-drift branch July 1, 2026 06:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG-03] Version drift across 6 files — pyproject=7.2.0, utils.py=8.0.0, README=v8.2, SKILL.md=v8.1

1 participant