Skip to content

Regenerate discovered nested lockfiles during lading bump - #160

Open
leynos wants to merge 15 commits into
mainfrom
regenerate-lockfiles
Open

Regenerate discovered nested lockfiles during lading bump#160
leynos wants to merge 15 commits into
mainfrom
regenerate-lockfiles

Conversation

@leynos

@leynos leynos commented Jul 7, 2026

Copy link
Copy Markdown
Owner

Summary

This branch makes lading bump regenerate every git-tracked Cargo.lock in the repository, not just the workspace root plus manifests listed in bump.lockfile_manifests. Previously, lading publish validated all tracked lockfiles under --locked, so any nested fixture lockfile that bump had not been configured to refresh went stale and publish aborted with a manual repair message — leaving the user wondering why bump had not done the repair itself. The users' guide already promised discovery-based refresh; this branch makes the code keep that promise.

Execplan: docs/execplans/regenerate-lockfiles.md (implemented in full; status COMPLETE, including the Stage A prototype evidence, red/green test transcripts, an end-to-end acceptance run, and the retrospective).

The branch also carries three supporting changes:

  • The publish pre-flight stale-lockfile message no longer blames lading bump; it now names the remaining causes (manifest edits made without bump, or bump runs with --no-rebuild-lockfiles).
  • The make typecheck gate is restored and future-proofed: six pre-existing diagnostics under the drifting unpinned ty toolchain are fixed, and ty is now pinned (TY_VERSION ?= 0.0.56) in the Makefile with CI running the pinned version via make typecheck rather than installing ty separately.
  • A formatting-only mdformat reflow of the developers' guide is committed separately to keep future make fmt runs clean.

Review walkthrough

Validation

  • make test: 683 passed, 62 snapshots passed.
  • make lint: Ruff clean; interrogate 100%; Pylint 10.00/10.
  • make check-fmt: 132 files already formatted.
  • make typecheck (ty 0.0.56, pinned): all checks passed.
  • make markdownlint and make nixie: clean.
  • uv tool run mbake validate Makefile: valid syntax.
  • coderabbit review --agent: run after each milestone (feature, docs, ty pinning); zero findings each time.
  • End-to-end acceptance with real git and cargo against a prototype workspace mirroring the reported failure: bump discovered two tracked lockfiles, listed - fixtures/minimal/Cargo.lock (lockfile) in its output, refreshed the nested lockfile to the new version, and cargo metadata --locked subsequently exited 0.
  • Red/green evidence: the new unit tests and BDD scenario were observed failing for the expected reasons before implementation (transcripts recorded in the execplan).

