#1153

feat(support): permit gate-backed 1.0 release claims in the support manifest

Openiamgpwants to merge intofrom

Implements two ADR 0053 exit criteria (decision 1 and section 7) without changing what the manifest reports.

Schema

registry/support/schema/v1.json replaces its const pins with closed enums:

  • current_release.maturity: alpha or supported (reuses the existing status vocabulary).
  • $defs.maturity (component current_maturity) adds supported. The validator allows it only for blessed_core components with target status supported in a production-ready release.
  • current_release.production_ready: boolean.
  • artifact_pinning: not_yet_published or published.
  • production.status: blocked, required_before_release, or passed.

Validator

scripts/validate_support_manifest.py enforces what the schema cannot:

  • production_ready: true requires all five required gates passed and every blessed_core gate component passed or not_required.
  • production.status is derived: blocked until those gates pass, required_before_release while production_ready is false, and passed only with production_ready: true.
  • maturity: supported exactly when production_ready: true.
  • A gate component with no applicable gates must report not_required, and it still needs checked evidence. Before this change it could only fail.
  • Release guard: a current_release.version at or above 1.0.0 is rejected unless production_ready is true. Versions are parsed with the full PEP 440 grammar (spelling variants, epochs, local labels) and ordered as in PEP 440, so 1.0.0rc1 and 1.0.0.dev1 sort below 1.0.0 and are allowed, which matches the ADR's "explicit pre-release suffix" wording. 1.0.0.post1 and 1.1.0rc1 are rejected. An unparseable version also fails.

Where the guard runs

relx rewrites current_release.version in the release PR. The always-run ci-config step in ci.yml validates the manifest, and pr.yml runs it on that PR and in the merge queue. release_stage.py reserve requires a successful exact-SHA Main source health run, which reuses or reruns the same pr.yml checks. No workflow change was needed.

ReleaseX replacement

The current_release.version replacement in relx.toml now matches "version": "X",\n "maturity": " without the maturity value, so it still matches exactly once after the manifest flips to supported. A new test in tests/tooling/test_release_replacements.py covers both maturities. The versioning strategy is unchanged. docs/contributing/release-publication.md now says the readiness flip and regenerated reference docs land on main before the release PR.

Unchanged

registry/support/v1.json still reports alpha, production_ready: false, not_yet_published, and production.status: blocked, and it still validates. The relx replacement still matches exactly once.

Verification

  • make check: every lane passed on the final tree (exit 0).
  • python3 -I scripts/validate_support_manifest.py, check_version_drift.py, check_ci_package_groups.py, and generate_reference_docs.py --check all pass.
  • The new tests in tests/tooling/test_support_manifest.py fail against the previous validator: 13 failures before the review fixes. More cases were added afterwards.

    

Activity

316
coldtea-pr-lens[bot]3h ago
  • Redraw · drawn at 373e88c, the branch has moved on

Architecture


Data flow


Review

2 findings addressed · reviewed 373e88c

TIP

Open a diagram on the canvas, then press W or click play to walk through the change one step at a time

🪧 More tips
  • Run npx skills add coldteadotai/pr-lens, then tell your coding agent: "Diagram the change you just made with PR Lens and attach it to the pull request."
  • Run npx @coldtea/pr-lens-cli analyze --base origin/main on a branch, then npx @coldtea/pr-lens-cli render .pr-lens/graph.json. Same lenses, your own model key, before the pull request exists
  • Click the link under each diagram to open it on a canvas you can zoom, pan and step through
  • The diagrams are links. Click one to open it on the canvas, then press W or click play to walk through the change
  • The CLI's render reads .github/pr-lens.yml and applies your renames, exclusions and lane pins at draw time
  • Set github.comment.collapsed: true in .github/pr-lens.yml to fold the comment behind one View architecture… row. Drawing still runs as before
  • Set github.draw: on-demand in .github/pr-lens.yml and PR Lens stops drawing pull requests on its own. Comment @pr-lens draw on a pull request when you want that one drawn
  • Add .github/workflows/pr-lens.yml with coldteadotai/pr-lens/packages/action@v0 and your model provider's key as its api-key to run PR Lens from your own CI. Any /chat/completions endpoint works
  • After a push, tick Redraw to draw the latest commit
  • Switch GitHub to dark mode and the diagrams follow. The moving dots are this pull request's data in motion
  • Set github.description: false in .github/pr-lens.yml to stop PR Lens adding buttons to your PR descriptions

Thanks for using PR Lens! It's free for OSS. If it helped, a star helps other teams find it. 

coldtea-pr-lens[bot]reviewed3h ago
coldtea-pr-lens[bot]reviewed3h ago
coldtea-pr-lens[bot]reviewed3h ago
phlo-agent[bot]3h ago

Reviewed 373e88c against ADR 0053 and the release tooling. The new validator rules match decision 1 on inspection, but the 1.0 release path has an integration break and two consistency gaps.

1. relx cannot generate a release PR once the readiness claim is true (blocking)

relx.toml#L18-L23 rewrites current_release.version with a literal search that includes "maturity": "alpha" and expected_matches = 1. The new rule at validate_support_manifest.py#L951-L954 requires maturity: supported whenever production_ready is true, and test_support_manifest.py#L729-L730 explicitly accepts a production-ready manifest at 0.18.0, so flipping readiness on main before the version bump is a supported state.

Once main carries "maturity": "supported", the relx search finds zero matches: the 1.0.0 release PR, and every release PR after it, fails expected_matches = 1. If the flip is deferred into the release PR instead, relx writes 1.0.0 with maturity: alpha and production_ready: false, and this PR's guard rejects the PR, leaving a manual edit that release-publication.md#L61 currently says is not required.

Please make the replacement maturity-agnostic (the current_release block is unique, so the version line can be matched without the maturity line), or update relx.toml as part of the 1.0 change, and document the readiness flip and doc regeneration step. The "still matches exactly once" note only holds while the manifest is alpha.

2. A 1.0 manifest still cannot report its components as supported

schema/v1.json#L69-L72 omits supported from $defs.maturity, and validate_support_manifest.py#L466-L474 maps target_status: supported to current_maturity: alpha (enforced at #L569-L573). A 1.0 manifest therefore either keeps every blessed component at alpha — and the generated matrix will say "Release 1.0.0 has supported maturity" next to "Current maturity: alpha" for each package (generate_reference_docs.py#L385, #L412) — or fails validation if a component is set to supported. If 1.0 is meant to cover those components, the enum and _EXPECTED_MATURITY need the same change; otherwise the generated page should distinguish release maturity from component maturity.

3. Version parsing is narrower than the documented PEP 440 contract (minor)

The regex at validate_support_manifest.py#L919 accepts only a subset of PEP 440. 1.0.0-rc.1 and 1.0.0_rc1 are valid PEP 440 pre-releases of 1.0.0 (normalizing to 1.0.0rc1) but are reported as "not a PEP 440 version"; 1.0.0.0rc1 is treated as at or above 1.0.0 because the release tuple is not exactly (1, 0, 0) and the suffix is ignored (#L923-L925). If those spellings can reach pyproject.toml, the guard blocks legitimate pre-releases; otherwise narrow the error wording and the generated docs to the grammar actually accepted.

Checked the schema, validator, generated docs, relx replacements, and the source-health/staging path. PR Validation run 41145946487 was still queued at review time, so the claimed make check result is not yet corroborated by CI. I did not execute PR code.