Skip to content

fix(ci): allow packaging>=26 so twine check accepts Metadata-Version 2.5 - #411

Merged
azalio merged 3 commits into
mainfrom
fix-ci-packaging-metadata-25
Aug 12, 2026
Merged

fix(ci): allow packaging>=26 so twine check accepts Metadata-Version 2.5#411
azalio merged 3 commits into
mainfrom
fix-ci-packaging-metadata-25

Conversation

@azalio

@azalio azalio commented Aug 12, 2026

Copy link
Copy Markdown
Owner

Summary

Latest CI run on main (31465691220) fails in the build job:

Checking dist/mapify_cli-3.24.1-py3-none-any.whl: ERROR InvalidDistribution: Invalid distribution metadata: '2.5' is not a valid metadata version

Root cause

The packaging>=24.2,<26 cap introduced in #195 forces pip to downgrade the runner's preinstalled packaging 26.3 to 25.0. Current setuptools emits Metadata-Version 2.5 wheels, which packaging 25.0 does not recognize, so twine check aborts.

Fix

Bump the pin to packaging>=26 in ci.yml, release.yml, test-pypi.yml + CHANGELOG entry.

Verification (local, same wheel)

  • uv run --with 'twine>=6.2.0' --with 'packaging>=24.2,<26' python -m twine check dist/*FAILS (repro)
  • uv run --with 'twine>=6.2.0' --with 'packaging>=26' python -m twine check dist/*PASSED

Unblocks the release: release.yml has the identical step and would fail at publish time.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Updated package validation to support newer package metadata and prevent valid distributions from being rejected.
    • Applied the fix across continuous integration, TestPyPI, and release validation workflows.
  • Documentation

    • Added Unreleased changelog entries covering recent fixes, CLI guidance, session limits, memory behavior, review artifacts, and monitoring feedback.
    • Added an assessment of potential invariant-lineage improvements and future validation options.

The packaging>=24.2,<26 cap (#195) downgrades packaging to 25.0 in the
build job, and 25.0 does not recognize Metadata-Version 2.5 emitted by
current setuptools. twine check then fails with InvalidDistribution:
'2.5' is not a valid metadata version. Verified locally: same wheel
fails twine check with packaging<26 and passes with packaging>=26.
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The workflows now install packaging>=26. The changelog records related updates. A new spike assesses Specula and defines staged invariant-lineage and wave-coordinator validation for MAP Framework.

Changes

Packaging validation

Layer / File(s) Summary
Update packaging validation requirement
.github/workflows/ci.yml, .github/workflows/release.yml, .github/workflows/test-pypi.yml, CHANGELOG.md
The workflows replace packaging>=24.2,<26 with packaging>=26. The changelog records packaging, Wayfind, runner, settings, fixture, parity, and documentation updates.

Specula applicability assessment

Layer / File(s) Summary
Assess Specula and define invariant lineage
docs/spikes/specula-applicability.md
The spike documents Specula’s method, evidence, limitations, MAP constraints, and the proposed Invariant_Lineage_v1 contract.
Define staged wave-coordinator validation
docs/spikes/specula-applicability.md
The spike defines staged adoption, bounded wave scenarios, runtime trace collection, acceptance criteria, and promotion or rejection gates.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Poem

I’m a rabbit mapping invariants bright,
While packaging hops to version twenty-six tonight.
Wave traces run through bounded ground,
Specula’s scope is carefully found.
Hop by hop, the changelog keeps the sound.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main CI dependency change and its purpose for twine check.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-ci-packaging-metadata-25

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Mikhail [azalio] Petrov added 2 commits August 12, 2026 11:47
Gate 12 of the release workflow found 15 commits since v3.24.1 but only
4 CHANGELOG entries. Adds entries for #379, #390, #393, #395, #396,
#397, #399, #400/#401, #404, #408, #409 and the untracked 6-bug sweep
(db028b6).

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

🤖 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/spikes/specula-applicability.md`:
- Around line 368-380: Extend the process-interruption scenario in the
experiment plan through restart and reconciliation: restart the interrupted
runtime, reconcile the persisted partial state, and verify resumption or
terminal handling as required. Repeat reconciliation to demonstrate idempotence,
asserting that group visibility, main HEAD, worktrees, and rendered runtime
artifacts remain correct after both passes.
- Around line 392-404: Update the bounded exploration and resource-bound
requirements to define finite constants for every state dimension, including
event counts, retries, failure choices, Git states, and coordinator ownership.
Require TLC to exhaust that explicitly finite state space and report complete
exploration separately from successful execution or resource-limit termination.
- Around line 165-190: Define the versioned Invariant_Lineage_v1 schema before
implementing validation, including source-specific reference shapes for code,
test, issue, commit, document, user_decision, and external references. Add an
explicit verification-method vocabulary and a rationale field required when
fault_model is none, while preserving the stated lineage and validation
requirements.
- Around line 7-8: Update the spike’s MAP metadata to record the exact commit
SHA instead of main, and revise all source and test lineage references to
include both a revision and a stable symbol or content hash rather than relying
on file/line ranges. Apply this consistently to the captured revision and the
referenced sections.
- Around line 162-183: Update the validator described in the Requirements Index
contract to require non-empty lineage for every entry whose kind is invariant,
regardless of its identifier prefix. Keep INV-* naming validation as a separate
rule only if that convention remains mandatory, so identifier format does not
control lineage enforcement.
🪄 Autofix

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: CHILL

Plan: Pro Plus

Run ID: 709b3013-b544-42d5-8e2e-7c463224954d

📥 Commits

Reviewing files that changed from the base of the PR and between 7b84237 and eba18cd.

📒 Files selected for processing (2)
  • CHANGELOG.md
  • docs/spikes/specula-applicability.md

Comment on lines +7 to +8
**Captured:** 2026-07-29 against MAP Framework `main` and Specula revision
[`d45b873`](https://github.com/specula-org/Specula/tree/d45b873bc19cf51bc26fd845fce072d9b99b5cd0).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Pin the MAP revision and make lineage references stable.

The spike records MAP as main, and the validator checks current file/line or test references. A line range can remain valid while pointing to different code. The required stale-lineage cases can then pass incorrectly.

Record the exact MAP commit SHA. Require each source and test reference to include a revision plus a stable symbol or content hash.

Also applies to: 182-190, 306-316

🤖 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/spikes/specula-applicability.md` around lines 7 - 8, Update the spike’s
MAP metadata to record the exact commit SHA instead of main, and revise all
source and test lineage references to include both a revision and a stable
symbol or content hash rather than relying on file/line ranges. Apply this
consistently to the captured revision and the referenced sections.

Comment on lines +162 to +183
Adopt a low-cost `Invariant_Lineage_v1` contract inside each Requirements Index
`kind: invariant` entry:

```yaml
- id: INV-1
kind: invariant
lineage:
sources:
- kind: code
ref: src/module.py:120-138
scenario: concurrent wave abort after a partial squash merge
fault_model: merge conflict, process interruption, or failed verification
verification:
method: test
ref: tests/test_wave.py::test_abort_restores_base
```

The source-kind vocabulary should cover `code`, `test`, `issue`, `commit`,
`document`, and `user_decision`. A deterministic validator should:

1. require non-empty lineage for every indexed `INV-*`;
2. validate repo `file:line` ranges, test references, commit existence, and

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Use one authoritative invariant predicate.

The contract targets Requirements Index entries with kind: invariant, but the validator rule targets only INV-* identifiers. If an invariant uses another identifier prefix, it can bypass lineage validation.

Require lineage when kind == invariant. Validate the INV-* naming convention separately if that prefix is mandatory.

Proposed clarification
- require non-empty lineage for every indexed `INV-*`;
+ require non-empty lineage for every indexed entry where `kind: invariant`;
+ validate the `INV-*` identifier format separately, if required;
📝 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
Adopt a low-cost `Invariant_Lineage_v1` contract inside each Requirements Index
`kind: invariant` entry:
```yaml
- id: INV-1
kind: invariant
lineage:
sources:
- kind: code
ref: src/module.py:120-138
scenario: concurrent wave abort after a partial squash merge
fault_model: merge conflict, process interruption, or failed verification
verification:
method: test
ref: tests/test_wave.py::test_abort_restores_base
```
The source-kind vocabulary should cover `code`, `test`, `issue`, `commit`,
`document`, and `user_decision`. A deterministic validator should:
1. require non-empty lineage for every indexed `INV-*`;
2. validate repo `file:line` ranges, test references, commit existence, and
Adopt a low-cost `Invariant_Lineage_v1` contract inside each Requirements Index
`kind: invariant` entry:
🤖 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/spikes/specula-applicability.md` around lines 162 - 183, Update the
validator described in the Requirements Index contract to require non-empty
lineage for every entry whose kind is invariant, regardless of its identifier
prefix. Keep INV-* naming validation as a separate rule only if that convention
remains mandatory, so identifier format does not control lineage enforcement.

Comment on lines +165 to +190
```yaml
- id: INV-1
kind: invariant
lineage:
sources:
- kind: code
ref: src/module.py:120-138
scenario: concurrent wave abort after a partial squash merge
fault_model: merge conflict, process interruption, or failed verification
verification:
method: test
ref: tests/test_wave.py::test_abort_restores_base
```

The source-kind vocabulary should cover `code`, `test`, `issue`, `commit`,
`document`, and `user_decision`. A deterministic validator should:

1. require non-empty lineage for every indexed `INV-*`;
2. validate repo `file:line` ranges, test references, commit existence, and
typed external/user-decision references without dereferencing secrets;
3. require a non-empty scenario, an explicit fault model (`none` allowed only
with rationale), and a named verification method;
4. preserve the lineage through parsing, `coverage_map`, verification summary,
and review bundle; and
5. report `missing_lineage` separately from `missing_evidence`—declaring an
owner or repeating `[INV-1]` must not self-certify provenance.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Define the Invariant_Lineage_v1 schema before implementation.

The example defines only a code source and verification.method: test. The rules also require issue, commit, document, user-decision, and external references. Their shapes and allowed values are unspecified.

The rule for fault_model: none requires a rationale, but the example has no rationale field. Add a versioned schema, source-specific reference types, a verification-method vocabulary, and an explicit rationale field.

🤖 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/spikes/specula-applicability.md` around lines 165 - 190, Define the
versioned Invariant_Lineage_v1 schema before implementing validation, including
source-specific reference shapes for code, test, issue, commit, document,
user_decision, and external references. Add an explicit verification-method
vocabulary and a rationale field required when fault_model is none, while
preserving the stated lineage and validation requirements.

Comment on lines +368 to +380
Bound the first model to two subtasks and one wave, then cover:

- full success;
- conflict on the second squash merge;
- post-wave verification failure after both squash merges;
- external HEAD movement before merge;
- process interruption after `begin_wave_group` and before all terminal events;
- rollback that returns without moving HEAD.

Use actual temporary Git repositories and the rendered runtime for trace
collection. Mock-only lifecycle traces are insufficient because the experiment
is specifically testing conformance between the model, Git effects, and
sidecar state.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

Extend the interruption scenario through reconciliation.

The scenario stops after process interruption. This tests persisted partial state, but it does not test restart, reconciliation, resume, or idempotence. Those behaviors are required by the crash-visible lifecycle and Phase 2 plan.

Add a restart and reconciliation step. Repeat reconciliation and assert that group visibility, main HEAD, worktrees, and runtime artifacts remain correct.

🤖 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/spikes/specula-applicability.md` around lines 368 - 380, Extend the
process-interruption scenario in the experiment plan through restart and
reconciliation: restart the interrupted runtime, reconcile the persisted partial
state, and verify resumption or terminal handling as required. Repeat
reconciliation to demonstrate idempotence, asserting that group visibility, main
HEAD, worktrees, and rendered runtime artifacts remain correct after both
passes.

Comment on lines +392 to +404
4. **Bounded exploration:** TLC exhausts the two-subtask bounded state space;
simulation-only results do not satisfy the experiment.
5. **Real confirmation:** every reported counterexample is reproduced against
the rendered Python runtime in an isolated real Git repository. An
unreproduced model violation is recorded as a model/harness gap, not a MAP
bug.
6. **Incremental value:** compare findings against the existing wave tests. A
promotion decision requires at least one previously uncovered reachable
defect or a concrete reachable transition gap that becomes a regression
test; restating existing tests is a negative result.
7. **Resource bound:** stop at four wall-clock hours, 32 GB TLC memory, and
$75 equivalent model cost. Record actual time, token cost, peak memory,
model/effort, Specula SHA, MAP SHA, and explored-state count.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

Define a finite TLC state space.

Two subtasks and one wave do not bound event counts, retries, failure choices, Git states, or coordinator ownership. TLC cannot exhaust the model unless every such domain is finite.

Define finite constants for each state dimension. Require the run to report complete state-space exploration, not only successful execution within the resource limit.

🤖 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/spikes/specula-applicability.md` around lines 392 - 404, Update the
bounded exploration and resource-bound requirements to define finite constants
for every state dimension, including event counts, retries, failure choices, Git
states, and coordinator ownership. Require TLC to exhaust that explicitly finite
state space and report complete exploration separately from successful execution
or resource-limit termination.

@azalio
azalio merged commit 8f674fc into main Aug 12, 2026
7 checks passed
@azalio
azalio deleted the fix-ci-packaging-metadata-25 branch August 12, 2026 10:49
azalio added a commit that referenced this pull request Aug 12, 2026
…notes excerpt (#412)

Two release-pipeline defects found while releasing 3.25.0:

1. pypa/gh-action-pypi-publish@v1.13.0 bundles an older twine that
   rejects Metadata-Version 2.5 wheels (InvalidDistribution). The
   repo's own twine-check step was already fixed in #411, but the
   action runs its own check internally. v1.14.2 ships twine v7 with
   core-metadata 2.5 support (upstream #416). Applied in release.yml
   and test-pypi.yml.

2. The GitHub Release changelog excerpt was always empty: the
   two-address awk range /^## \[VERSION\]/,/^## \[/ collapses to a
   single line because the version heading matches both patterns, so
   every release body fell back to 'See CHANGELOG.md for details.'
   (verified on v3.24.1). Replaced with a flag state machine in
   release.yml, the release-checklist issue template, and the
   map-release skill (.jinja source + rendered trees).

Co-authored-by: Mikhail [azalio] Petrov <azalio@yandex-team.ru>
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.

1 participant