Notes

  • Tests follow red-green-refactor; the red tests were committed together with the implementation so the suite stays green at every commit boundary.
  • One edge surfaced by the live acceptance run: a nested non-member package that pins a versioned path dependency on a bumped crate (alpha = { path = ..., version = "0.1.0" }) now fails at bump time with cargo's version-selection error, because bump does not rewrite non-member manifests. Such a repository already failed at publish time, so the error merely surfaces earlier and more actionably; rewriting those requirements is recorded in the execplan as an open follow-up.
  • bump.lockfile_manifests remains supported for lockfiles that git does not track; --no-rebuild-lockfiles remains the global escape hatch.
  • Regeneration is still non-atomic across manifests (pre-existing behaviour, documented; see issue Handle workspace inconsistency when lockfile refresh fails after manifest rewrites in bump #84).

References

@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

Walkthrough

Changes

Nested lockfile regeneration

Layer / File(s) Summary
Manifest discovery and merge
lading/commands/bump_lockfiles.py, lading/commands/lockfile.py, tests/bdd/*
Merge configured manifests with manifests implied by tracked Cargo.lock files before resolving or regenerating lockfiles, and verify root plus nested refreshes.
Manifest merge and path validation
tests/unit/test_bump_lockfile_manifest_merge.py, tests/unit/test_bump_lockfile_path_resolution.py, tests/unit/test_bump_lockfiles.py, tests/unit/test_bump_lockfile_rebuild.py, tests/unit/conftest.py
Test ordering, de-duplication, git fallback, path projection, invalid targets, merged manifests, and aggregated failures.
Lockfile workflow documentation
docs/contents.md, docs/execplans/*, docs/developers-guide.md, docs/users-guide.md, docs/repository-layout.md, docs/lading-design.md, tests/unit/publish/__snapshots__/*
Document execution plans, discovery, regeneration, configuration, diagnostics, repository ownership, and dry-run behaviour.

Pinned typechecking toolchain

Layer / File(s) Summary
Pinned typecheck execution
Makefile, .github/workflows/ci.yml, docs/developers-guide.md, lading/commands/bump_toml.py
Pin ty through uv, align CI and developer documentation, and suppress the OutOfOrderTableProxy indexing diagnostic.

Publish validation control flow

Layer / File(s) Summary
Dependency placement narrowing
lading/commands/publish_index_check.py
Type publishable indexes and route missing dependency handling through explicit downgrade-or-raise branches.
Publish validation documentation
lading/commands/publish_preflight.py, tests/unit/publish/__snapshots__/*
Broaden stale-lockfile diagnostic wording and update its snapshot.

Sequence Diagram(s)

sequenceDiagram
  participant BumpCommand
  participant CargoLockfileRepository
  participant Git
  participant Cargo
  BumpCommand->>CargoLockfileRepository: resolve or regenerate lockfiles
  CargoLockfileRepository->>Git: discover tracked Cargo.lock files
  Git-->>CargoLockfileRepository: return tracked lockfile paths
  CargoLockfileRepository-->>BumpCommand: return merged manifest paths
  BumpCommand->>Cargo: run cargo update --workspace
Loading

Possibly related PRs

  • leynos/lading#119: Overlaps with nested lockfile handling and stale-lockfile snapshot updates.
  • leynos/lading#129: Overlaps with the replaced resolve_lockfile_paths property-based tests.
  • leynos/lading#135: Introduces the bump-side repository flow extended by this change.

Suggested labels: Issue

Suggested reviewers: codescene-access

Poem

Nested locks arise,
Git gathers paths through the rain,
Cargo updates.

ty checks in a pinned shell,
Publish branches choose their course.

🚥 Pre-merge checks | ✅ 19 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Title check ⚠️ Warning The title matches the change, but it omits the required execplan reference for this roadmapped work. Add the execplan reference, e.g. Regenerate discovered nested lockfiles during lading bump (regenerate-lockfiles), so the title matches the required format.
✅ Passed checks (19 passed)
Check name Status Explanation
Description check ✅ Passed The description clearly describes the lockfile regeneration, typecheck pinning, docs, and CI changes in this branch.
Docstring Coverage ✅ Passed Docstring coverage is 85.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 PASS: New tests cover manifest merging, path resolution, dry-run/live wiring, BDD nested-lockfile refresh, and stale-lock messaging; they fail for plausible broken implementations.
User-Facing Documentation ✅ Passed docs/users-guide.md clearly documents nested/tracked lockfile regeneration, dry-run semantics, configurable manifests, and the updated stale-lock warning.
Developer Documentation ✅ Passed PASS: docs/developers-guide.md and docs/lading-design.md document the new lockfile merge/rebuild API and TY pin; docs/roadmap.md has the lockfile task checked off, and the execplan is COMPLETE and...
Module-Level Documentation ✅ Passed PASS: Every touched Python module has a top-level docstring; the command modules describe purpose and cross-module relationships, and the test modules state their scope.
Testing (Unit And Behavioural) ✅ Passed Unit tests cover merge, validation, error and ordering invariants; BDD runs the bump CLI via subprocess, so the behavioural boundary is exercised.
Testing (Property / Proof) ✅ Passed PASS: The PR adds Hypothesis property tests for manifest merging and lockfile path resolution, covering ordering, deduplication, and escape invariants; no proof obligation is introduced.
Testing (Compile-Time / Ui) ✅ Passed PASS: No Rust/TS compile-time surface exists; text/UI output is covered by focused snapshots and semantic BDD assertions, not blanket matches.
Unit Architecture ✅ Passed Explicit ports keep bump-side lockfile discovery/regeneration injectable; the new query helpers stay read-only, and tests split merge, path projection, and regeneration seams.
Domain Architecture ✅ Passed PASS: The new manifest discovery and regeneration logic stays in lading.commands, with git/cargo/filesystem concerns isolated behind the LockfileRepository port and adapter.
Observability ✅ Passed Approve this: bump_lockfiles logs start/end, per-manifest failures, non-git fallback, and existing lockfile discovery/validation metrics cover the new flow.
Security And Privacy ✅ Passed No secrets, credentials, auth or permission changes found; new cargo/git calls are parameterised, and manifest paths are validated to stay within the workspace.
Performance And Resource Use ✅ Passed Accept the change: merge_discovered_manifests does one git scan and O(n) set/sort work, and bump calls it once per run before the necessary per-manifest cargo updates.
Concurrency And State ✅ Passed PASS: The new lockfile merge/regeneration path is single-owner and sequential, with no shared mutable state or async tasks; ordering and non-git fallback are tested.
Architectural Complexity And Maintainability ✅ Passed PASS: merge_discovered_manifests is a small, single-purpose seam reused by dry-run and live paths; existing repository/protocol boundaries stay explicit, and tests were split into focused modules.
Rust Compiler Lint Integrity ✅ Passed No Rust files changed; the diff only touches Python tests, and no lint suppressions or suspicious clone workarounds appear in the modified files.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch regenerate-lockfiles

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

codescene-access[bot]

This comment was marked as outdated.

@leynos
leynos marked this pull request as ready for review July 8, 2026 09:48

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9d8c9c57a1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread docs/execplans/regenerate-lockfiles.md
codescene-access[bot]

This comment was marked as outdated.

@lodyai
lodyai Bot force-pushed the regenerate-lockfiles branch from fbc0a6d to 2509734 Compare July 9, 2026 09:09
codescene-access[bot]

This comment was marked as outdated.

@lodyai
lodyai Bot force-pushed the regenerate-lockfiles branch from 2509734 to 1198e46 Compare July 13, 2026 19:29
codescene-access[bot]

This comment was marked as outdated.

@coderabbitai coderabbitai Bot added the Roadmap label Jul 13, 2026

@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: 8

🤖 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 `@docs/developers-guide.md`:
- Around line 177-184: Fix the API reference in the merge_discovered_manifests
documentation by removing the space between the module and member, so it
resolves as lading.commands.lockfile.discover_tracked_lockfiles.

In `@docs/execplans/regenerate-lockfiles.md`:
- Around line 48-51: Update the CommandRunner constraint in
regenerate-lockfiles.md to reference its defining module,
lading/runtime/runner.py, instead of lading/runtime.py; leave the lockfile
function signature constraints unchanged.
- Around line 271-272: Update the “Follow-up candidates” section in
regenerate-lockfiles.md to remove the completed “pin ty in CI and the Makefile”
item, keeping only genuinely pending candidates and preserving the completed
pinning record in the revision note.
- Around line 247-250: Update the “Delivered as planned” statement in the
lockfile regeneration plan to distinguish modes: live mode regenerates the root,
discovered, and configured lockfiles, while dry-run only discovers and reports
that same set without modifying files. Keep the existing discovery and publish
pre-flight behavior description unchanged.

In `@docs/users-guide.md`:
- Around line 279-284: Update the lockfile_manifests documentation to state that
configured manifests are required for nested lockfiles when the workspace is
outside a Git repository, because discovery returns no Git-tracked manifests
there and the configured list is the only inclusion mechanism. Replace the
wording that limits this option to untracked lockfiles, while preserving the
notes about automatic discovery and excluding the workspace-root manifest.

In `@lading/commands/publish_index_check.py`:
- Around line 375-393: The None-returning paths in _handle_index_missing_version
and _downgrade_or_raise currently rely on implicit returns. Add bare return
statements at the ends of both functions, using return rather than return None,
while preserving their existing control flow.
- Around line 290-292: Update the comments around the missing_index if/elif
chain to reference ty 0.0.56 instead of ty 0.0.8. Verify whether the pinned
checker still requires branch-based narrowing; if not, remove the workaround and
retain equivalent behavior.

In `@tests/unit/test_bump_lockfiles.py`:
- Around line 62-131: Update the assertions in all three
merge_discovered_manifests tests to include descriptive failure messages,
covering the merged result and runner.invocations checks in
test_merge_discovered_manifests_appends_tracked_manifests and the merged-result
checks in the other two tests. Follow the existing assert-with-message
convention used elsewhere in the test suite.
🪄 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: 0c8bcc34-50a7-4e4b-b434-a3b0d2fd11bb

📥 Commits

Reviewing files that changed from the base of the PR and between efaa795 and 1198e46.

📒 Files selected for processing (19)
  • .github/workflows/ci.yml
  • Makefile
  • docs/contents.md
  • docs/developers-guide.md
  • docs/execplans/regenerate-lockfiles.md
  • docs/repository-layout.md
  • docs/users-guide.md
  • lading/commands/bump.py
  • lading/commands/bump_lockfiles.py
  • lading/commands/bump_toml.py
  • lading/commands/lockfile.py
  • lading/commands/publish_index_check.py
  • lading/commands/publish_preflight.py
  • tests/bdd/features/cli.feature
  • tests/bdd/steps/test_bump_steps.py
  • tests/unit/conftest.py
  • tests/unit/publish/__snapshots__/test_preflight_lockfile_validation.ambr
  • tests/unit/test_bump_lockfile_rebuild.py
  • tests/unit/test_bump_lockfiles.py
🔗 Linked repositories identified

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

  • leynos/cmd-mox (auto-detected)
  • leynos/shared-actions (auto-detected)

Comment thread docs/developers-guide.md Outdated
Comment thread docs/execplans/regenerate-lockfiles.md
Comment thread docs/execplans/regenerate-lockfiles.md Outdated
Comment thread docs/execplans/regenerate-lockfiles.md Outdated
Comment thread docs/users-guide.md Outdated
Comment thread lading/commands/publish_index_check.py Outdated
Comment thread lading/commands/publish_index_check.py Outdated
Comment thread tests/unit/test_bump_lockfiles.py Outdated
codescene-access[bot]

This comment was marked as outdated.

@lodyai
lodyai Bot force-pushed the regenerate-lockfiles branch from 84f36e7 to 27ca243 Compare July 13, 2026 22:29
codescene-access[bot]

This comment was marked as outdated.

@leynos

leynos commented Jul 18, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai resume

@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown
✅ Action performed

Reviews resumed.

@leynos

leynos commented Jul 18, 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 (4 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 76.19% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Developer Documentation ⚠️ Warning docs/developers-guide.md still has a malformed lading.commands.lockfile .discover_tracked_lockfiles ref, and the execplan still leaves ty pinning and dry-run wording stale. Fix the module path, update the execplan to match implemented live/dry-run behaviour, and remove or mark the ty pinning follow-up as complete.
Testing (Property / Proof) ⚠️ Warning merge_discovered_manifests adds order/dedup invariants, but only example tests were added; repo guidance calls for Hypothesis on such invariants. Add a Hypothesis test for merge_discovered_manifests covering arbitrary configured/discovered orders, resolved-path de-duplication, and the non-git fallback.

@coderabbitai

This comment was marked as resolved.

codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

@leynos

leynos commented Jul 19, 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 (4 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 76.19% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Developer Documentation ⚠️ Warning docs/developers-guide.md still has a malformed lading.commands.lockfile .discover_tracked_lockfiles ref, and the execplan still leaves ty pinning and dry-run wording stale. Fix the module path, update the execplan to match implemented live/dry-run behaviour, and remove or mark the ty pinning follow-up as complete.
Testing (Property / Proof) ⚠️ Warning merge_discovered_manifests adds order/dedup invariants, but only example tests were added; repo guidance calls for Hypothesis on such invariants. Add a Hypothesis test for merge_discovered_manifests covering arbitrary configured/discovered orders, resolved-path de-duplication, and the non-git fallback.
Title check ⚠️ Warning The title matches the nested-lockfile regeneration work, but it omits the required execplan reference for this roadmapped change. Add the execplan reference to the title, e.g. Regenerate discovered nested lockfiles during lading bump (regenerate-lockfiles).},{

@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

echo '=== PR metadata ==='
gh pr view 160 --repo leynos/lading --json title,url,state,headRefName,updatedAt \
  --jq '{title, url, state, headRefName, updatedAt}'

echo '=== PR checks ==='
gh pr checks 160 --repo leynos/lading || true

echo '=== Relevant Makefile validation targets ==='
rg -n -A12 -B3 '^(docs|format|lint|typecheck|test|check|TOOLS|TY_VERSION|TY)\b' Makefile || true

echo '=== Documentation: stale/current wording and ty status ==='
rg -n -i -C3 \
  'currently passes only|currently used only|dry.run|dry run|configured manifests|merged manifest|uv tool install ty|pinning.*(follow.up|worthwhile)|TY_VERSION|ty==0\.0\.56|CargoLockfileRepository|LockfileRepository|discover_tracked_lockfiles' \
  docs/developers-guide.md docs/execplans/regenerate-lockfiles.md || true

echo '=== Source and property-test structure ==='
ast-grep outline lading/commands/bump_lockfiles.py --items all --view expanded
ast-grep outline tests/unit/test_bump_lockfiles.py --items all --view expanded
rg -n -A70 -B10 \
  '\bmerge_discovered_manifests\b|`@given`\b|hypothesis|non.git|not.a.git|fallback|dedup|deduplication|order' \
  tests/unit/test_bump_lockfiles.py || true

echo '=== Public functions lacking docstrings (source only) ==='
python3 - <<'PY'
from pathlib import Path
import ast

missing = []
for filename in Path("lading").rglob("*.py"):
    tree = ast.parse(filename.read_text(encoding="utf-8"), filename=str(filename))
    for node in ast.walk(tree):
        if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
            if not node.name.startswith("_") and ast.get_docstring(node) is None:
                missing.append(f"{filename}:{node.lineno}: {node.name}")
print("\n".join(sorted(missing)) or "None")
PY

Length of output: 59462


@leynos Mark three warnings as resolved and address one remaining title-only failure.

Check Status Evidence
Docstring Coverage Resolved lint-test passes. Makefile Line 89 enforces interrogate --fail-under 100 lading, exceeding the reported 80% threshold.
Developer Documentation Resolved docs/developers-guide.md now references lading.commands.lockfile.discover_tracked_lockfiles correctly. The ExecPlan accurately documents the LockfileRepository/CargoLockfileRepository boundary, merged dry-run projection, completed TY_VERSION ?= 0.0.56 pinning, and matching live/dry-run lockfile sets.
Testing (Property / Proof) Resolved tests/unit/test_bump_lockfiles.py contains Hypothesis properties for ordering and resolved-path de-duplication (Lines 172–207) and non-git fallback identity (Lines 210–231).
Title check Unresolved PR #160 is currently titled Regenerate discovered nested lockfiles during lading bump; it lacks the required execplan reference.

Do not open a GitHub issue. Update the PR metadata in scope:

Update the title of GitHub PR `#160` in leynos/lading only.

Set the title exactly to:

Regenerate discovered nested lockfiles during lading bump (regenerate-lockfiles)

Do not modify code, documentation, tests, PR body, labels, or reviewers. Report the resulting PR URL and title.

The current lint-test CI check passes; use that as the required repository validation evidence.

@lodyai
lodyai Bot force-pushed the regenerate-lockfiles branch from 58bb2a7 to 37be73c Compare July 27, 2026 12:55
codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

leynos and others added 14 commits July 28, 2026 16:12
`lading bump` regenerates only the root lockfile plus manifests listed
in `bump.lockfile_manifests`, while `lading publish` pre-flight
validates every git-tracked `Cargo.lock`, so unconfigured nested
lockfiles go stale and publish fails with a manual repair message.

Plan the fix: reuse `discover_tracked_lockfiles` in bump, merging
discovered manifests with the configured list. Record the Stage A
prototype evidence that `cargo update --workspace` refreshes
path-dependency entries in nested fixture lockfiles.
`uv tool install ty` (used by CI and locally) now resolves to ty 0.0.8,
which does not narrow bindings after calls to `NoReturn` helpers and
flags tomlkit's `OutOfOrderTableProxy` indexing. Six pre-existing
diagnostics broke `make typecheck` on a clean tree.

Restructure the guard cascades in `publish_index_check.py` as
if/elif/else chains so narrowing flows from the branch conditions,
extract `_downgrade_or_raise` to keep the named-dependency path typed
as `str`, and mirror the existing `type: ignore[index]` comment for
proxy indexing in `bump_toml.py`. No behaviour change.
`lading bump` regenerated only the workspace root `Cargo.lock` plus
manifests listed in `bump.lockfile_manifests`, while the publish
pre-flight validates every git-tracked `Cargo.lock`. A tracked nested
fixture lockfile therefore went stale after a bump and `lading publish`
failed with a manual repair message.

Add `bump_lockfiles.merge_discovered_manifests`, which unions the
configured manifests with manifests implied by git-tracked lockfiles
(via `discover_tracked_lockfiles`, the same helper publish uses), and
feed the merged tuple to both the dry-run and live regeneration paths
in `bump._process_lockfiles`. Configured entries keep their order;
discovered entries follow sorted, de-duplicated by resolved path. In a
non-git workspace discovery degrades to a warning and the configured
list, matching the publish pre-flight.

A Stage A prototype (recorded in the ExecPlan) confirmed that
`cargo update --workspace --manifest-path <nested>` refreshes
path-dependency entries in a nested standalone package's lockfile, so
the existing cargo invocation is reused unchanged.

The autouse `stub_lockfile_regeneration` fixture now also stubs the
merge so manifest-focused unit suites never shell out to git.
Now that `lading bump` discovers and regenerates git-tracked lockfiles
itself, the publish pre-flight's "This commonly happens after running
`lading bump`" hint would mislead. Point it at the remaining causes
instead: manifest edits made without bump, or bump runs with
`--no-rebuild-lockfiles`. Regenerate the affected snapshot.

Update the users' guide (bump discovery paragraph, quoted pre-flight
message, `lockfile_manifests` and `rebuild_lockfiles` key descriptions,
and the regeneration paragraph) and the developers' guide
(`bump_lockfiles` module description and the lockfile helpers section)
to describe the merged configured-plus-discovered manifest set.
Record the end-to-end acceptance run (real git and cargo against the
prototype workspace: nested lockfile discovered, refreshed, and fresh
under `--locked`), the versioned-path-dependency edge case surfaced by
that run, both CodeRabbit reviews (zero findings), the retrospective,
and the follow-up candidates. Mark the plan COMPLETE.
`make typecheck` previously ran whichever ty happened to be on PATH,
and CI installed ty unpinned with `uv tool install`. ty is pre-1.0 and
its diagnostics shift between releases, so the typecheck gate could
break (or silently loosen) without any code change — locally, a stale
ty 0.0.8 flagged six diagnostics that the current release does not.

Adopt the latest release by pinning `TY_VERSION ?= 0.0.56` in the
Makefile, mirroring the existing `RUFF_VERSION` pattern: the
`typecheck` target now invokes `uv tool run --from ty==$(TY_VERSION)`,
so no separate installation is needed and CI's tool-install step drops
ty. Document the variable (and the bump-deliberately policy) in the
developers' guide. ty 0.0.56 passes with no new diagnostics.
`docs/contents.md` is the documented entry point for the documentation
set, but the new plan under `docs/execplans/` was not listed, so
readers following the navigation path would not discover it. Add an
"Execution plans" section to the index and record the `docs/execplans/`
placement convention in the repository layout guide.
Clarify live and dry-run lockfile behaviour and document non-Git
configuration requirements. Simplify ty narrowing now supported by the
pinned checker, make successful None returns explicit, and add property
coverage for merge ordering, resolved-path de-duplication, and non-Git
fallback behaviour.

Refresh the generated spelling dictionary entries carried in the working
tree.
Adapt the rebased lockfile discovery behaviour to main's
`LockfileRepository` boundary. Keep the bump domain independent of Git and
Cargo execution while ensuring the concrete adapter discovers the same
manifest set for dry-run projection and live regeneration.

Record the post-plan architectural adjustment in the developer and design
documentation.
Describe the current `LockfileRepository` boundary, shared lockfile
discovery, and live versus dry-run behaviour. Label pre-pin ty evidence as
historical and record the completed 0.0.56 pin unambiguously.

Correct the remaining Oxford-spelling blocker surfaced by the documentation
gate.
Add bare returns after the terminal raising helpers while preserving the
existing branch structure and type narrowing.
Restore Ruff's required module-level spacing after the rebase combined the
example and property tests.
Assert that the discovery BDD scenario invokes Cargo separately for the
workspace and nested manifests. Expand the affected fixture docstrings to
record their inputs, module gating, side effects, and return contract.
Separate manifest merging and path projection from lockfile regeneration so
each test module exercises one cohesive production API. Keep private support
code local and preserve the regeneration snapshot under its existing module.
@lodyai
lodyai Bot force-pushed the regenerate-lockfiles branch from 2696b26 to c112996 Compare July 28, 2026 14:14
codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

@coderabbitai coderabbitai Bot added the Roadmap label Jul 28, 2026

@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: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/developers-guide.md (1)

601-612: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Caption the shim inventory table.

Add a concise numbered caption immediately before or after the table.

Triage: [type:docstyle]

Proposed fix
+_Table 1: Removed compatibility shims and their canonical replacements._
+
 | Removed shim | Location | Canonical replacement |

As per coding guidelines, “Caption every table and every diagram in documentation.” As per path instructions, doc-style comments require a Triage paragraph.

🤖 Prompt for 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.

In `@docs/developers-guide.md` around lines 601 - 612, Add a concise numbered
caption immediately before or after the shim inventory table in the developers
guide, identifying it as the table of removed shims and canonical replacements.
Include the required doc-style Triage paragraph near the caption, without
changing the table contents.

Sources: Coding guidelines, Path instructions

🤖 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 `@docs/users-guide.md`:
- Around line 87-98: Update the `lading bump` documentation to state that
configured `bump.lockfile_manifests` entries also include nested lockfiles in
non-Git workspaces, rather than limiting them to lockfiles Git does not track.
Retain the existing Git-tracked discovery behavior and add the required Triage
paragraph for this doc-style change.

In `@tests/unit/conftest.py`:
- Around line 80-95: Update the fixture docstring near the lockfile-stubbing
fixture to include an Examples section showing how the fixture is applied in a
test and that selected modules use deterministic helpers without invoking Git or
Cargo.

In `@tests/unit/test_bump_lockfile_path_resolution.py`:
- Around line 56-66: Change the _inside_dir helper’s multi-line docstring to a
concise single-line docstring. If the rationale about safe parent traversal is
still needed, preserve it as an inline comment within the helper without
changing generation behavior.

---

Outside diff comments:
In `@docs/developers-guide.md`:
- Around line 601-612: Add a concise numbered caption immediately before or
after the shim inventory table in the developers guide, identifying it as the
table of removed shims and canonical replacements. Include the required
doc-style Triage paragraph near the caption, without changing the table
contents.
🪄 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: 205c31ec-7fe6-4e25-b345-a3939996d152

📥 Commits

Reviewing files that changed from the base of the PR and between 37be73c and c112996.

📒 Files selected for processing (21)
  • .github/workflows/ci.yml
  • Makefile
  • docs/contents.md
  • docs/developers-guide.md
  • docs/execplans/regenerate-lockfiles.md
  • docs/lading-design.md
  • docs/repository-layout.md
  • docs/users-guide.md
  • lading/commands/bump_lockfiles.py
  • lading/commands/bump_toml.py
  • lading/commands/lockfile.py
  • lading/commands/publish_index_check.py
  • lading/commands/publish_preflight.py
  • tests/bdd/features/cli.feature
  • tests/bdd/steps/test_bump_steps.py
  • tests/unit/conftest.py
  • tests/unit/publish/__snapshots__/test_preflight_lockfile_validation.ambr
  • tests/unit/test_bump_lockfile_manifest_merge.py
  • tests/unit/test_bump_lockfile_path_resolution.py
  • tests/unit/test_bump_lockfile_rebuild.py
  • tests/unit/test_bump_lockfiles.py
🔗 Linked repositories identified

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

  • leynos/cmd-mox (auto-detected)
  • leynos/cuprum (auto-detected)
  • leynos/shared-actions (auto-detected)

Comment thread docs/users-guide.md Outdated
Comment thread tests/unit/conftest.py
Comment on lines +80 to +95
"""Stub lockfile operations for manifest-focused bump test modules.

Parameters
----------
request : pytest.FixtureRequest
Active test request used to identify the containing test module.
monkeypatch : pytest.MonkeyPatch
Fixture used to replace lockfile discovery and regeneration helpers.

Returns
-------
None
Modules outside ``_LOCKFILE_STUB_MODULES`` are left unchanged; selected
modules receive deterministic helpers that avoid invoking Git or Cargo.

"""

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a usage example to the fixture docstring.

Add an Examples section showing fixture application and the resulting stubbed behaviour.

Triage: [type:docstyle]

As per path instructions, public function documentation must include clear examples demonstrating usage and outcome.

🤖 Prompt for 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.

In `@tests/unit/conftest.py` around lines 80 - 95, Update the fixture docstring
near the lockfile-stubbing fixture to include an Examples section showing how
the fixture is applied in a test and that selected modules use deterministic
helpers without invoking Git or Cargo.

Source: Path instructions

Comment on lines +56 to +66
@st.composite
def _inside_dir(draw: st.DrawFn) -> list[str]:
"""Draw a relative directory path that stays within the workspace.

Alongside real segments and redundant ``.`` segments, this emits safe
``..`` parent-traversal segments that never ascend above the workspace
root after normalisation: a ``..`` is only produced while a prior real
segment remains to cancel it (the running segment balance never drops
below zero). Cases such as ``crate/../Cargo.toml`` are therefore
exercised without allowing traversal above the root.
"""

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use a single-line docstring for this private helper.

Move the generation rationale into an inline comment if it remains necessary.

Proposed fix
 `@st.composite`
 def _inside_dir(draw: st.DrawFn) -> list[str]:
-    """Draw a relative directory path that stays within the workspace.
-
-    Alongside real segments and redundant ``.`` segments, this emits safe
-    ``..`` parent-traversal segments that never ascend above the workspace
-    root after normalisation: a ``..`` is only produced while a prior real
-    segment remains to cancel it (the running segment balance never drops
-    below zero). Cases such as ``crate/../Cargo.toml`` are therefore
-    exercised without allowing traversal above the root.
-    """
+    """Draw a relative directory path that stays within the workspace."""
+    # Permit redundant components while preventing traversal above the root.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@st.composite
def _inside_dir(draw: st.DrawFn) -> list[str]:
"""Draw a relative directory path that stays within the workspace.
Alongside real segments and redundant ``.`` segments, this emits safe
``..`` parent-traversal segments that never ascend above the workspace
root after normalisation: a ``..`` is only produced while a prior real
segment remains to cancel it (the running segment balance never drops
below zero). Cases such as ``crate/../Cargo.toml`` are therefore
exercised without allowing traversal above the root.
"""
`@st.composite`
def _inside_dir(draw: st.DrawFn) -> list[str]:
"""Draw a relative directory path that stays within the workspace."""
# Permit redundant components while preventing traversal above the root.
🤖 Prompt for 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.

In `@tests/unit/test_bump_lockfile_path_resolution.py` around lines 56 - 66,
Change the _inside_dir helper’s multi-line docstring to a concise single-line
docstring. If the rationale about safe parent traversal is still needed,
preserve it as an inline comment within the helper without changing generation
behavior.

Sources: Coding guidelines, Path instructions

@pandalump

Copy link
Copy Markdown
Collaborator

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 28, 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 added Issue and removed Roadmap labels Jul 28, 2026

@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: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/developers-guide.md (1)

601-612: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Caption the shim-inventory table.

Add a table caption immediately after the table, consistent with the captioned table and figure conventions elsewhere in this document.

Triage: [type:docstyle]

As per coding guidelines, every table and diagram requires a caption.

🤖 Prompt for 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.

In `@docs/developers-guide.md` around lines 601 - 612, Add a descriptive caption
immediately after the shim-inventory table in the developers guide, following
the existing caption syntax and conventions used by other tables and figures in
the document. Keep the caption specific to the removed compatibility shims and
do not alter the table contents.

Sources: Coding guidelines, Path instructions

♻️ Duplicate comments (1)
docs/users-guide.md (1)

87-98: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Carry the non-Git fallback wording into the tutorial too.

The tutorial still reads "for lockfiles that git does not track", but the configuration reference two hundred lines down (Lines 285-290) now correctly adds "and for nested lockfiles when the workspace is outside a Git repository". Sync the tutorial with the reference so readers scanning only the tutorial do not skip configuring bump.lockfile_manifests in a non-Git workspace.

📝 Proposed fix
-adjacent `Cargo.toml`, plus any additional manifests listed in
-`bump.lockfile_manifests` for lockfiles that git does not track. The result
-header counts each changed category, e.g. "N manifest(s)", "N documentation
+adjacent `Cargo.toml`. It also refreshes manifests listed in
+`bump.lockfile_manifests`, including nested lockfiles in non-Git workspaces,
+where Git discovery returns no manifests. The result header counts each
+changed category, e.g. "N manifest(s)", "N documentation
🤖 Prompt for 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.

In `@docs/users-guide.md` around lines 87 - 98, Update the tutorial’s lockfile
description in the `lading bump` documentation to include nested lockfiles when
the workspace is outside a Git repository, matching the wording and behavior
described in the `bump.lockfile_manifests` configuration reference. Preserve the
existing tracked-lockfile and additional-manifest details.
🤖 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 `@docs/developers-guide.md`:
- Around line 212-220: Update the bump_lockfiles description to identify it as
owning bump-side manifest merging and regeneration, rather than Cargo lockfile
discovery. Preserve the explicit attribution of discovery to
lading.commands.lockfile.discover_tracked_lockfiles and keep the existing
details about merge ordering and regeneration behavior unchanged.

In `@docs/execplans/regenerate-lockfiles.md`:
- Around line 62-64: Update the line-count reference for
lading/commands/bump_lockfiles.py in the execplan from 155 to 379, while
preserving the existing 400-line repository limit and surrounding guidance.

In `@lading/commands/lockfile.py`:
- Around line 16-21: Update the documentation describing lading bump’s
regenerate_lockfiles behavior to explicitly state that it also regenerates the
workspace-root lockfile from Cargo.toml, even when that file is not discovered
or configured; keep the existing distinction between bump and validation
behavior intact.

In `@tests/unit/test_bump_lockfile_manifest_merge.py`:
- Around line 186-193: Update the expected_discovered helper in the test to
format each generated Cargo.toml path with the same POSIX conversion used by
merge_discovered_manifests, replacing plain str() while preserving the existing
filtering and sorting behavior.

---

Outside diff comments:
In `@docs/developers-guide.md`:
- Around line 601-612: Add a descriptive caption immediately after the
shim-inventory table in the developers guide, following the existing caption
syntax and conventions used by other tables and figures in the document. Keep
the caption specific to the removed compatibility shims and do not alter the
table contents.

---

Duplicate comments:
In `@docs/users-guide.md`:
- Around line 87-98: Update the tutorial’s lockfile description in the `lading
bump` documentation to include nested lockfiles when the workspace is outside a
Git repository, matching the wording and behavior described in the
`bump.lockfile_manifests` configuration reference. Preserve the existing
tracked-lockfile and additional-manifest details.
🪄 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: a78be84e-1910-456e-8d7b-041babf8adf2

📥 Commits

Reviewing files that changed from the base of the PR and between 37be73c and c112996.

📒 Files selected for processing (21)
  • .github/workflows/ci.yml
  • Makefile
  • docs/contents.md
  • docs/developers-guide.md
  • docs/execplans/regenerate-lockfiles.md
  • docs/lading-design.md
  • docs/repository-layout.md
  • docs/users-guide.md
  • lading/commands/bump_lockfiles.py
  • lading/commands/bump_toml.py
  • lading/commands/lockfile.py
  • lading/commands/publish_index_check.py
  • lading/commands/publish_preflight.py
  • tests/bdd/features/cli.feature
  • tests/bdd/steps/test_bump_steps.py
  • tests/unit/conftest.py
  • tests/unit/publish/__snapshots__/test_preflight_lockfile_validation.ambr
  • tests/unit/test_bump_lockfile_manifest_merge.py
  • tests/unit/test_bump_lockfile_path_resolution.py
  • tests/unit/test_bump_lockfile_rebuild.py
  • tests/unit/test_bump_lockfiles.py
🔗 Linked repositories identified

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

  • leynos/cmd-mox (auto-detected)
  • leynos/cuprum (auto-detected)
  • leynos/shared-actions (auto-detected)

Comment thread docs/developers-guide.md Outdated
Comment thread docs/execplans/regenerate-lockfiles.md Outdated
Comment on lines +62 to +64
- No single code file may exceed 400 lines (repository rule); adding to
`lading/commands/bump_lockfiles.py` (155 lines) and `lading/commands/bump.py`
must respect this.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Correct the stale capacity figure.

Update the stated bump_lockfiles.py line count. The supplied implementation reaches Line 379, not 155, leaving materially less headroom under the 400-line limit.

Triage: [type:docstyle]

As per coding guidelines, execplans must be kept up to date with the progress of changes.

🤖 Prompt for 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.

In `@docs/execplans/regenerate-lockfiles.md` around lines 62 - 64, Update the
line-count reference for lading/commands/bump_lockfiles.py in the execplan from
155 to 379, while preserving the existing 400-line repository limit and
surrounding guidance.

Sources: Coding guidelines, Path instructions

Comment thread lading/commands/lockfile.py
Comment thread tests/unit/test_bump_lockfile_manifest_merge.py
Attribute discovery to its defining module, document unconditional root
regeneration and non-Git configuration, and align the manifest-merge
property with the POSIX path contract.
codescene-access[bot]

This comment was marked as outdated.

@codescene-access codescene-access 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.

No quality gates enabled for this code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants