diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6f9926af..5d7718ac 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,12 +1,14 @@
# Changelog
-## 0.2.11 - Release candidate; not published
+## 0.2.11 - Released
-QF Solver 0.2.11 is being prepared as a cumulative update to the published
-0.2.10 solver. The package version in this candidate is 0.2.11, while the
-latest public PyPI/GitHub/Zenodo release and `CITATION.cff` remain 0.2.10
-until a separate release authorization and publication. This entry describes
-the candidate scope; it does not announce a release or assign a version DOI.
+QF Solver 0.2.11 is a cumulative update to 0.2.10, published on 2026-10-07.
+Its version DOI is [`10.5281/zenodo.23214487`](https://doi.org/10.5281/zenodo.23214487);
+the project concept DOI remains
+[`10.5281/zenodo.22697897`](https://doi.org/10.5281/zenodo.22697897). This
+entry describes bounded capabilities and their exclusions. The audited
+distribution is limited to the selected wheel, sdist and checksum manifest;
+the complete repository archive is not cleared.
### Added
@@ -45,19 +47,18 @@ the candidate scope; it does not announce a release or assign a version DOI.
### API and packaging
-- The candidate adds `rotating_modal` and `campbell` routes with provisional
- result contracts. They are not represented as stable API guarantees before
- the 0.2.11 publication decision.
+- The release includes `rotating_modal` and `campbell` routes with experimental
+ result contracts. They are not represented as stable downstream API
+ guarantees.
- Fixed Campbell execution-provenance hashing to resolve implementation files
from the installed wheel layout as well as a source checkout; no solver or
tracking calculation changed.
-- Package metadata identifies 0.2.11; `CITATION.cff` continues to identify the
- actually published 0.2.10 release. The package DOI URL uses the published
- project concept DOI until a version DOI exists.
+- Package and citation metadata identify 0.2.11. The project DOI URL continues
+ to use the concept DOI; exact-version citation uses the 0.2.11 version DOI.
### Documentation
-- Added candidate What's New and V&V summaries and made the rotating-modal and
+- Added What's New and V&V summaries and made the rotating-modal and
Campbell scope, ambiguity, provenance, and maturity visible in the public
documentation.
diff --git a/CITATION.cff b/CITATION.cff
index abcfdde9..150519df 100644
--- a/CITATION.cff
+++ b/CITATION.cff
@@ -1,8 +1,10 @@
cff-version: 1.2.0
-message: "For the evolving project, use concept DOI 10.5281/zenodo.22697897. For exact-version reproducibility, use a published version DOI when assigned. This metadata identifies version 0.2.11 without asserting a release date or version DOI."
+message: "For QF Solver 0.2.11, cite version DOI 10.5281/zenodo.23214487. Use concept DOI 10.5281/zenodo.22697897 to cite the project across versions."
type: software
title: "QF Solver"
version: "0.2.11"
+date-released: "2026-10-07"
+doi: "10.5281/zenodo.23214487"
license: "Apache-2.0"
authors:
- family-names: "Farinazzo"
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 2151cf78..4a7adb2e 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -16,8 +16,9 @@ cases.
## Current release state
-QF Solver `0.2.10` (`v0.2.10`) is the current published release. New changes
-on the default branch do not change the published scope. The public
+QF Solver `0.2.11` (`v0.2.11`) is the current published release. Its version
+DOI is [`10.5281/zenodo.23214487`](https://doi.org/10.5281/zenodo.23214487).
+New changes on the default branch do not change the published scope. The public
[capability index](docs/capabilities/index.md) and [V&V/maturity guide](docs/verification/evidence-and-maturity.md)
define the current bounded scope; historical 0.2.7 evidence must remain
unchanged.
diff --git a/README.md b/README.md
index 11e64d99..96e408f8 100644
--- a/README.md
+++ b/README.md
@@ -512,18 +512,18 @@ and the controlling evidence record for the chosen analysis.
## Current release and citation
-The current QF Solver release is `0.2.11`; it follows the published `0.2.10`
-release. The [What's New in 0.2.11](docs/whats-new/0.2.11.md) page summarizes
-the changes, while the [changelog](CHANGELOG.md) retains the full project
-history.
-
-Use a version DOI for exact-release reproducibility when one is assigned. Use
-the version DOI for the preceding release, `10.5281/zenodo.23106744`, when
-citing 0.2.10. Use the project concept DOI
+The current QF Solver release is `0.2.11`, published on 2026-10-07. Cite this
+version with [DOI `10.5281/zenodo.23214487`](https://doi.org/10.5281/zenodo.23214487).
+The preceding 0.2.10 release has version DOI
+[`10.5281/zenodo.23106744`](https://doi.org/10.5281/zenodo.23106744). Use the
+project concept DOI
[`10.5281/zenodo.22697897`](https://doi.org/10.5281/zenodo.22697897) to cite
-QF Solver as a project. The previous release used source tag
+QF Solver across versions. [`CITATION.cff`](CITATION.cff) provides
+machine-readable citation metadata. The preceding release used source tag
[`v0.2.10`](https://github.com/emptiesvoid-cloud/QF_solver/tree/v0.2.10).
-[`CITATION.cff`](CITATION.cff) provides machine-readable citation metadata.
+The 0.2.11 selected wheel, sdist and checksum manifest are the audited
+distribution artifacts. GitHub's automatically generated source archives are
+not part of that selected distribution.
The whole-repository G03 archive gate remains **FAIL**, the full repository
archive is not cleared, and WP14 remains **HOLD_NOT_PROMOTED**. Selected
distribution checks do not change those states.
diff --git a/SECURITY.md b/SECURITY.md
index ba0421c7..b4e6492c 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -5,14 +5,14 @@
| Version or channel | Security support |
| --- | --- |
| Latest published release | Best-effort security support. |
-| Current `0.2.10` release | Best-effort security support for the published release. |
+| Current `0.2.11` release | Best-effort security support for the published release. |
| Older releases | Best effort only; not actively supported. |
Support is provided on a best-effort basis. A security fix does not imply
certification or qualification for a broader technical scope.
-Current release: `0.2.10` / `v0.2.10`. Version DOI:
-[`10.5281/zenodo.23106744`](https://doi.org/10.5281/zenodo.23106744).
+Current release: `0.2.11` / `v0.2.11`. Version DOI:
+[`10.5281/zenodo.23214487`](https://doi.org/10.5281/zenodo.23214487).
## Reporting
diff --git a/SUPPORT.md b/SUPPORT.md
index 6d7c0fb7..dffd4189 100644
--- a/SUPPORT.md
+++ b/SUPPORT.md
@@ -7,8 +7,10 @@ Support is best-effort. QF_solver is not certified software and does not
replace an engineer's independent model review, boundary-condition review,
mesh-quality assessment or validation against the intended application.
-The latest published release, currently `0.2.10`, is the normal support
-reference. Questions should include the exact release tag or source revision
+The latest published release, currently `0.2.11`, is the normal support
+reference. Its tag is `v0.2.11` and its version DOI is
+[`10.5281/zenodo.23214487`](https://doi.org/10.5281/zenodo.23214487). Questions
+should include the exact release tag or source revision
when reproducibility matters. Older releases are supported on a best-effort
basis and are not actively maintained by default.
diff --git a/docs/getting-started/installation.md b/docs/getting-started/installation.md
index 64385a35..829e8930 100644
--- a/docs/getting-started/installation.md
+++ b/docs/getting-started/installation.md
@@ -12,15 +12,17 @@ approver: ""
This guide applies to QF Solver `0.2.11`. Release availability is
authoritative on [PyPI](https://pypi.org/project/qf-solver/) and
[GitHub Releases](https://github.com/emptiesvoid-cloud/QF_solver/releases).
-Only the exact selected wheel/sdist bytes bound to a successful release audit
-are audited distribution artifacts; this page is not an upload confirmation.
+The selected QF Solver `0.2.11` wheel and sdist are the audited PyPI release
+artifacts. Their exact hashes are recorded in the selected-release contract
+and checksum manifest. GitHub's automatically generated source archives are
+not part of the audited selected distribution.
See [What's New in 0.2.11](../whats-new/0.2.11.md) for the release
scope and [the capability index](../capabilities/index.md) for maturity
boundaries.
## User installation
-Install the exact version from the package index after its release upload:
+Install the published release from PyPI:
```bash
python -m pip install "qf-solver==0.2.11"
@@ -38,8 +40,8 @@ python -m pip install .
qf-solver --version
```
-The tag command applies once that release tag exists. The default branch is
-not a promise that it contains a specific release.
+The `v0.2.11` tag is immutable and identifies the source used for the release.
+The default branch may advance and is not a release selector.
The published core package requires Python 3.10 or newer. The recommended
public import is:
diff --git a/docs/index.md b/docs/index.md
index d69b3b67..e35f2809 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -10,6 +10,8 @@ approver: ""
# QF Solver
**Current release documentation:** `0.2.11`
+**Published:** 2026-10-07
+**Version DOI:** [`10.5281/zenodo.23214487`](https://doi.org/10.5281/zenodo.23214487)
**Project concept DOI:** [`10.5281/zenodo.22697897`](https://doi.org/10.5281/zenodo.22697897)
QF Solver is an inspectable Python finite-element solver for structural
@@ -76,13 +78,14 @@ be represented as audited Python distribution artifacts.
The full-repository G03 archive gate remains failed; automatic GitHub source
archives and a complete repository archive are not represented as cleared.
-For reproducibility, cite a published exact-version DOI when one is assigned.
-The DOI [`10.5281/zenodo.23106744`](https://doi.org/10.5281/zenodo.23106744)
-identifies the preceding 0.2.10 release, not 0.2.11. Use
-[concept DOI `10.5281/zenodo.22697897`](https://doi.org/10.5281/zenodo.22697897)
-to cite the project across versions. The machine-readable
+For exact-version reproducibility, cite the 0.2.11 version DOI
+[`10.5281/zenodo.23214487`](https://doi.org/10.5281/zenodo.23214487). The
+preceding 0.2.10 release has version DOI
+[`10.5281/zenodo.23106744`](https://doi.org/10.5281/zenodo.23106744). Use the
+project concept DOI [`10.5281/zenodo.22697897`](https://doi.org/10.5281/zenodo.22697897)
+to cite QF Solver across versions. The machine-readable
[`CITATION.cff`](https://github.com/emptiesvoid-cloud/QF_solver/blob/main/CITATION.cff)
-identifies version 0.2.11 without asserting a publication date or version DOI.
+records the 0.2.11 version DOI and publication date.
Release availability is authoritative on [PyPI](https://pypi.org/project/qf-solver/)
and [GitHub Releases](https://github.com/emptiesvoid-cloud/QF_solver/releases).
diff --git a/docs/reference/feuille_de_route.md b/docs/reference/feuille_de_route.md
index 4ecdfff9..9af73560 100644
--- a/docs/reference/feuille_de_route.md
+++ b/docs/reference/feuille_de_route.md
@@ -9,9 +9,11 @@ approver: ""
# Public roadmap
-QF Solver 0.2.11 is the current documentation baseline. Version 0.2.9 was a
-development/source snapshot, not a PyPI package, GitHub Release, or version
-DOI. This roadmap is a product-level orientation; it is not a release gate,
+QF Solver 0.2.11 is the current documentation baseline. QF Solver 0.2.11 is
+the current published release. It was published on 2026-10-07 with version DOI
+[`10.5281/zenodo.23214487`](https://doi.org/10.5281/zenodo.23214487). Version
+0.2.9 was a development/source snapshot, not a PyPI package, GitHub Release,
+or version DOI. This roadmap is a product-level orientation; it is not a release gate,
tag, publication decision, or promise that an unqualified route is ready for
production.
@@ -21,8 +23,9 @@ Version 0.2.11 includes prospective V&V consolidation and experimental
gyroscopic modal/Campbell routes within a bounded BEAM2-and-disk scope.
Neither route is promoted beyond `EXPERIMENTAL`. The
[verification summary](../verification/0_2_11/README.md) records its evidence
-and limitations. Package publication is governed by separate exact-source
-release gates and is not inferred from this roadmap.
+and limitations. The selected 0.2.11 distribution has been published after
+exact-source release gates; this does not clear the whole-repository archive
+or broaden any technical claim.
Follow-up work will extend evidence and reproducibility without
generalizing the existing bounded nonlinear routes or changing the linear
diff --git a/docs/verification/0_2_11/README.md b/docs/verification/0_2_11/README.md
index dbf4422c..ddc3045c 100644
--- a/docs/verification/0_2_11/README.md
+++ b/docs/verification/0_2_11/README.md
@@ -11,9 +11,12 @@ approver: ""
# QF Solver 0.2.11 verification summary
This summary reports the recorded WP01–WP06 evidence for QF Solver 0.2.11.
-It does not turn a numerical result into an automatic maturity decision or
-confirm a package upload. The original source identities, measurements and
-decisions remain in their structured records.
+It does not turn a numerical result into an automatic maturity decision. The
+release was published on 2026-10-07 with version DOI
+[`10.5281/zenodo.23214487`](https://doi.org/10.5281/zenodo.23214487); the
+separate publication record verifies channel availability and exact selected
+artifact hashes. Original source identities, measurements and decisions remain
+in their structured records.
## Scope and provenance
@@ -69,11 +72,11 @@ outside scope.
## Gates and publication boundary
WP01–WP06 provide their recorded baseline, architecture, V&V, historical
-retest, gyro and Campbell evidence. The final QF0211-G07/G08 candidate gates
-and exact-source release audit are recorded separately during WP07. The
-published 0.2.10 tag and artifacts are not modified by this version or by
-edits to the current public documentation. Each release audit applies only
-to its recorded source and artifact bytes.
+retest, gyro and Campbell evidence. The final QF0211-G07/G08 gates and exact-
+source release audit are recorded separately under WP07. The published 0.2.10
+tag and artifacts are not modified by this version or by later edits to the
+current public documentation. Each release audit applies only to its recorded
+source and artifact bytes.
Historical 0.2.10 G03 remains `FAIL_PRESERVED`; the complete repository
archive is not cleared. Historical WP14 remains `HOLD_NOT_PROMOTED`. These
diff --git a/docs/verification/evidence-and-maturity.md b/docs/verification/evidence-and-maturity.md
index 53d4df32..3f57de7c 100644
--- a/docs/verification/evidence-and-maturity.md
+++ b/docs/verification/evidence-and-maturity.md
@@ -10,6 +10,8 @@ approver: ""
# Verification, validation, evidence and maturity
**Current release documentation:** QF Solver `0.2.11`
+**Current version DOI:** [`10.5281/zenodo.23214487`](https://doi.org/10.5281/zenodo.23214487)
+**Published:** 2026-10-07
**Previous version DOI (0.2.10 only):** [`10.5281/zenodo.23106744`](https://doi.org/10.5281/zenodo.23106744)
The cumulative solver retains the 0.2.10 development made since the published 0.2.8
@@ -21,14 +23,13 @@ current scopes. The 46-combination
is historical authority for those published element-analysis decisions and
is not silently rewritten here.
-QF Solver 0.2.11 adds experimental gyroscopic modal and Campbell
-evidence. Those results, their availability and their maturity decisions are
-summarized separately in the [0.2.11 V&V page](0_2_11/README.md);
-they are not part of the published 0.2.10 record.
-
-Publication availability is established by PyPI and GitHub Releases, not by
-this page. The 0.2.11 citation metadata does not assert a publication date or
-an assigned version DOI.
+QF Solver 0.2.11 adds experimental gyroscopic modal and Campbell evidence.
+Those results, their availability and their maturity decisions are summarized
+separately in the [0.2.11 V&V page](0_2_11/README.md); they do not rewrite the
+published 0.2.10 record. The selected 0.2.11 wheel and sdist are published on
+PyPI, with matching selected assets on GitHub Releases and Zenodo. The version
+DOI above identifies the Zenodo record; this page summarizes evidence but is
+not a substitute for its controlling records.
## Four distinct claims
diff --git a/docs/whats-new/0.2.11.md b/docs/whats-new/0.2.11.md
index 162c5f94..4f5c46db 100644
--- a/docs/whats-new/0.2.11.md
+++ b/docs/whats-new/0.2.11.md
@@ -12,8 +12,10 @@ approver: ""
This page summarizes changes from QF Solver 0.2.10 to 0.2.11. For the
cumulative solver capabilities, use the [capability index](../capabilities/index.md).
-Publication availability is authoritative on PyPI and GitHub Releases, not
-inferred from this documentation page.
+QF Solver 0.2.11 was published on 2026-10-07. Its exact-version DOI is
+[`10.5281/zenodo.23214487`](https://doi.org/10.5281/zenodo.23214487). The
+selected wheel, sdist and checksum manifest are the audited distribution
+artifacts; GitHub-generated source archives are not part of that selection.
## Overview
@@ -84,11 +86,12 @@ Version 0.2.11 keeps the existing `qf_solver` namespace and 0.2.x compatibility
surface. The new routes and their complex result contracts are experimental
and provisional, not stable downstream API commitments. See the
[installation guide](../getting-started/installation.md) for exact-version
-installation and availability checks. Use the concept DOI
-`10.5281/zenodo.22697897` for the evolving project; use a published version DOI
-for exact-release citation when one is assigned. The preceding version DOI
-`10.5281/zenodo.23106744` identifies 0.2.10 only. No publication date or
-0.2.11 version DOI is asserted here.
+installation. Cite this release with version DOI
+[`10.5281/zenodo.23214487`](https://doi.org/10.5281/zenodo.23214487), and use
+the concept DOI [`10.5281/zenodo.22697897`](https://doi.org/10.5281/zenodo.22697897)
+for the project across versions. The preceding version DOI
+[`10.5281/zenodo.23106744`](https://doi.org/10.5281/zenodo.23106744)
+identifies 0.2.10 only.
Historical G03 remains `FAIL_PRESERVED`, the whole-repository archive is not
cleared, and WP14 remains `HOLD_NOT_PROMOTED`.
diff --git a/qualification/0_2_11/publication_verification_0_2_11.json b/qualification/0_2_11/publication_verification_0_2_11.json
new file mode 100644
index 00000000..60ca4f6a
--- /dev/null
+++ b/qualification/0_2_11/publication_verification_0_2_11.json
@@ -0,0 +1,113 @@
+{
+ "schema_version": 1,
+ "record_id": "QF-0211-G09-PUBLICATION-VERIFICATION-2026-10-07",
+ "status": "PUBLICATION_VERIFIED",
+ "publication_phase": "POST_PUBLICATION",
+ "version": "0.2.11",
+ "tag": "v0.2.11",
+ "source_sha": "afd2efa469a18e66581720ff4801f50de7d29eb4",
+ "release_date": "2026-10-07",
+ "version_doi": "10.5281/zenodo.23214487",
+ "concept_doi": "10.5281/zenodo.22697897",
+ "tag_exists": true,
+ "main_contains_tag_target": true,
+ "tag_verification": {
+ "target_sha": "afd2efa469a18e66581720ff4801f50de7d29eb4",
+ "annotated": true,
+ "immutable_target_verified": true
+ },
+ "github_release": {
+ "published": true,
+ "release_id": 405822960,
+ "tag": "v0.2.11",
+ "url": "https://github.com/emptiesvoid-cloud/QF_solver/releases/tag/v0.2.11",
+ "selected_assets": [
+ {
+ "filename": "qf_solver-0.2.11-py3-none-any.whl",
+ "sha256": "bcf860f0a008f4a2c3c9efbe2301753a59c687ecc101d6f799dd52557d0fcba8"
+ },
+ {
+ "filename": "qf_solver-0.2.11.tar.gz",
+ "sha256": "bdf61fb59e5617778a2c539ab9729ab9b0912bc841ac9207d4cce1fba175824e"
+ },
+ {
+ "filename": "qf_solver-0.2.11-afd2efa4-SHA256SUMS.txt",
+ "sha256": "b461928d9443f5164c555ba6d520efe00ddeaea23b7d4af6215442f54b942364"
+ }
+ ],
+ "platform_generated_source_archives_are_selected_artifacts": false
+ },
+ "pypi": {
+ "published": true,
+ "version": "0.2.11",
+ "url": "https://pypi.org/project/qf-solver/0.2.11/",
+ "install_probe": "PASS",
+ "files": [
+ {
+ "filename": "qf_solver-0.2.11-py3-none-any.whl",
+ "sha256": "bcf860f0a008f4a2c3c9efbe2301753a59c687ecc101d6f799dd52557d0fcba8"
+ },
+ {
+ "filename": "qf_solver-0.2.11.tar.gz",
+ "sha256": "bdf61fb59e5617778a2c539ab9729ab9b0912bc841ac9207d4cce1fba175824e"
+ }
+ ],
+ "downloaded_public_bytes_hash_verified": true
+ },
+ "zenodo": {
+ "published": true,
+ "record_id": 23214487,
+ "url": "https://zenodo.org/records/23214487",
+ "doi_resolves": true,
+ "version_doi": "10.5281/zenodo.23214487",
+ "concept_doi": "10.5281/zenodo.22697897",
+ "release_date": "2026-10-07",
+ "version": "0.2.11",
+ "author": "Quentin Farinazzo",
+ "license": "Apache-2.0",
+ "whole_repository_archive_present": false,
+ "file_count": 3,
+ "files": [
+ {
+ "filename": "qf_solver-0.2.11-py3-none-any.whl",
+ "bytes": 1559189,
+ "sha256": "bcf860f0a008f4a2c3c9efbe2301753a59c687ecc101d6f799dd52557d0fcba8"
+ },
+ {
+ "filename": "qf_solver-0.2.11.tar.gz",
+ "bytes": 1177522,
+ "sha256": "bdf61fb59e5617778a2c539ab9729ab9b0912bc841ac9207d4cce1fba175824e"
+ },
+ {
+ "filename": "qf_solver-0.2.11-afd2efa4-SHA256SUMS.txt",
+ "bytes": 190,
+ "sha256": "b461928d9443f5164c555ba6d520efe00ddeaea23b7d4af6215442f54b942364"
+ }
+ ],
+ "public_file_bytes_downloaded_and_hash_verified": true
+ },
+ "qf0211_gates": {
+ "QF0211_G01": "INHERITED_PASS",
+ "QF0211_G02": "INHERITED_PASS",
+ "QF0211_G03": "INHERITED_PASS",
+ "QF0211_G04": "INHERITED_PASS",
+ "QF0211_G05": "INHERITED_PASS",
+ "QF0211_G06": "INHERITED_PASS",
+ "QF0211_G07": "PASS",
+ "QF0211_G08": "PASS",
+ "QF0211_G09": "PASS"
+ },
+ "maturities_and_limitations": {
+ "rotating_modal": "EXPERIMENTAL",
+ "campbell": "EXPERIMENTAL",
+ "campbell_100_rad_s_ambiguity": "PRESERVED",
+ "gyro_06_evidence": "INTERNAL_MESH_CONVERGENCE_ONLY"
+ },
+ "historical_statuses": {
+ "G03": "FAIL_PRESERVED",
+ "whole_repository_archive_cleared": false,
+ "WP14": "HOLD_NOT_PROMOTED"
+ },
+ "publication_scope": "SELECTED_DISTRIBUTION_ONLY",
+ "whole_repository_archive_cleared": false
+}
diff --git a/tests/documentation/test_docs_generation.py b/tests/documentation/test_docs_generation.py
index 4c7163bb..541258c7 100644
--- a/tests/documentation/test_docs_generation.py
+++ b/tests/documentation/test_docs_generation.py
@@ -89,6 +89,10 @@ def test_public_release_status_copy_distinguishes_release_and_tagged_source() ->
assert "0.2.8 is the current development candidate" not in roadmap
assert "10.5281/zenodo.23106744" in readme
assert "10.5281/zenodo.23106744" in index
+ assert "10.5281/zenodo.23214487" in readme
+ assert "10.5281/zenodo.23214487" in index
+ assert "2026-10-07" in readme
+ assert "2026-10-07" in index
assert "version DOI" in readme
assert "Current release" in normalized_index
assert "current documentation baseline is 0.2.11" in normalized_comparisons
@@ -99,8 +103,8 @@ def test_public_release_status_copy_distinguishes_release_and_tagged_source() ->
assert "not a current capability or maturity record" in normalized_comparison_snapshot
citation = (ROOT / "CITATION.cff").read_text(encoding="utf-8")
assert 'version: "0.2.11"' in citation
- assert not any(line.startswith("date-released:") for line in citation.splitlines())
- assert not any(line.startswith("doi:") for line in citation.splitlines())
+ assert 'date-released: "2026-10-07"' in citation
+ assert 'doi: "10.5281/zenodo.23214487"' in citation
@pytest.mark.parametrize(
diff --git a/tests/unit/test_gate_b_release_surface.py b/tests/unit/test_gate_b_release_surface.py
index d46e0476..6316699f 100644
--- a/tests/unit/test_gate_b_release_surface.py
+++ b/tests/unit/test_gate_b_release_surface.py
@@ -78,15 +78,16 @@ def test_version_registry_and_public_docs_are_aligned() -> None:
assert project["version"] == __version__ == "0.2.11"
assert project["optional-dependencies"]["hdf5"] == ["h5py>=3.10"]
- # The candidate citation identifies 0.2.11, but has no release-only date
- # or DOI until publication. The project concept DOI remains in project URLs.
+ # Citation metadata records the published version DOI; the package project
+ # URL continues to identify the concept DOI across releases.
citation = (ROOT / "CITATION.cff").read_text(encoding="utf-8")
assert 'version: "0.2.11"' in citation
- assert not any(line.startswith("date-released:") for line in citation.splitlines())
- assert not any(line.startswith("doi:") for line in citation.splitlines())
+ assert 'date-released: "2026-10-07"' in citation
+ assert 'doi: "10.5281/zenodo.23214487"' in citation
assert project["urls"]["DOI"] == "https://doi.org/10.5281/zenodo.22697897"
readme = (ROOT / "README.md").read_text(encoding="utf-8")
assert "The current QF Solver release is `0.2.11`" in readme
+ assert "10.5281/zenodo.23214487" in readme
assert "0.2.11 is a **candidate, not yet published**" not in readme
registry = json.loads((ROOT / "qualification/0_2_8/consolidated_registry.json").read_text(encoding="utf-8"))
assert registry["combination_registry"]["state_counts"] == {
diff --git a/tests/unit/test_pp05_release_metadata.py b/tests/unit/test_pp05_release_metadata.py
index 90d3de62..60a66615 100644
--- a/tests/unit/test_pp05_release_metadata.py
+++ b/tests/unit/test_pp05_release_metadata.py
@@ -48,26 +48,24 @@ def test_028_changelog_is_structured_released_and_bounded() -> None:
def test_security_policy_identifies_current_and_older_release_channels() -> None:
security = _text("SECURITY.md")
assert "Latest published release" in security
- assert "Current `0.2.10` release" in security
+ assert "Current `0.2.11` release" in security
assert "Older releases" in security
assert "0.2.7 = supported" not in security
assert "best-effort basis" in security
-def test_release_candidate_citation_has_no_unpublished_release_metadata() -> None:
+def test_published_release_citation_has_exact_release_metadata() -> None:
project = tomllib.loads(_text("pyproject.toml"))["project"]
runtime = _text("src/solveur/version.py")
citation = _text("CITATION.cff")
assert project["version"] == "0.2.11"
assert '__version__ = "0.2.11"' in runtime
- # The candidate is identified, but release-only metadata stays absent until
- # the version DOI and publication date actually exist.
assert 'title: "QF Solver"' in citation
assert 'version: "0.2.11"' in citation
+ assert 'date-released: "2026-10-07"' in citation
+ assert 'doi: "10.5281/zenodo.23214487"' in citation
assert 'license: "Apache-2.0"' in citation
assert 'repository-code: "https://github.com/emptiesvoid-cloud/QF_solver"' in citation
- assert not any(line.startswith("date-released:") for line in citation.splitlines())
- assert not any(line.startswith("doi:") for line in citation.splitlines())
assert "NOT_PUBLISHED_YET" not in citation
assert "NOT_AVAILABLE_YET" not in citation
@@ -114,5 +112,6 @@ def test_release_registry_and_public_boundaries_remain_unchanged() -> None:
}
assert "no general HPC or nonlinear distributed claim" in _text("README.md")
assert "`NOT_VALIDATED`" in _text("README.md")
- assert "0.2.10" in _text("CONTRIBUTING.md")
+ assert "QF Solver `0.2.11` (`v0.2.11`) is the current published release" in _text("CONTRIBUTING.md")
+ assert "10.5281/zenodo.23214487" in _text("SECURITY.md")
assert "haven't had the time to put everything on GitHub" not in _text("CONTRIBUTING.md")
diff --git a/tests/unit/test_publication_metadata_gate.py b/tests/unit/test_publication_metadata_gate.py
index f92bec64..8c27591c 100644
--- a/tests/unit/test_publication_metadata_gate.py
+++ b/tests/unit/test_publication_metadata_gate.py
@@ -13,8 +13,10 @@
ROOT = Path(__file__).resolve().parents[2]
VERSION = "0.2.11"
TAG = "v0.2.11"
-VERSION_DOI = "10.5281/zenodo.99999999"
+VERSION_DOI = "10.5281/zenodo.23214487"
RELEASE_DATE = "2026-10-07"
+PUBLICATION_RECORD = ROOT / "qualification/0_2_11/publication_verification_0_2_11.json"
+RELEASE_CONTRACT = ROOT / "qualification/0_2_11/authorized_selected_package_release_contract_afd2efa.json"
def _write_release_copy(root: Path, phase: str, *, doi: str | None = None, released: bool = False) -> None:
@@ -169,8 +171,16 @@ def _write_postpublication_evidence(root: Path, *, doi: str = VERSION_DOI) -> tu
return contract_path, record_path
-def test_candidate_prepublication_metadata_is_valid_without_a_version_doi() -> None:
- failures = check_publication_metadata(ROOT, TAG, "PRE_PUBLICATION")
+def test_current_postpublication_metadata_matches_public_evidence() -> None:
+ failures = check_publication_metadata(
+ ROOT,
+ TAG,
+ "POST_PUBLICATION",
+ version_doi=VERSION_DOI,
+ release_date=RELEASE_DATE,
+ publication_record=PUBLICATION_RECORD,
+ release_contract=RELEASE_CONTRACT,
+ )
assert failures == []