diff --git a/.github/workflows/raincloud-conformance.yml b/.github/workflows/raincloud-conformance.yml
index 1acdea37..d6f711af 100644
--- a/.github/workflows/raincloud-conformance.yml
+++ b/.github/workflows/raincloud-conformance.yml
@@ -51,7 +51,7 @@ jobs:
run: scripts/hydrate-raincloud-corpus.sh --max-mb "${{ github.event.inputs.max-mb || '200' }}"
- name: Run conformance suite
- run: ./mvnw verify -pl integration -am -Dit.test=RaincloudConformanceIntegrationTest
+ run: ./mvnw verify -pl integration -am -Dvortex.it.excludedGroups= -Dit.test=RaincloudConformanceIntegrationTest
- name: Publish per-slug results to job summary
if: always()
diff --git a/CLAUDE.md b/CLAUDE.md
index 9aa6cf27..566f3148 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -63,10 +63,17 @@ Trunk-based. PRs fine but always squash or rebase — no merge commits. Keep com
./mvnw verify -pl integration -am # integration (failsafe, NOT surefire)
./mvnw verify -pl integration -am -Dit.test="RustWritesJavaReadsIntegrationTest#method"
./bench JavaVsJniReadBenchmark.javaReadVolume # benchmark — always ClassName.methodName filter
-scripts/hydrate-raincloud-corpus.sh --max-mb 200 # hydrate real-world conformance corpus (#205),
- # then verify -Dit.test=RaincloudConformanceIntegrationTest
+scripts/hydrate-raincloud-corpus.sh --max-mb 200 # hydrate real-world conformance corpus (#205), then:
+./mvnw verify -pl integration -am -Dvortex.it.excludedGroups= -Dit.test="RaincloudConformanceIntegrationTest"
```
+The Raincloud corpus tests (`RaincloudConformanceIntegrationTest`,
+`RaincloudSizeComparisonIntegrationTest`) are `@Tag("raincloud")` and excluded from a routine
+`./mvnw verify` (failsafe `excludedGroups`, default `raincloud`) so a plain build never runs the
+real corpus — even on a machine that has hydrated it locally. Opt in with
+`-Dvortex.it.excludedGroups=` (clears the exclusion); this is required *in addition to* `-Dit.test`,
+since the tag filter applies even to an explicitly named class.
+
Regenerate after editing `.fbs`/`.proto` (both generators are in-house, no external tools):
```bash
diff --git a/docs/compatibility.md b/docs/compatibility.md
index dcea9742..3858ec06 100644
--- a/docs/compatibility.md
+++ b/docs/compatibility.md
@@ -55,7 +55,7 @@ oracle) — a zero-diff proves every value survived the Python-write / Java-read
```bash
scripts/hydrate-raincloud-corpus.sh --max-mb 200 # cache → mirror → local build
-./mvnw verify -pl integration -am -Dit.test=RaincloudConformanceIntegrationTest
+./mvnw verify -pl integration -am -Dvortex.it.excludedGroups= -Dit.test=RaincloudConformanceIntegrationTest
```
Per-slug status lives in `integration/src/test/resources/raincloud/expected-status.csv`
diff --git a/integration/pom.xml b/integration/pom.xml
index 4721d649..c41726bc 100644
--- a/integration/pom.xml
+++ b/integration/pom.xml
@@ -14,6 +14,11 @@
true
+
+ raincloud
@@ -203,6 +208,16 @@
**/*IntegrationTest.java
+
+ ${vortex.it.excludedGroups}
@{argLine}
--add-opens java.base/java.nio=ALL-UNNAMED
diff --git a/integration/src/test/java/io/github/dfa1/vortex/integration/RaincloudConformanceIntegrationTest.java b/integration/src/test/java/io/github/dfa1/vortex/integration/RaincloudConformanceIntegrationTest.java
index 222b5dd9..62051c16 100644
--- a/integration/src/test/java/io/github/dfa1/vortex/integration/RaincloudConformanceIntegrationTest.java
+++ b/integration/src/test/java/io/github/dfa1/vortex/integration/RaincloudConformanceIntegrationTest.java
@@ -12,6 +12,7 @@
import io.github.dfa1.vortex.csv.CsvExporter;
import io.github.dfa1.vortex.csv.ExportOptions;
import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestFactory;
import org.junit.jupiter.api.parallel.Execution;
@@ -55,6 +56,14 @@
/// Expected per-slug status lives in `src/test/resources/raincloud/expected-status.csv`.
/// Known gaps assert that the failure still occurs, so fixing the reader forces the
/// matrix entry to flip to `ok` in the same change.
+///
+/// Tagged `raincloud` and excluded from the default `./mvnw verify` (via the failsafe
+/// `excludedGroups` configuration) so a routine build never runs the real corpus even on
+/// a developer machine that has hydrated it locally. The exclusion applies even to an
+/// explicit `-Dit.test=RaincloudConformanceIntegrationTest` selection, so running it
+/// requires clearing the tag filter first: `-Dvortex.it.excludedGroups=
+/// -Dit.test=RaincloudConformanceIntegrationTest`.
+@Tag("raincloud")
class RaincloudConformanceIntegrationTest {
private static final Path DEFAULT_MANIFEST =
diff --git a/integration/src/test/java/io/github/dfa1/vortex/integration/RaincloudSizeComparisonIntegrationTest.java b/integration/src/test/java/io/github/dfa1/vortex/integration/RaincloudSizeComparisonIntegrationTest.java
index 4269d494..c53a7c5f 100644
--- a/integration/src/test/java/io/github/dfa1/vortex/integration/RaincloudSizeComparisonIntegrationTest.java
+++ b/integration/src/test/java/io/github/dfa1/vortex/integration/RaincloudSizeComparisonIntegrationTest.java
@@ -2,6 +2,7 @@
import io.github.dfa1.vortex.parquet.ParquetImporter;
import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestFactory;
import org.junit.jupiter.api.parallel.Execution;
@@ -25,6 +26,14 @@
/// Skipped (visibly) when the corpus is not hydrated — run
/// `scripts/hydrate-raincloud-corpus.sh` first, or point `RAINCLOUD_CORPUS_MANIFEST`
/// at a manifest TSV (`slugvortex-pathparquet-path` per line).
+///
+/// Tagged `raincloud` and excluded from the default `./mvnw verify` (via the failsafe
+/// `excludedGroups` configuration): this purely-informational, CPU-heavy re-encode never
+/// gates a routine build, even on a developer machine that has hydrated the corpus locally.
+/// The exclusion applies even to an explicit `-Dit.test=RaincloudSizeComparisonIntegrationTest`
+/// selection, so running it requires clearing the tag filter first:
+/// `-Dvortex.it.excludedGroups= -Dit.test=RaincloudSizeComparisonIntegrationTest`.
+@Tag("raincloud")
class RaincloudSizeComparisonIntegrationTest {
private static final Path DEFAULT_MANIFEST =
diff --git a/scripts/hydrate-raincloud-corpus.sh b/scripts/hydrate-raincloud-corpus.sh
index 6520585b..1b4f4261 100755
--- a/scripts/hydrate-raincloud-corpus.sh
+++ b/scripts/hydrate-raincloud-corpus.sh
@@ -10,6 +10,11 @@
# Usage:
# scripts/hydrate-raincloud-corpus.sh [--max-mb N] [slug ...]
#
+# The conformance test is @Tag("raincloud") and excluded from a routine `./mvnw verify`,
+# so after hydrating run it explicitly with the tag exclusion cleared:
+# ./mvnw verify -pl integration -am -Dvortex.it.excludedGroups= \
+# -Dit.test=RaincloudConformanceIntegrationTest
+#
# With no slugs, hydrates every entry of the conformance matrix
# (integration/src/test/resources/raincloud/expected-status.csv) whose combined
# artifact size fits --max-mb (default 200; use --max-mb 0 for no size cap — the
@@ -115,4 +120,6 @@ with open(os.environ["MANIFEST"], "w") as manifest:
hydrated += 1
print(f"ok {slug}")
print(f"\nhydrated={hydrated} skipped={skipped} manifest={os.environ['MANIFEST']}")
+print("run: ./mvnw verify -pl integration -am -Dvortex.it.excludedGroups= "
+ "-Dit.test=RaincloudConformanceIntegrationTest")
PY