Skip to content

Pin ty to 0.0.56 - #25

Merged
leynos merged 4 commits into
mainfrom
pin-ty
Jul 26, 2026
Merged

Pin ty to 0.0.56#25
leynos merged 4 commits into
mainfrom
pin-ty

Conversation

@leynos

@leynos leynos commented Jul 7, 2026

Copy link
Copy Markdown
Owner

Rationale

ty 0.0.56 broke estate repositories whose CI installed ty unpinned (uv tool install ty, uvx ty, unpinned dev-dependencies): falcon-correlate and polythene mains were red for days. This pins every ty site in the template repository — both the template tree that generated repositories inherit and the repository's own gates — to 0.0.56, so future upgrades are deliberate rather than incidental.

Sites changed

  • Makefile (repository's own typecheck gate): uvx … ty check tests/uvx … ty@0.0.56 check tests/.
  • template/pyproject.toml.jinja (inherited by generated repositories): dev group "ty""ty==0.0.56". This also pins the generated Makefile's uv run ty --version / uv run ty check invocations, which resolve from the dev group; no change to template/Makefile.jinja is needed. The templated CI (ci.yml.jinja) typechecks via make typecheck, so it is covered by the same pin; its "Install CLI tools" step does not install ty.
  • tests/test_helpers.py and tests/helpers/pyproject_contracts.py: contract assertions updated to expect the pinned forms.

Validation

  • Repository gates: make check-fmt, make lint, make typecheck (now running ty 0.0.56: "All checks passed!"), and the full contract suite make test (33 passed, 2 skipped, 3 snapshots passed).
  • Rendered both toggle states (use_rust=false and use_rust=true): each resolves ty 0.0.56 and passes make typecheck (ty check my_project tests) cleanly, so the pin surfaces no ty 0.0.56 failures in generated projects.

Note for maintainers

Future ty bumps should be deliberate: update the pin in the parent Makefile, the templated dev group, and the contract assertions together, and re-render both toggle states before merging.

🤖 Generated with Claude Code

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @leynos, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 259794c9-4be9-42fd-b136-1a66f9f61abb

📥 Commits

Reviewing files that changed from the base of the PR and between cceb6ef and 1d1b4cc.

📒 Files selected for processing (1)
  • tests/test_helpers.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • leynos/whitaker (auto-detected)
  • leynos/cuprum (auto-detected)
  • leynos/mdtablefix (auto-detected)

Summary

  • Pin ty to 0.0.56 in the root Makefile and generated project development dependencies.
  • Strengthen contract and behavioural tests to enforce exact dependency sets and verify the pinned make typecheck invocation.
  • Document the versioning policy in both developer guides and ADR-004.
  • Validate repository checks, the full test suite, and rendered templates with both Rust toggle states.

Walkthrough

Pin ty to version 0.0.56 for the parent typecheck target and generated projects, strengthen dependency and invocation tests, and document the coordinated version-bump policy.

Changes

Ty version pinning

Layer / File(s) Summary
Build and template pinning
Makefile, template/pyproject.toml.jinja
Pin the parent typecheck command to ty@0.0.56 and generated development dependencies to ty==0.0.56.
Contract and invocation validation
tests/helpers/pyproject_contracts.py, tests/test_helpers.py
Require the exact development dependency set and verify that make typecheck invokes the pinned ty version.
Pinning guidance
docs/adr-004-pin-ty-version.md, docs/developers-guide.md, template/docs/developers-guide.md
Document the pin, typecheck behaviour, and deliberate version-bump process.

Possibly related PRs

  • leynos/beatcue#10: Modifies Makefile typecheck plumbing for running ty through uv, matching this PR’s pinned invocation path.

Poem

Pin ty firmly in place,
Keep each check at the same pace.
Templates, tests, and docs align,
Bumps follow one deliberate line—
0.0.56 shines.

🚥 Pre-merge checks | ✅ 20
✅ Passed checks (20 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the main change: pinning ty to version 0.0.56.
Description check ✅ Passed The description directly explains the ty pinning change and the affected files.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Testing (Overall) ✅ Passed The new fake-uvx test and exact pyproject contract both exercise the changed ty pinning and fail for plausible bad implementations.
User-Facing Documentation ✅ Passed The change is tooling/internal; the generated users guide already covers make all/typecheck, and no end-user workflow changed.
Developer Documentation ✅ Passed Approve: document the ty pin in both developer guides, record the decision in ADR-004, and leave no roadmap/execplan artefacts to update.
Module-Level Documentation ✅ Passed Both changed Python modules already begin with clear module docstrings describing purpose and relationships to other helpers.
Testing (Unit And Behavioural) ✅ Passed PASS: Exercise make typecheck at the subprocess boundary with a fake uvx shim, and enforce the exact pinned dev-dependency set in the pyproject contract.
Testing (Property / Proof) ✅ Passed The change only pins ty to fixed string values and adds exact-match contract tests; it introduces no range-based invariant or proof obligation.
Testing (Compile-Time / Ui) ✅ Passed PASS: The PR only pins Python tooling and adds a subprocess contract test; no Rust/TypeScript compile-time or UI-output change is present, so trybuild/snapshot requirements are not applicable.
Unit Architecture ✅ Passed The change stays at the orchestration edge: docs, pinning, and contract tests only; the new subprocess test injects PATH and resolves make explicitly.
Domain Architecture ✅ Passed Only a test helper changed to resolve make explicitly; no domain model, policy, repository, transport, or persistence code was altered.
Observability ✅ Passed PASS: The PR only pins a dev tool and updates docs/tests; it does not change any production/runtime path, so extra observability is not applicable.
Security And Privacy ✅ Passed Only ty pinning, tests, and docs changed; no new secrets, auth logic, broad permissions, or unsafe input handling appeared.
Performance And Resource Use ✅ Passed PASS: New checks stay bounded—fixed 8-item set comparisons and one subprocess call with a temp shim; no unbounded loops, extra cloning, or hot-path I/O.
Concurrency And State ✅ Passed PASS: The PR only pins ty and adds an isolated subprocess test; no shared mutable state, locks, async tasks, or ordering-sensitive paths were introduced.
Architectural Complexity And Maintainability ✅ Passed PASS: It only pins ty, updates docs, and tightens existing boundary contracts; no new layers, registries, or indirection appear.
Rust Compiler Lint Integrity ✅ Passed No Rust sources or lint/clone changes were touched; the PR only edits a Python test, so Rust compiler lint integrity is unaffected.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch pin-ty

Comment @coderabbitai help to get the list of available commands.

@pandalump

Copy link
Copy Markdown
Collaborator

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@leynos

leynos commented Jul 7, 2026

Copy link
Copy Markdown
Owner Author

Both review findings addressed in the latest push (3575221).

Finding 1 (documentation) — valid, fixed. The ty==0.0.56 pin is now documented in docs/developers-guide.md (parent make typecheck bullet plus a note in the Makefile Template section covering the generated dev-group pin) and in template/docs/developers-guide.md (which generated repositories receive), in both cases explaining why it is pinned (unpinned installs broke the falcon-correlate and polythene mains when 0.0.56 landed) and the bump policy (deliberate: update the pin and fix any new diagnostics in one PR). On the ADR suggestion: this repository does keep ADRs (docs/adr-001…, docs/adr-002…), so the decision is recorded in house style as docs/adr-003-pin-ty-version.md.

Finding 2 (behavioural coverage) — valid, fixed. Added test_parent_makefile_typecheck_invokes_pinned_ty in tests/test_helpers.py (alongside the existing parent-Makefile contract tests): it puts a POSIX uvx shim on PATH that captures "$@" to a file and exits 0, runs the repository's root make typecheck, and asserts the captured invocation includes the ty@0.0.56 token and the check subcommand. Skipped on win32. The existing string-contract assertions are retained.

One nearby observation assessed as out of scope: template/docs/developers-guide.md has a pre-existing MD013 over-length line (the make lint bullet); my added lines lint clean and the parent repository has no Markdown gate, so it was left untouched to keep the diff minimal.

Validation: new test passes in isolation; full contract suite 34 passed, 2 skipped (act-gated); make check-fmt, make lint, and make typecheck all green.

@leynos

leynos commented Jul 7, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai Have the following failed checks now been resolved?

If further work is required, please provide an AI agent prompt for the remaining work to be done to address these failures.

Do not treat warnings as optional or aspirational. Where a change is out of scope for this PR, propose a GitHub issue unless one exists already. (Treat documentation and validation coverage as in scope).

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Developer Documentation ⚠️ Warning The ty pin changes a build requirement, but docs/developers-guide.md and the template guide still describe generic ty check, and no doc/ADR was added. Add the pin to docs/developers-guide.md and the mirrored template developer guide, and record the version-pin decision in an ADR if you treat it as architectural.
Testing (Unit And Behavioural) ⚠️ Warning The updated checks are mostly string-contract assertions; no test exercises the root make typecheck boundary, so the CLI pin is not behaviourally covered. Add an integration test that runs make typecheck with faked uvx/ty and asserts the pinned invocation, while keeping the contract assertions.

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== ADR files ==="
fd -i 'adr-00' docs

echo "=== developers-guide.md ty mentions ==="
rg -n 'ty' docs/developers-guide.md | rg -i 'ty(@|==|check|0\.0\.56|pin)'

echo "=== template developers-guide.md ty mentions ==="
rg -n 'ty' template/docs/developers-guide.md | rg -i 'ty(@|==|check|0\.0\.56|pin)'

echo "=== ADR-003 content ==="
fd -i 'adr-003' docs -x cat {}

echo "=== test for pinned ty invocation ==="
rg -n 'test_parent_makefile_typecheck_invokes_pinned_ty' tests/test_helpers.py -A 40

echo "=== git log for commit 3575221 ==="
git log --oneline -5

Length of output: 4709


🏁 Script executed:

#!/bin/bash
set -euo pipefail
sed -n '480,545p' tests/test_helpers.py

Length of output: 2480


@leynos Confirmed — both warnings are resolved in commit 3575221.

Developer Documentation: Verified. docs/developers-guide.md (Lines 19 and 52) and template/docs/developers-guide.md (Line 16) now state the ty@0.0.56 / ty==0.0.56 pin explicitly and explain the rationale (unpinned installs broke the falcon-correlate and polythene mains). docs/adr-003-pin-ty-version.md records the decision with Context, Decision, and Consequences sections, including the bump policy.

Testing (Unit and Behavioural): Verified. test_parent_makefile_typecheck_invokes_pinned_ty in tests/test_helpers.py (Line 499) exercises the actual make typecheck boundary: it installs a POSIX uvx shim on PATH, runs make typecheck as a subprocess, and asserts the captured invocation contains both ty@0.0.56 and check. It's correctly gated with @pytest.mark.skipif(sys.platform == "win32", ...). The existing string-contract assertions remain in place, so behavioural and contract coverage now sit side by side.

No further work is required for these two warnings. No follow-up issue needed.

The MD013 over-length line you flagged as out-of-scope in template/docs/developers-guide.md is a pre-existing lint condition unrelated to this PR's diff, and the parent repository has no Markdown lint gate — leaving it untouched is correct; don't fix it here.

ᕮ(•ᴥ•)ᕮ

@leynos

leynos commented Jul 7, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

coderabbitai[bot]

This comment was marked as resolved.

@leynos

leynos commented Jul 8, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai resume

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown
✅ Action performed

Reviews resumed.

leynos added 3 commits July 18, 2026 21:21
The ty 0.0.56 release broke estate repositories whose CI installed ty
unpinned (falcon-correlate and polythene mains were red for days). Pin
every ty installation site to 0.0.56 so upgrades become deliberate:

- the parent Makefile's typecheck target now runs uvx ty@0.0.56;
- the templated dev dependency group now declares ty==0.0.56, which
  pins the generated Makefile's `uv run ty` invocations;
- the contract tests assert the pinned forms.

Both rendered toggle states resolve ty 0.0.56 and pass `make
typecheck`, and the template's own gates pass with the pin in place.
Address review feedback on the ty pin:

- document the ty==0.0.56 pin in the parent developers' guide and the
  generated developers' guide, including why it exists (unpinned
  installations broke falcon-correlate and polythene mains when ty
  0.0.56 landed) and the policy that bumps are deliberate (update the
  pin and fix any new diagnostics in one pull request);
- record the decision as ADR-003, following the repository's existing
  ADR convention;
- add an integration test that runs the parent `make typecheck` with a
  fake uvx shim on PATH and asserts the captured invocation includes
  the pinned ty@0.0.56 token (POSIX-only, skipped on Windows), keeping
  the existing string-contract assertions.
Replace the loose membership check on `dev_dependencies` with an
exact set equality assertion plus a duplicate-count guard. The old
`dependency in dev_dependencies` loop would silently pass if an
extra unpinned `ty` entry co-existed alongside `ty==0.0.56`. The
new assertion requires the rendered list to match the pinned contract
precisely — no extra entries, no duplicates.
@leynos

leynos commented Jul 19, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai Have the following now been resolved?

tests/helpers/pyproject_contracts.py (1)

35-47: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Make the dev dependency assertion exact.
dependency in dev_dependencies still passes if an unpinned ty stays alongside ty==0.0.56, so this contract can drift without failing.

♻️ Tighten the assertion
-    for dependency in [
-        "pytest",
-        "interrogate",
-        "pip-audit",
-        "ruff",
-        "pyright",
-        "ty==0.0.56",
-        "pytest-timeout",
-        "pytest-xdist",
-    ]:
-        assert dependency in dev_dependencies, (
-            f"expected generated dev dependencies to include {dependency}"
-        )
+    expected_dev_dependencies = {
+        "pytest",
+        "interrogate",
+        "pip-audit",
+        "ruff",
+        "pyright",
+        "ty==0.0.56",
+        "pytest-timeout",
+        "pytest-xdist",
+    }
+    assert set(dev_dependencies) == expected_dev_dependencies, (
+        "expected generated dev dependencies to match the pinned contract"
+    )
+    assert len(dev_dependencies) == len(expected_dev_dependencies), (
+        "expected generated dev dependencies to contain no duplicates"
+    )
🤖 Detailed instructions

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @tests/helpers/pyproject_contracts.py around lines 35 - 47, The dev
dependency contract in the helper assertion is too loose because dependency in dev_dependencies allows extra or duplicate entries like an unpinned ty to
slip through. Update the check in tests/helpers/pyproject_contracts.py to use
an exact match against the full expected set for dev_dependencies, and add a
duplicate/length guard so the generated list must match the pinned contract
precisely when validating the dev_dependencies collection.

@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

ast-grep outline tests/helpers/pyproject_contracts.py --items all --type function
printf '\n=== development-dependency assertions ===\n'
rg -n -C 12 'expected_dev_dependencies|dev_dependencies|ty==0\.0\.56' \
  tests/helpers/pyproject_contracts.py

Length of output: 2164


@leynos Confirm this finding as resolved.

tests/helpers/pyproject_contracts.py now:

  • defines the full expected development-dependency set, including ty==0.0.56;
  • asserts exact set equality, rejecting both missing and additional dependencies; and
  • guards against duplicates by comparing the list length with the expected-set length.

An unpinned ty alongside ty==0.0.56 now fails the contract. No further work or follow-up issue is required.

@pandalump

Copy link
Copy Markdown
Collaborator

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/test_helpers.py`:
- Around line 576-583: Update the subprocess invocation in the test helper to
resolve make through shutil.which before calling subprocess.run. Assert that the
resolved executable is available, then pass the absolute path with the existing
typecheck argument while preserving the current process options.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 9a9bcaf5-eadd-401b-9a8e-0496d47041b0

📥 Commits

Reviewing files that changed from the base of the PR and between 3575221 and cceb6ef.

📒 Files selected for processing (7)
  • Makefile
  • docs/adr-004-pin-ty-version.md
  • docs/developers-guide.md
  • template/docs/developers-guide.md
  • template/pyproject.toml.jinja
  • tests/helpers/pyproject_contracts.py
  • tests/test_helpers.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • leynos/whitaker (auto-detected)
  • leynos/cuprum (auto-detected)
  • leynos/mdtablefix (auto-detected)

Comment thread tests/test_helpers.py
The parent-Makefile typecheck boundary test spawned `make` by bare name,
leaving executable resolution to the subprocess layer at spawn time. Resolve
it through `shutil.which` first, assert it is present, and pass the absolute
path, so the test controls which binary runs rather than relying on implicit
PATH lookup.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@pandalump

Copy link
Copy Markdown
Collaborator

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@leynos
leynos merged commit 9a7676b into main Jul 26, 2026
6 checks passed
@leynos
leynos deleted the pin-ty branch July 26, 2026 21:21
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.

2 participants