descriptor: reject empty enums #1331
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| # Run required checks on merge queue groups so queued PRs can land. | |
| merge_group: | |
| permissions: | |
| contents: read | |
| env: | |
| CARGO_TERM_COLOR: always | |
| # protoc v27+ is required for editions 2023 support (utf8_validation.proto). | |
| # Ubuntu's apt protobuf-compiler is v21.12 — too old. Keep this in sync | |
| # with the conformance tools image (see conformance/Dockerfile.tools). | |
| PROTOC_VERSION: "33.5" | |
| # SHA256 of protoc-${PROTOC_VERSION}-linux-x86_64.zip from the upstream | |
| # protobuf release. Bump together with PROTOC_VERSION. | |
| PROTOC_SHA256: "24e58fb231d50306ee28491f33a170301e99540f7e29ca461e0e80fd1239f8d1" | |
| jobs: | |
| # ── Fast feedback: lint + test on stable ───────────────────────────────── | |
| lint-and-test: | |
| runs-on: ubuntu-latest | |
| # 15 rather than 10: documenting the workspace (buffa-test's generated | |
| # modules are large) adds a few minutes on top of a cold-cache build. | |
| timeout-minutes: 15 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| # Pinned (not @stable) so rustfmt/clippy match rust-toolchain.toml and | |
| # local runs agree with CI. Bump together with that file. | |
| # | |
| # NOTE: the action only runs `rustup default`, which rust-toolchain.toml | |
| # overrides — so the file is what actually selects the toolchain for | |
| # cargo. The pin here must NAME THE SAME VERSION as the file so the | |
| # components installed by this step belong to the toolchain cargo uses. | |
| - uses: dtolnay/rust-toolchain@1.95 | |
| with: | |
| components: clippy, rustfmt | |
| - name: Install protoc | |
| run: | | |
| curl -fsSL "https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC_VERSION}/protoc-${PROTOC_VERSION}-linux-x86_64.zip" -o /tmp/protoc.zip | |
| echo "${PROTOC_SHA256} /tmp/protoc.zip" | sha256sum -c - | |
| sudo unzip -o /tmp/protoc.zip -d /usr/local | |
| protoc --version | |
| - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 (sha-pinned) | |
| - name: Rustfmt | |
| run: cargo fmt --all --check | |
| - name: Clippy | |
| run: cargo clippy --workspace --all-targets -- -D warnings | |
| - name: Tests | |
| run: cargo test --workspace | |
| # Optional features must keep compiling — #88 was a feature-flag-only | |
| # break that escaped the default-features test pass above. cargo check | |
| # is sufficient to catch compile breaks without doubling the test time. | |
| - name: Check all features | |
| run: cargo check --workspace --all-features | |
| # Rustdoc warnings are errors, in generated docs too: buffa-test's | |
| # build include!s codegen output (views, lazy views, json, reflect), so | |
| # documenting the workspace lints emitted doc comments as well as | |
| # hand-written ones. Covers workspace members only — excluded crates | |
| # (benchmarks/, most examples/) are not documented. (#295) | |
| - name: Rustdoc (deny warnings) | |
| run: cargo doc --workspace --all-features --no-deps | |
| env: | |
| RUSTDOCFLAGS: -D warnings | |
| # `gate_impls_on_crate_features` codegen output: generate the buffa-test | |
| # fixture protos with the gate on, then `cargo check` the result with | |
| # each `{json, views, text}` subset. Catches name-resolution bugs the | |
| # string-match tests cannot — a `cfg`-gated item referenced from an | |
| # ungated context survives `syn::parse_file` but fails this. Marked | |
| # `--ignored` so the default workspace test stays fast. (#113) | |
| - name: Feature-gating compile matrix | |
| run: cargo test -p buffa-codegen --test feature_gating_compile -- --ignored | |
| # Shared-pool mode emits each package's descriptor_pool() as a relative | |
| # `super::…::__buffa_fds` path, so the hop count has to match the module | |
| # nesting exactly. Only a real compiled tree proves it resolves; the | |
| # string-level tests check the arithmetic against itself. Also `#[ignore]`d | |
| # because it spawns cargo. (#311) | |
| - name: Shared descriptor pool compile | |
| run: cargo test -p buffa-codegen --test shared_pool_compile -- --ignored | |
| # ── Markdown lint ──────────────────────────────────────────────────────── | |
| # Same pinned markdownlint-cli version as `task lint-md`. Node is | |
| # preinstalled on ubuntu-latest so no setup-node step is needed. | |
| lint-markdown: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - run: npx --yes markdownlint-cli@0.47.0 '**/*.md' --ignore target --ignore .claude | |
| # ── Workflow lint ──────────────────────────────────────────────────────── | |
| # A malformed workflow does not fail a normal CI job — GitHub records a | |
| # startup failure on the run instead, which is easy to miss and only surfaces | |
| # when the workflow was meant to do something. A duplicate `env:` key reached | |
| # main in publish-crates.yml exactly that way: PyYAML's default loader accepts | |
| # duplicate keys and keeps the last one, so it validated locally while the | |
| # publish workflow silently could not start. actionlint parses the way Actions | |
| # does and rejects it. | |
| lint-workflows: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install actionlint | |
| env: | |
| ACTIONLINT_VERSION: 1.7.7 | |
| # SHA256 of actionlint_${ACTIONLINT_VERSION}_linux_amd64.tar.gz from | |
| # the upstream release's checksums.txt. Bump together with the | |
| # version. | |
| ACTIONLINT_SHA256: 023070a287cd8cccd71515fedc843f1985bf96c436b7effaecce67290e7e0757 | |
| run: | | |
| curl -fsSL -o /tmp/actionlint.tar.gz \ | |
| "https://github.com/rhysd/actionlint/releases/download/v${ACTIONLINT_VERSION}/actionlint_${ACTIONLINT_VERSION}_linux_amd64.tar.gz" | |
| echo "${ACTIONLINT_SHA256} /tmp/actionlint.tar.gz" | sha256sum -c - | |
| mkdir -p "${RUNNER_TEMP}/bin" | |
| tar -xzf /tmp/actionlint.tar.gz -C "${RUNNER_TEMP}/bin" actionlint | |
| echo "${RUNNER_TEMP}/bin" >> "${GITHUB_PATH}" | |
| "${RUNNER_TEMP}/bin/actionlint" --version | |
| - name: Lint workflows | |
| run: actionlint -color | |
| # ── Publish list ───────────────────────────────────────────────────────── | |
| # Adding a publishable crate to the workspace without adding it to | |
| # .github/publish-order.txt means the release silently skips it. That is how | |
| # buffa-remote-derive was announced in the 0.9.0 changelog and never reached | |
| # crates.io. The publish workflow checks this too, but only on a v* tag — | |
| # running it here fails the PR that introduces the crate instead. | |
| check-publish-list: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@stable | |
| # cargo metadata only reads manifests, so the pinned dev toolchain is not | |
| # needed; stable avoids downloading it just for this check. | |
| - name: Check publish coverage | |
| env: | |
| RUSTUP_TOOLCHAIN: stable | |
| run: ./scripts/check-publish-coverage.sh | |
| # ── Changelog check ────────────────────────────────────────────────────── | |
| # CHANGELOG.md is generated from .changes/ via changie. Fail if it has been | |
| # edited directly or is stale relative to the per-version source files. | |
| check-changelog: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install changie | |
| env: | |
| CHANGIE_VERSION: 1.24.2 | |
| # SHA256 of changie_${CHANGIE_VERSION}_linux_amd64.tar.gz from the | |
| # upstream release's checksums.txt. Bump together with the version. | |
| CHANGIE_SHA256: 31535a9d8dc548d6d8f315762bfd5b1fba34e707b7600748c8bb8a609649007d | |
| run: | | |
| curl -fsSL -o /tmp/changie.tar.gz \ | |
| "https://github.com/miniscruff/changie/releases/download/v${CHANGIE_VERSION}/changie_${CHANGIE_VERSION}_linux_amd64.tar.gz" | |
| echo "${CHANGIE_SHA256} /tmp/changie.tar.gz" | sha256sum -c - | |
| mkdir -p "${RUNNER_TEMP}/bin" | |
| tar -xzf /tmp/changie.tar.gz -C "${RUNNER_TEMP}/bin" changie | |
| echo "${RUNNER_TEMP}/bin" >> "${GITHUB_PATH}" | |
| "${RUNNER_TEMP}/bin/changie" --version | |
| - name: Verify CHANGELOG.md is in sync | |
| run: | | |
| changie merge | |
| # The message below is single-quoted on purpose: its backticks are | |
| # literal markdown for the reader, not command substitution. | |
| # shellcheck disable=SC2016 | |
| git diff --exit-code -- CHANGELOG.md || { | |
| echo '::error file=CHANGELOG.md::CHANGELOG.md is out of sync. Do not edit it directly — add a fragment via `task changelog-new` (see CONTRIBUTING.md), or run `task changelog-merge` if you edited a .changes/ file.' | |
| exit 1 | |
| } | |
| # ── MSRV check ─────────────────────────────────────────────────────────── | |
| msrv-check: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@stable | |
| # The checked-in Cargo.lock is written by the pinned dev toolchain and | |
| # may resolve transitive deps (e.g. getrandom, clap_lex) to versions | |
| # whose manifests cargo 1.75 cannot parse (edition2024). Regenerate with | |
| # stable cargo's MSRV-aware resolver so transitive deps satisfy | |
| # rust-version = 1.75; cargo writes a v3 lockfile because the workspace | |
| # rust-version is below 1.78. | |
| - name: Regenerate MSRV-compatible lockfile | |
| env: | |
| CARGO_RESOLVER_INCOMPATIBLE_RUST_VERSIONS: fallback | |
| run: rm -f Cargo.lock && cargo generate-lockfile | |
| - uses: dtolnay/rust-toolchain@master | |
| with: | |
| toolchain: '1.75' | |
| - name: Install protoc | |
| run: | | |
| curl -fsSL "https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC_VERSION}/protoc-${PROTOC_VERSION}-linux-x86_64.zip" -o /tmp/protoc.zip | |
| echo "${PROTOC_SHA256} /tmp/protoc.zip" | sha256sum -c - | |
| sudo unzip -o /tmp/protoc.zip -d /usr/local | |
| protoc --version | |
| - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 (sha-pinned) | |
| # rust-toolchain.toml pins the dev toolchain and overrides `rustup | |
| # default`, so RUSTUP_TOOLCHAIN is set explicitly to outrank the file. | |
| - name: Check (MSRV 1.75) | |
| env: | |
| RUSTUP_TOOLCHAIN: '1.75' | |
| run: cargo check --workspace --all-targets --locked | |
| # ── Miri: proves the `set_len`-publishing `unsafe` reads no uninit memory ── | |
| # SizeCache stores its inline slots as `MaybeUninit<u32>` to avoid zeroing the | |
| # whole array on every encode; `consume_next` reads them via `assume_init`. | |
| # `copy_into_spare` (types.rs) fills a Vec's spare capacity chunk by chunk and | |
| # publishes the length afterwards, including on the unwind paths its tests | |
| # drive. Miri tracks per-byte init state, so this job mechanically verifies | |
| # both invariants on every path those two test modules exercise. Scoped to | |
| # them to keep the (interpreted, slow) run fast — under a minute steady state, | |
| # so it runs on every PR as a blocking gate rather than on a nightly schedule. | |
| # | |
| # The nightly is PINNED (not floating): a required check must not be broken by | |
| # an unrelated bad nightly. Bump MIRI_TOOLCHAIN occasionally; the sysroot | |
| # cache key follows it. `cargo +<toolchain>` overrides rust-toolchain.toml. | |
| miri: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| env: | |
| MIRI_TOOLCHAIN: nightly-2026-02-27 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@master | |
| with: | |
| toolchain: ${{ env.MIRI_TOOLCHAIN }} | |
| components: miri | |
| - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 (sha-pinned) | |
| # The Miri std sysroot (~100 MB) is the only slow part of a cold run | |
| # (~1-3 min to build); rust-cache does not cover it. Cache it keyed on the | |
| # pinned toolchain so steady-state runs skip the build. | |
| - name: Cache Miri sysroot | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.cache/miri | |
| key: miri-sysroot-${{ runner.os }}-${{ env.MIRI_TOOLCHAIN }} | |
| - name: Miri setup (build/restore sysroot) | |
| run: cargo +${{ env.MIRI_TOOLCHAIN }} miri setup | |
| - name: Miri (size_cache and copy_into_spare soundness) | |
| run: cargo +${{ env.MIRI_TOOLCHAIN }} miri test -p buffa -- size_cache copy_into_spare | |
| # OwnedView: the view borrows from the Bytes it is stored beside, with | |
| # forged 'static lifetimes hidden behind a MaybeDangling wrapper. Miri | |
| # turns a wrong field order (a dangling borrow while the view's | |
| # destructor runs), a second drop of the view on the into_bytes unwind | |
| # path, or a missing MaybeDangling (a protector on the forged borrows | |
| # when an OwnedView is passed by value) into a hard error. | |
| # `owned_view_lifetime_parametric_contract` adds the Debug, Clone, | |
| # PartialEq, reborrow and to_owned_message paths on a hand-written view. | |
| - name: Miri (OwnedView soundness) | |
| run: >- | |
| cargo +${{ env.MIRI_TOOLCHAIN }} miri test -p buffa -- | |
| owned_view_drop owned_view_into_bytes owned_view_lifetime_parametric_contract | |
| # ── no_std and 32-bit compilation checks ───────────────────────────────── | |
| check-nostd: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| # Must name the same version as rust-toolchain.toml (which selects the | |
| # toolchain cargo uses) so the cross-targets installed here belong to | |
| # that toolchain. With @stable, the targets land on a toolchain the | |
| # file then bypasses, and the bare-metal check fails with E0463. | |
| - uses: dtolnay/rust-toolchain@1.95 | |
| with: | |
| targets: i686-unknown-linux-gnu, thumbv7em-none-eabihf | |
| - name: Install protoc | |
| run: | | |
| curl -fsSL "https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC_VERSION}/protoc-${PROTOC_VERSION}-linux-x86_64.zip" -o /tmp/protoc.zip | |
| echo "${PROTOC_SHA256} /tmp/protoc.zip" | sha256sum -c - | |
| sudo unzip -o /tmp/protoc.zip -d /usr/local | |
| protoc --version | |
| - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 (sha-pinned) | |
| - name: Check buffa no_std (host) | |
| run: cargo check -p buffa --no-default-features | |
| - name: Check buffa no_std (bare-metal ARM) | |
| run: cargo check -p buffa --no-default-features --target thumbv7em-none-eabihf | |
| - name: Check buffa-types no_std | |
| run: cargo check -p buffa-types --no-default-features | |
| - name: Check buffa-types no_std + chrono | |
| run: cargo check -p buffa-types --no-default-features --features chrono | |
| - name: Check buffa-descriptor no_std | |
| run: cargo check -p buffa-descriptor --no-default-features | |
| - name: Check workspace 32-bit | |
| run: cargo check --workspace --target i686-unknown-linux-gnu | |
| # ── Verify checked-in generated code is up to date ─────────────────────── | |
| check-generated-code: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - name: Install protoc | |
| run: | | |
| curl -fsSL "https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC_VERSION}/protoc-${PROTOC_VERSION}-linux-x86_64.zip" -o /tmp/protoc.zip | |
| echo "${PROTOC_SHA256} /tmp/protoc.zip" | sha256sum -c - | |
| sudo unzip -o /tmp/protoc.zip -d /usr/local | |
| protoc --version | |
| - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 (sha-pinned) | |
| - name: Regenerate bootstrap descriptor types | |
| # Proto sources are vendored in buffa-descriptor/protos/ (pinned), | |
| # so this is independent of the installed protoc's bundled includes. | |
| run: scripts/gen-bootstrap-types.sh | |
| - name: Generate descriptor set (WKTs) | |
| run: | | |
| # WKT protos are vendored in buffa-types/protos (NOT read from | |
| # /usr/local/include) so the checked-in code is pinned to a | |
| # specific proto source, not whatever protoc version ships. | |
| protoc --descriptor_set_out=/tmp/wkt.pb --include_imports \ | |
| --include_source_info \ | |
| -I buffa-types/protos \ | |
| google/protobuf/any.proto \ | |
| google/protobuf/api.proto \ | |
| google/protobuf/duration.proto \ | |
| google/protobuf/empty.proto \ | |
| google/protobuf/field_mask.proto \ | |
| google/protobuf/source_context.proto \ | |
| google/protobuf/struct.proto \ | |
| google/protobuf/timestamp.proto \ | |
| google/protobuf/type.proto \ | |
| google/protobuf/wrappers.proto | |
| - name: Regenerate WKT types | |
| run: cargo run -p buffa-codegen --bin gen_wkt_types -- /tmp/wkt.pb buffa-types/src/generated | |
| - name: Check for differences | |
| run: | | |
| if ! git diff --exit-code buffa-descriptor/src/generated/ buffa-types/src/generated/; then | |
| echo "::error::Checked-in generated code is stale. Run 'task gen-wkt-types' and/or regenerate bootstrap types, then commit." | |
| exit 1 | |
| fi | |
| # ── Conformance test suite ─────────────────────────────────────────────── | |
| # Builds conformance binaries on the runner (cached via rust-cache) and | |
| # extracts the conformance_test_runner + proto files from the tools image. | |
| conformance: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 (sha-pinned) | |
| with: | |
| workspaces: conformance | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 (sha-pinned) | |
| - name: Build tools image (cached) | |
| uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2 (sha-pinned) | |
| with: | |
| context: . | |
| file: conformance/Dockerfile.tools | |
| load: true | |
| tags: buffa/tools:local | |
| cache-from: type=gha,scope=tools-image | |
| # Only main pushes save the cache. The cache service already | |
| # isolates branches (a PR-written entry is not restorable from | |
| # main), so this is quota hygiene plus defense in depth rather | |
| # than the poisoning boundary itself: PR and merge-queue saves | |
| # count against the repo's shared 10GB cache and can LRU-evict | |
| # the main-scoped entries every PR restores from — merge_group | |
| # writes land on an ephemeral queue ref nothing can ever restore. | |
| # Cost: a PR that edits Dockerfile.tools rebuilds cold on every | |
| # push instead of only the first; such PRs are rare. | |
| cache-to: ${{ github.event_name == 'push' && 'type=gha,scope=tools-image,mode=max' || '' }} | |
| - name: Extract tools from image | |
| run: | | |
| CID=$(docker create buffa/tools:local /dev/null) | |
| docker cp "$CID:/conformance_test_runner" /usr/local/bin/conformance_test_runner | |
| docker cp "$CID:/protoc" /usr/local/bin/protoc | |
| docker cp "$CID:/protos/." conformance/protos/ | |
| docker rm "$CID" | |
| chmod +x /usr/local/bin/conformance_test_runner /usr/local/bin/protoc | |
| # Both builds use the same target dir so build-script artifacts | |
| # (buffa-codegen, buffa-build, syn, etc.) are compiled only once. | |
| # The std binary is copied out before the no_std build overwrites it. | |
| - name: Determine host target | |
| id: host | |
| run: echo "triple=$(rustc -vV | grep '^host:' | cut -d' ' -f2)" >> "$GITHUB_OUTPUT" | |
| - name: Build conformance binary (std) | |
| run: >- | |
| cargo build --release --manifest-path conformance/Cargo.toml | |
| --target ${{ steps.host.outputs.triple }} | |
| - name: Save std binary | |
| run: cp conformance/target/${{ steps.host.outputs.triple }}/release/conformance /tmp/buffa-conformance-std | |
| - name: Build conformance binary (no_std) | |
| run: >- | |
| cargo build --release --manifest-path conformance/Cargo.toml | |
| --no-default-features --target ${{ steps.host.outputs.triple }} | |
| - name: Run conformance tests (std) | |
| run: >- | |
| conformance_test_runner | |
| --failure_list conformance/known_failures.txt | |
| --maximum_edition 2024 | |
| /tmp/buffa-conformance-std | |
| - name: Run conformance tests (no_std) | |
| run: >- | |
| conformance_test_runner | |
| --failure_list conformance/known_failures_nostd.txt | |
| --maximum_edition 2024 | |
| conformance/target/${{ steps.host.outputs.triple }}/release/conformance | |
| - name: Run conformance tests (via-view) | |
| env: | |
| BUFFA_VIA_VIEW: "1" | |
| run: >- | |
| conformance_test_runner | |
| --failure_list conformance/known_failures_view.txt | |
| --maximum_edition 2024 | |
| /tmp/buffa-conformance-std | |
| - name: Run conformance tests (via-lazy) | |
| env: | |
| BUFFA_VIA_LAZY: "1" | |
| run: >- | |
| conformance_test_runner | |
| --failure_list conformance/known_failures_lazy.txt | |
| --maximum_edition 2024 | |
| /tmp/buffa-conformance-std | |
| - name: Run conformance tests (view-json) | |
| env: | |
| BUFFA_VIEW_JSON: "1" | |
| run: >- | |
| conformance_test_runner | |
| --failure_list conformance/known_failures_view_json.txt | |
| --maximum_edition 2024 | |
| /tmp/buffa-conformance-std | |
| - name: Run conformance tests (via-reflect) | |
| env: | |
| BUFFA_VIA_REFLECT: "1" | |
| run: >- | |
| conformance_test_runner | |
| --failure_list conformance/known_failures_reflect.txt | |
| --maximum_edition 2024 | |
| /tmp/buffa-conformance-std | |
| - name: Run conformance tests (via-vtable) | |
| env: | |
| BUFFA_VIA_VTABLE: "1" | |
| run: >- | |
| conformance_test_runner | |
| --failure_list conformance/known_failures_view_vtable.txt | |
| --maximum_edition 2024 | |
| /tmp/buffa-conformance-std |