From e2cde2109e41ef19b1dde47d1d5445cf7982ad15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis-F=C3=A9lix=20Nothias?= Date: Fri, 10 Jul 2026 10:53:03 +0200 Subject: [PATCH 1/9] fix(ci): admit repository-OA tiers in the paper access gate --- .github/workflows/verify-paper.yml | 10 +++++ tests/test_oa_tier_parity.py | 64 ++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 tests/test_oa_tier_parity.py diff --git a/.github/workflows/verify-paper.yml b/.github/workflows/verify-paper.yml index 11a51f66c..b32822864 100644 --- a/.github/workflows/verify-paper.yml +++ b/.github/workflows/verify-paper.yml @@ -76,6 +76,16 @@ jobs: "diamond", } + # Repository-OA tier (OPEN_ACCESS_POLICY.md): a tool admitted on its + # repository's open licence rather than a paper's. Must stay in sync with + # scripts/release_gate.py:_REPO_OA_TIERS, which is the release authority. + REPO_OA_TYPES = { + "repo-oa", + "repo-permissive", + "repo-copyleft", + } + OPEN_ACCESS_TYPES |= REPO_OA_TYPES + def normalize_access_type(raw: str) -> str: """Normalize an access.type token to a canonical OA tier. diff --git a/tests/test_oa_tier_parity.py b/tests/test_oa_tier_parity.py new file mode 100644 index 000000000..dd1603858 --- /dev/null +++ b/tests/test_oa_tier_parity.py @@ -0,0 +1,64 @@ +"""The two open-access gates must admit the same tiers. + +`scripts/release_gate.py` is the release authority; `.github/workflows/verify-paper.yml` +gates pushes and PRs. When they disagree, one of them silently rejects (or admits) a +whole tier -- which is how every `repo-oa` paper came to fail CI on main while the +release gate passed them. +""" + +import ast +import pathlib +import re +import sys + +import yaml + +sys.path.insert(0, str(pathlib.Path(__file__).parent.parent)) +from scripts import release_gate + +REPO_ROOT = pathlib.Path(__file__).parent.parent +VERIFY_PAPER_WORKFLOW = REPO_ROOT / ".github" / "workflows" / "verify-paper.yml" + + +def _inline_gate_source() -> str: + """Return the python heredoc embedded in the verify-paper access-tier step.""" + workflow = yaml.safe_load(VERIFY_PAPER_WORKFLOW.read_text()) + for job in workflow["jobs"].values(): + for step in job.get("steps", []): + run = step.get("run") or "" + if "OPEN_ACCESS_TYPES" in run: + match = re.search(r"<<'([A-Z]+)'\n(.*?)\n\s*\1\s*$", run, re.S | re.M) + if match: + return match.group(2) + raise AssertionError("no verify-paper step defines OPEN_ACCESS_TYPES") + + +def _workflow_open_access_types() -> set[str]: + """Evaluate the workflow's OPEN_ACCESS_TYPES without executing the whole gate.""" + namespace: dict[str, object] = {} + for node in ast.parse(_inline_gate_source()).body: + if isinstance(node, (ast.Assign, ast.AugAssign)): + target = node.targets[0] if isinstance(node, ast.Assign) else node.target + if isinstance(target, ast.Name) and target.id in { + "OPEN_ACCESS_TYPES", + "REPO_OA_TYPES", + }: + exec(compile(ast.Module([node], []), "", "exec"), namespace) + return set(namespace["OPEN_ACCESS_TYPES"]) + + +def test_workflow_admits_every_repo_oa_tier(): + assert release_gate._REPO_OA_TIERS <= _workflow_open_access_types() + + +def test_workflow_admits_every_release_gate_tier(): + normalized = { + release_gate._normalize_access_type(t) for t in _workflow_open_access_types() + } + assert release_gate._NORMALIZED_OA_TIERS <= normalized + + +if __name__ == "__main__": + test_workflow_admits_every_repo_oa_tier() + test_workflow_admits_every_release_gate_tier() + print(f"PASS: gates agree on {len(_workflow_open_access_types())} access tiers") From a8ecf85509d4d7e34ed31607e9423088fcadc1fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis-F=C3=A9lix=20Nothias?= Date: Fri, 10 Jul 2026 10:53:03 +0200 Subject: [PATCH 2/9] fix(skills): start asb-metabolomics description with an approved prefix --- collections/metabolomics/v2/skills/asb-metabolomics/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collections/metabolomics/v2/skills/asb-metabolomics/SKILL.md b/collections/metabolomics/v2/skills/asb-metabolomics/SKILL.md index 3a7f94bf6..0b86dfb75 100644 --- a/collections/metabolomics/v2/skills/asb-metabolomics/SKILL.md +++ b/collections/metabolomics/v2/skills/asb-metabolomics/SKILL.md @@ -1,6 +1,6 @@ --- name: asb-metabolomics -description: "Use FIRST when working with the ASB Metabolomics skill collection. The meta-skill: it explains good practice (search -> apply -> ground), enforces the license-tier acknowledgment for non-open tools, then hands off to the _router skill for actual skill selection." +description: "Use when starting any task with the ASB Metabolomics skill collection — read this meta-skill first. It explains good practice (search -> apply -> ground), enforces the license-tier acknowledgment for non-open tools, then hands off to the _router skill for actual skill selection." license: CC-BY-4.0 metadata: role: meta From 5d7eeadc4afa0cf363ffce9b7095d7859e0f1ab2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis-F=C3=A9lix=20Nothias?= Date: Fri, 10 Jul 2026 10:55:00 +0200 Subject: [PATCH 3/9] chore(license): verify wave status and record the resolved licences --- .../license_clarification/deployments.yaml | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/governance/license_clarification/deployments.yaml b/governance/license_clarification/deployments.yaml index 77539a166..8faaaec78 100644 --- a/governance/license_clarification/deployments.yaml +++ b/governance/license_clarification/deployments.yaml @@ -9,7 +9,7 @@ deployments: wave: trial-2026-06-24 status: open license_after: null - last_checked: '2026-06-24' + last_checked: '2026-07-10' - repo: matteogiulietti/LipidOne tool_names: - LipidOne 2.0 @@ -17,9 +17,12 @@ deployments: issue_url: https://github.com/matteogiulietti/LipidOne/issues/1 filed_on: '2026-06-24' wave: trial-2026-06-24 - status: open - license_after: null - last_checked: '2026-06-24' + status: closed + license_after: BSD-2-Clause + last_checked: '2026-07-10' + note: Already licensed when we filed. The two-clause FreeBSD text is embedded in + the README rather than a LICENSE file, so GitHub does not surface it and our LICENSE-file-only + scan missed it. Issue closed with an apology. Do not re-file. - repo: Ansanqi/GutUDB tool_names: - GutUDB @@ -29,7 +32,7 @@ deployments: wave: trial-2026-06-24 status: open license_after: null - last_checked: '2026-06-24' + last_checked: '2026-07-10' - repo: MassBank/MassBank-data tool_names: - MassBank @@ -37,9 +40,13 @@ deployments: issue_url: https://github.com/MassBank/MassBank-data/issues/394 filed_on: '2026-06-24' wave: trial-2026-06-24 - status: open + status: closed license_after: null - last_checked: '2026-06-24' + last_checked: '2026-07-10' + note: 'Answered by the maintainer: GPL-3 covers the MassBank software, but this + repository is a data collection whose records carry per-record licences (CC0 or + another Creative Commons variant). No single SPDX id applies, so license_after + stays null deliberately. Do not re-file.' - repo: mariallr/easy-amanida tool_names: - Easy-Amanida @@ -47,6 +54,6 @@ deployments: issue_url: https://github.com/mariallr/easy-amanida/issues/2 filed_on: '2026-06-24' wave: trial-2026-06-24 - status: open + status: responded license_after: null - last_checked: '2026-06-24' + last_checked: '2026-07-10' From a4d3e9676b1d87ef59430b8949da5a915aa35181 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis-F=C3=A9lix=20Nothias?= Date: Fri, 10 Jul 2026 10:55:00 +0200 Subject: [PATCH 4/9] docs(license): warn that licences hide outside LICENSE files --- governance/license_clarification/README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/governance/license_clarification/README.md b/governance/license_clarification/README.md index 725470d00..275a12521 100644 --- a/governance/license_clarification/README.md +++ b/governance/license_clarification/README.md @@ -81,8 +81,26 @@ deployments: status: open # open | responded | license-added | closed | wontfix license_after: null # SPDX id if the repo later adds a license last_checked: null # ISO date of last verify run + note: ... # optional prose; why an entry is settled. Preserved by verify. ``` +### Before filing a wave: check for licences outside `LICENSE` + +`verify` (and the original wave scan) resolve a licence through GitHub's SPDX +detection, which **only reads a `LICENSE`/`COPYING` file**. A project can be +properly licensed without one: + +| Where the licence hides | Real example | +|---|---| +| Full licence text pasted into the `README` | `matteogiulietti/LipidOne` — BSD-2-Clause | +| `License:` field of an R package `DESCRIPTION` | `mariallr/amanida` — GPL-3 | +| `LICENSE.txt` (detected by GitHub, but not by a bare `LICENSE` glob) | `workflow4metabolomics/tools-metabolomics` — GPL-3 | + +Filing against such a repo asks an author for something they already published. +This happened once (LipidOne, issue closed with an apology). Run +`scripts/readme_license_precheck.py` **before** `--create`, and treat a null +`licenseInfo` as *unknown*, never as *unlicensed*. + ### Append-on-create When `--create` is used, the script automatically appends one record per newly From 3445d3a7026b71b4fbaca53dc82b4e1cb6a8d592 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis-F=C3=A9lix=20Nothias?= Date: Fri, 10 Jul 2026 10:56:42 +0200 Subject: [PATCH 5/9] feat(proposals): stage OmniPath and Workflow4Metabolomics from issues #15 and #16 --- .../proposals/wave-2026-06-community.yaml | 78 ++++++++++++++++++- 1 file changed, 74 insertions(+), 4 deletions(-) diff --git a/collections/metabolomics/proposals/wave-2026-06-community.yaml b/collections/metabolomics/proposals/wave-2026-06-community.yaml index d8c627ae6..301dee13a 100644 --- a/collections/metabolomics/proposals/wave-2026-06-community.yaml +++ b/collections/metabolomics/proposals/wave-2026-06-community.yaml @@ -13,13 +13,13 @@ schema: asb-corpus/1.0 collection: metabolomics version: 2 generated_on: '2026-06-23' -source: community proposals (GitHub issues #11–#14), curator-normalized +source: community proposals (GitHub issues #11–#16), curator-normalized policy: OPEN_ACCESS_POLICY.md (OA verified per entry; unresolved tiers flagged in triage) wave: community-2026-06 summary: - total: 4 + total: 6 included: 0 - hold: 4 + hold: 6 papers: - name: RforMassSpectrometry @@ -32,7 +32,7 @@ papers: license_tier: open wave: community-2026-06 resource_type: software-ecosystem - source_issue: 14 # filed alongside #13 + source_issue: 13 # co-staged with #14 (Metabonaut), same authors access: type: gold-oa license: cc-by-4.0 @@ -147,3 +147,73 @@ papers: prose-only SKILL.md with link-only grounding and a runtime use-acknowledgment gate; do NOT embed the repo. access.type stays "restricted" (OA axis unchanged) — the license_tier is what makes it includable. Still status: hold pending merge. + +- name: OmniPath Metabo + doi: 10.64898/2026.06.18.733117 + title: 'OmniPath Metabo: chemical structures, interactions and mechanisms to study the metabolome' + year: 2026 + category: Databases + repo_url: https://github.com/saezlab/omnipath-metabo + status: hold + license_tier: open + wave: community-2026-06 + resource_type: database-knowledge-base + source_issue: 15 + access: + type: open-access + license: cc-by-4.0 + is_oa: true + provenance: preprint # bioRxiv; update to the canonical DOI once peer-reviewed + verified_via: biorxiv_api_license # api.biorxiv.org reported license=cc_by + verified_on: '2026-07-10' + code_license: BSD-3-Clause # saezlab/omnipath-metabo LICENSE + triage: + proposer: lfnothias + rationale: >- + A metabolome-oriented extension of the OmniPath knowledge base (Saez-Rodriguez + lab) linking chemical structures to interactions and mechanisms. Useful for + grounding agent tasks that connect annotated metabolites to biological context. + decision: accept + notes: >- + The preprint's licence was read from the bioRxiv API (cc_by), NOT inferred from + OPEN_ACCESS_POLICY.md's blanket "preprints are always CC-BY" rule — bioRxiv lets + authors choose CC-BY-NC-ND or no-reuse, so that rule can admit non-reusable text. + Repository is BSD-3-Clause. Re-point the entry at the peer-reviewed DOI on + publication, keeping this preprint as source_history. + +- name: Workflow4Metabolomics + doi: 10.1093/bioinformatics/btu813 + title: 'Workflow4Metabolomics: a collaborative research infrastructure for computational metabolomics' + year: 2015 + category: Multifunctional + repo_url: https://github.com/workflow4metabolomics/tools-metabolomics + status: hold + license_tier: open + wave: community-2026-06 + resource_type: workflow-platform + source_issue: 16 + links: + - https://workflow4metabolomics.usegalaxy.fr/ + - https://doi.org/10.1002/cpz1.70095 # Delport 2025 protocol; green OA, NOT reusable + access: + type: open-access + license: cc-by + is_oa: true + oa_status: hybrid + verified_via: unpaywall_best_oa_location # publisher-hosted cc-by + verified_on: '2026-07-10' + code_license: GPL-3.0-only # tools-metabolomics LICENSE.txt + triage: + proposer: yguitton # first external community proposal + rationale: >- + The Galaxy Workflow4Metabolomics suite is a long-standing, widely adopted public + infrastructure for reproducible LC-MS/GC-MS/NMR metabolomics. It covers the + preprocessing-to-statistics span with tools our corpus otherwise reaches only + through individual R/Python packages. + decision: accept + notes: >- + Anchored on Giacomoni 2015 (Bioinformatics), verified CC-BY at the publisher. + The Delport 2025 Current Protocols paper is green OA with no reuse licence, so it + is linked for context only and must NOT be used as the grounding source. The + repository is GPL-3, which clears the repository-OA tier independently. + Proposed by an external contributor — credit yguitton on promotion. From c58d4b9f65a72b35b31541aacacd025f17d5592b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis-F=C3=A9lix=20Nothias?= Date: Fri, 10 Jul 2026 11:14:44 +0200 Subject: [PATCH 6/9] test(ci): assert the two open-access gates admit exactly the same tiers --- .github/workflows/verify-paper.yml | 9 +++-- governance/CONTENT_POLICY.md | 2 +- tests/test_oa_tier_parity.py | 63 ++++++++++++++++++++++++------ 3 files changed, 57 insertions(+), 17 deletions(-) diff --git a/.github/workflows/verify-paper.yml b/.github/workflows/verify-paper.yml index b32822864..9e7588f9d 100644 --- a/.github/workflows/verify-paper.yml +++ b/.github/workflows/verify-paper.yml @@ -76,9 +76,12 @@ jobs: "diamond", } - # Repository-OA tier (OPEN_ACCESS_POLICY.md): a tool admitted on its - # repository's open licence rather than a paper's. Must stay in sync with - # scripts/release_gate.py:_REPO_OA_TIERS, which is the release authority. + # Repository-OA tier (CONTENT_POLICY.md §3, "software / dataset / tutorial + # DOIs"): a public git repository cloned at build qualifies as `repo-oa`. + # This is the paper-ACCESS axis only; what a consumer may do with the tool is + # the separate `license_tier` axis. Must stay in sync with + # scripts/release_gate.py:_REPO_OA_TIERS -- tests/test_oa_tier_parity.py + # fails if the two ever drift apart. REPO_OA_TYPES = { "repo-oa", "repo-permissive", diff --git a/governance/CONTENT_POLICY.md b/governance/CONTENT_POLICY.md index c7a9768bd..cba1032f4 100644 --- a/governance/CONTENT_POLICY.md +++ b/governance/CONTENT_POLICY.md @@ -86,7 +86,7 @@ Papers with the following status are **rejected at curation**: 1. **Automated check:** OpenAlex API lookup; flag `is_oa: true|false` 2. **Manual spot-check:** Sample papers in the final corpus (≥10% per domain) to confirm OA license accuracy -3. **Red-flag gate:** CI verify-paper.yml (stage §7.5) enforces `access.type ∈ {open-access, open_access, oa, gold-oa, gold_oa, green-oa, green, diamond}` (after hyphen/underscore + `green`→`green-oa` normalization) for all `status:included` papers; unknown/non-OA triggers a hard fail. `preprint` is rejected as an `access.type` value because it is a provenance value, not an OA tier. +3. **Red-flag gate:** CI verify-paper.yml (stage §7.5) enforces `access.type ∈ {open-access, open_access, oa, gold-oa, gold_oa, green-oa, green, diamond} ∪ {repo-oa, repo-permissive, repo-copyleft}` (after hyphen/underscore + `green`→`green-oa` normalization) for all `status:included` papers; unknown/non-OA triggers a hard fail. `preprint` is rejected as an `access.type` value because it is a provenance value, not an OA tier. The three `repo-*` values are the repository-access tiers from the software/dataset note above; `tests/test_oa_tier_parity.py` keeps this set identical to `scripts/release_gate.py:_REPO_OA_TIERS`, so the push gate and the release gate cannot drift apart. ### Exception Procedure (Post-v0) diff --git a/tests/test_oa_tier_parity.py b/tests/test_oa_tier_parity.py index dd1603858..75439d83d 100644 --- a/tests/test_oa_tier_parity.py +++ b/tests/test_oa_tier_parity.py @@ -1,9 +1,13 @@ -"""The two open-access gates must admit the same tiers. +"""The two open-access gates must admit exactly the same tiers. `scripts/release_gate.py` is the release authority; `.github/workflows/verify-paper.yml` gates pushes and PRs. When they disagree, one of them silently rejects (or admits) a whole tier -- which is how every `repo-oa` paper came to fail CI on main while the release gate passed them. + +Both directions matter. Missing a tier the release gate admits turns CI red on valid +content; admitting a tier the release gate rejects lets non-open content reach the +public branch, and only fails later at release time. """ import ast @@ -18,6 +22,7 @@ REPO_ROOT = pathlib.Path(__file__).parent.parent VERIFY_PAPER_WORKFLOW = REPO_ROOT / ".github" / "workflows" / "verify-paper.yml" +TIER_NAMES = {"OPEN_ACCESS_TYPES", "REPO_OA_TYPES"} def _inline_gate_source() -> str: @@ -33,32 +38,64 @@ def _inline_gate_source() -> str: raise AssertionError("no verify-paper step defines OPEN_ACCESS_TYPES") +def _assignments_to(tree: ast.Module, name: str) -> list[ast.stmt]: + """Every Assign/AugAssign binding `name`, at any nesting depth.""" + found = [] + for node in ast.walk(tree): + if isinstance(node, ast.Assign): + targets = node.targets + elif isinstance(node, ast.AugAssign): + targets = [node.target] + else: + continue + if any(isinstance(t, ast.Name) and t.id == name for t in targets): + found.append(node) + return found + + def _workflow_open_access_types() -> set[str]: """Evaluate the workflow's OPEN_ACCESS_TYPES without executing the whole gate.""" + tree = ast.parse(_inline_gate_source()) namespace: dict[str, object] = {} - for node in ast.parse(_inline_gate_source()).body: - if isinstance(node, (ast.Assign, ast.AugAssign)): - target = node.targets[0] if isinstance(node, ast.Assign) else node.target - if isinstance(target, ast.Name) and target.id in { - "OPEN_ACCESS_TYPES", - "REPO_OA_TYPES", - }: - exec(compile(ast.Module([node], []), "", "exec"), namespace) + for node in tree.body: + is_binding = isinstance(node, (ast.Assign, ast.AugAssign)) + if is_binding and _binds_a_tier_name(node): + exec(compile(ast.Module([node], []), "", "exec"), namespace) return set(namespace["OPEN_ACCESS_TYPES"]) +def _binds_a_tier_name(node: ast.stmt) -> bool: + targets = node.targets if isinstance(node, ast.Assign) else [node.target] + return any(isinstance(t, ast.Name) and t.id in TIER_NAMES for t in targets) + + +def _normalized_workflow_tiers() -> set[str]: + return {release_gate._normalize_access_type(t) for t in _workflow_open_access_types()} + + +def test_tier_sets_are_bound_only_at_module_level(): + """A nested rebind would diverge from what this test statically evaluates.""" + tree = ast.parse(_inline_gate_source()) + for name in TIER_NAMES: + for node in _assignments_to(tree, name): + assert node in tree.body, f"{name} rebound outside module level; parity test would go stale" + + def test_workflow_admits_every_repo_oa_tier(): assert release_gate._REPO_OA_TIERS <= _workflow_open_access_types() def test_workflow_admits_every_release_gate_tier(): - normalized = { - release_gate._normalize_access_type(t) for t in _workflow_open_access_types() - } - assert release_gate._NORMALIZED_OA_TIERS <= normalized + assert release_gate._NORMALIZED_OA_TIERS <= _normalized_workflow_tiers() + + +def test_workflow_admits_nothing_the_release_gate_rejects(): + assert _normalized_workflow_tiers() <= release_gate._NORMALIZED_OA_TIERS if __name__ == "__main__": + test_tier_sets_are_bound_only_at_module_level() test_workflow_admits_every_repo_oa_tier() test_workflow_admits_every_release_gate_tier() + test_workflow_admits_nothing_the_release_gate_rejects() print(f"PASS: gates agree on {len(_workflow_open_access_types())} access tiers") From 7dc4a142f0185385c98b32d6f107fd895efd3ae0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis-F=C3=A9lix=20Nothias?= Date: Fri, 10 Jul 2026 11:14:44 +0200 Subject: [PATCH 7/9] fix(governance): require per-preprint licence verification instead of assuming CC-BY --- governance/OPEN_ACCESS_POLICY.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/governance/OPEN_ACCESS_POLICY.md b/governance/OPEN_ACCESS_POLICY.md index ec1304478..a2706b9c2 100644 --- a/governance/OPEN_ACCESS_POLICY.md +++ b/governance/OPEN_ACCESS_POLICY.md @@ -146,7 +146,19 @@ The static page at /` → `license` (`cc_by`, `cc_by_nc_nd`, `cc_no`, …) | `verified_via: biorxiv_api_license` | +| arXiv | Atom API entry → `` | `verified_via: arxiv_api_license` | +| ChemRxiv | item metadata → `license` | `verified_via: chemrxiv_api_license` | + +Only a licence permitting the intended reuse admits the pre-print at an open `access.type`. A non-reuse licence makes the entry link-only, exactly as for a closed paper. Note that bioRxiv/medRxiv DOIs now carry the **openRxiv prefix `10.64898`** alongside the legacy Cold Spring Harbor prefix `10.1101`; both are genuine. + +Per [`CONTENT_POLICY.md`](CONTENT_POLICY.md) §3, `preprint` is a **provenance** value and must never be used as an `access.type`. When the peer-reviewed version is later published with a different DOI, the corpus entry is updated to point at the canonical DOI (linking back to the pre-print as `source_history`). ### Books and book chapters From f136f41994c22bcd7697dfc7b2ce8b6dcadc88ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis-F=C3=A9lix=20Nothias?= Date: Fri, 10 Jul 2026 11:14:44 +0200 Subject: [PATCH 8/9] docs(proposals): note that 10.64898 is the openRxiv preprint prefix --- collections/metabolomics/proposals/wave-2026-06-community.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/collections/metabolomics/proposals/wave-2026-06-community.yaml b/collections/metabolomics/proposals/wave-2026-06-community.yaml index 301dee13a..dd63fac44 100644 --- a/collections/metabolomics/proposals/wave-2026-06-community.yaml +++ b/collections/metabolomics/proposals/wave-2026-06-community.yaml @@ -149,6 +149,8 @@ papers: the license_tier is what makes it includable. Still status: hold pending merge. - name: OmniPath Metabo + # DOI prefix 10.64898 is openRxiv (bioRxiv/medRxiv's registrant since the Cold Spring + # Harbor handover). It is NOT a typo for the legacy 10.1101 prefix. Do not "correct" it. doi: 10.64898/2026.06.18.733117 title: 'OmniPath Metabo: chemical structures, interactions and mechanisms to study the metabolome' year: 2026 From 53bf97cba99851d8ccf42b7161beb1c4e89e0d66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis-F=C3=A9lix=20Nothias?= Date: Fri, 10 Jul 2026 11:21:21 +0200 Subject: [PATCH 9/9] fix(ci): run the test suite on every PR and re-run the paper gate when it changes --- .github/workflows/validate.yml | 9 ++++++++- .github/workflows/verify-paper.yml | 4 ++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 43cb3616d..b36eb824c 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -37,12 +37,19 @@ jobs: - name: Install dependencies run: | pip install --upgrade pip - pip install pyyaml jsonschema requests + pip install pyyaml jsonschema requests pytest pip install linkml linkml-runtime || echo "WARNING: linkml install failed" pip install rocrate || echo "WARNING: rocrate install failed" # indicium-adapters provides the verify-claims console script (Plan 1c) pip install indicium-adapters || echo "WARNING: indicium-adapters not yet available; gate 9 will warn-only" + # -- Gate 0: Unit tests ------------------------------------------------- + # Until now the suite ran only inside release.yml, so a test could sit broken + # on main for weeks and nothing would say so. The suite is hermetic (pyyaml + # + pytest, no network). + - name: Run test suite + run: python -m pytest tests/ -q + # -- Gate 10: Plugin manifest validates -------------------------------- - name: Validate .claude-plugin/marketplace.json run: | diff --git a/.github/workflows/verify-paper.yml b/.github/workflows/verify-paper.yml index 9e7588f9d..0cc49c239 100644 --- a/.github/workflows/verify-paper.yml +++ b/.github/workflows/verify-paper.yml @@ -18,6 +18,9 @@ on: - 'collections/**/v*/collection.yaml' - 'staged-collections/**/corpus.yaml' - 'staged-collections/**/v*/collection.yaml' + # Editing the gate must re-run the gate, or a change to the admitted tier set + # ships without ever being exercised. + - '.github/workflows/verify-paper.yml' push: branches: [main] paths: @@ -25,6 +28,7 @@ on: - 'collections/**/v*/collection.yaml' - 'staged-collections/**/corpus.yaml' - 'staged-collections/**/v*/collection.yaml' + - '.github/workflows/verify-paper.yml' permissions: contents: read