fix: add string attributes to `amend_artifact` for explicit unset state (#1499)

---------

Co-authored-by: Jonathan Perry <jonpez63@gmail.com>
diff --git a/MODULE.bazel b/MODULE.bazel
index 4a2e2af..032a47d 100644
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -185,6 +185,37 @@
     resolver = "coursier",
 )
 dev_maven.install(
+    name = "amend_artifacts",
+    artifacts = [
+        "com.google.guava:guava:31.1-jre",
+        "org.apache.commons:commons-lang3:3.12.0",
+        "org.slf4j:slf4j-api:1.7.32",
+    ],
+    lock_file = "//tests/custom_maven_install:amend_artifacts_install.json",
+)
+
+# Toggle the `testonly` flag on guava
+dev_maven.amend_artifact(
+    name = "amend_artifacts",
+    testonly = "on",
+    coordinates = "com.google.guava:guava",
+)
+dev_maven.amend_artifact(
+    name = "amend_artifacts",
+    testonly = "off",
+    coordinates = "com.google.guava:guava",
+)
+dev_maven.amend_artifact(
+    name = "amend_artifacts",
+    testonly = "true",
+    coordinates = "org.apache.commons:commons-lang3",
+)
+dev_maven.amend_artifact(
+    name = "amend_artifacts",
+    coordinates = "org.slf4j:slf4j-api",
+    neverlink = "on",
+)
+dev_maven.install(
     name = "duplicate_version_warning",
     artifacts = [
         "com.fasterxml.jackson.core:jackson-annotations:2.10.1",
@@ -285,7 +316,7 @@
 )
 dev_maven.amend_artifact(
     name = "from_files",
-    testonly = True,
+    testonly = "true",
     coordinates = "org.junit.jupiter:junit-jupiter-api",
 )
 dev_maven.install(
@@ -930,7 +961,7 @@
 dev_maven.amend_artifact(
     name = "root_wins",
     coordinates = "io.netty:netty-buffer",
-    force_version = True,
+    force_version = "true",
 )
 
 bazel_dep(name = "root_wins_layer", version = "0.0.0", dev_dependency = True)
@@ -971,6 +1002,7 @@
 # want it to
 use_repo(
     dev_maven,
+    "amend_artifacts",
     "duplicate_version_warning",
     "duplicate_version_warning_same_version",
     "exclusion_testing",
diff --git a/WORKSPACE b/WORKSPACE
index 806fb2f..d1cda26 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -132,7 +132,7 @@
         "org.hamcrest:hamcrest-core:2.1",
         "io.netty:netty-tcnative-boringssl-static:2.0.61.Final",
     ],
-    maven_install_json = "@rules_jvm_external//:maven_install.json",
+    maven_install_json = "@rules_jvm_external//:maven_coursier_install.json",
     repositories = [
         "https://repo1.maven.org/maven2",
     ],
@@ -1174,3 +1174,30 @@
     ],
     resolver = "gradle",
 )
+
+maven_install(
+    name = "amend_artifacts",
+    artifacts = [
+        maven.artifact(
+            testonly = False,
+            artifact = "guava",
+            group = "com.google.guava",
+            version = "31.1-jre",
+        ),
+        maven.artifact(
+            testonly = True,
+            artifact = "commons-lang3",
+            group = "org.apache.commons",
+            version = "3.12.0",
+        ),
+        maven.artifact(
+            artifact = "slf4j-api",
+            group = "org.slf4j",
+            neverlink = True,
+            version = "1.7.32",
+        ),
+    ],
+    repositories = [
+        "https://repo1.maven.org/maven2",
+    ],
+)
diff --git a/maven_coursier_install.json b/maven_coursier_install.json
new file mode 100644
index 0000000..3abf41f
--- /dev/null
+++ b/maven_coursier_install.json
@@ -0,0 +1,243 @@
+{
+  "__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL",
+  "__INPUT_ARTIFACTS_HASH": -1642503178,
+  "__RESOLVED_ARTIFACTS_HASH": -1242467072,
+  "artifacts": {
+    "com.google.code.findbugs:jsr305": {
+      "shasums": {
+        "jar": "766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7"
+      },
+      "version": "3.0.2"
+    },
+    "com.google.errorprone:error_prone_annotations": {
+      "shasums": {
+        "jar": "721cb91842b46fa056847d104d5225c8b8e1e8b62263b993051e1e5a0137b7ec"
+      },
+      "version": "2.11.0"
+    },
+    "com.google.guava:failureaccess": {
+      "shasums": {
+        "jar": "a171ee4c734dd2da837e4b16be9df4661afab72a41adaf31eb84dfdaf936ca26"
+      },
+      "version": "1.0.1"
+    },
+    "com.google.guava:guava": {
+      "shasums": {
+        "jar": "a42edc9cab792e39fe39bb94f3fca655ed157ff87a8af78e1d6ba5b07c4a00ab"
+      },
+      "version": "31.1-jre"
+    },
+    "com.google.guava:listenablefuture": {
+      "shasums": {
+        "jar": "b372a037d4230aa57fbeffdef30fd6123f9c0c2db85d0aced00c91b974f33f99"
+      },
+      "version": "9999.0-empty-to-avoid-conflict-with-guava"
+    },
+    "com.google.j2objc:j2objc-annotations": {
+      "shasums": {
+        "jar": "21af30c92267bd6122c0e0b4d20cccb6641a37eaf956c6540ec471d584e64a7b"
+      },
+      "version": "1.3"
+    },
+    "io.netty:netty-tcnative-boringssl-static": {
+      "shasums": {
+        "jar": "b6f974972c44cd6f9cecabc255290286faac40b6393c66c3c3c0db7f421cc28e",
+        "linux-aarch_64": "3614395218ae379cec22ccaa089c4f27b9329a660e0d53c93e7cb12b7a2cee46",
+        "linux-x86_64": "4ff9d14f1ec6ccee35b78f53a6f3d9c7c54535aa2a76138311c2f619c5e150e1",
+        "osx-aarch_64": "58e0302c9fde3db984c3ff7ee7ec7159dc0320bdb91533cc290e12e40911cd1a",
+        "osx-x86_64": "fcfea887f4f0802d363c699b444d504b7109a7cb198ae6845eeff63745e5b0ba",
+        "windows-x86_64": "17cd2fa3c63b7ed23edea01c945e55cb7baed1faa0f553732c3f5f56da90b3e0"
+      },
+      "version": "2.0.61.Final"
+    },
+    "io.netty:netty-tcnative-classes": {
+      "shasums": {
+        "jar": "9b970eccd844bfae175a5cbbf7bf94891894add06d6ccbe1abf2250cd64080f6"
+      },
+      "version": "2.0.61.Final"
+    },
+    "org.checkerframework:checker-qual": {
+      "shasums": {
+        "jar": "ff10785ac2a357ec5de9c293cb982a2cbb605c0309ea4cc1cb9b9bc6dbe7f3cb"
+      },
+      "version": "3.12.0"
+    },
+    "org.hamcrest:hamcrest": {
+      "shasums": {
+        "jar": "ba93b2e3a562322ba432f0a1b53addcc55cb188253319a020ed77f824e692050"
+      },
+      "version": "2.1"
+    },
+    "org.hamcrest:hamcrest-core": {
+      "shasums": {
+        "jar": "e09109e54a289d88506b9bfec987ddd199f4217c9464132668351b9a4f00bee9"
+      },
+      "version": "2.1"
+    }
+  },
+  "dependencies": {
+    "com.google.guava:guava": [
+      "com.google.code.findbugs:jsr305",
+      "com.google.errorprone:error_prone_annotations",
+      "com.google.guava:failureaccess",
+      "com.google.guava:listenablefuture",
+      "com.google.j2objc:j2objc-annotations",
+      "org.checkerframework:checker-qual"
+    ],
+    "io.netty:netty-tcnative-boringssl-static": [
+      "io.netty:netty-tcnative-boringssl-static:jar:linux-aarch_64",
+      "io.netty:netty-tcnative-boringssl-static:jar:linux-x86_64",
+      "io.netty:netty-tcnative-boringssl-static:jar:osx-aarch_64",
+      "io.netty:netty-tcnative-boringssl-static:jar:osx-x86_64",
+      "io.netty:netty-tcnative-boringssl-static:jar:windows-x86_64",
+      "io.netty:netty-tcnative-classes"
+    ],
+    "io.netty:netty-tcnative-boringssl-static:jar:linux-aarch_64": [
+      "io.netty:netty-tcnative-boringssl-static:jar:linux-x86_64",
+      "io.netty:netty-tcnative-boringssl-static:jar:osx-aarch_64",
+      "io.netty:netty-tcnative-boringssl-static:jar:osx-x86_64",
+      "io.netty:netty-tcnative-boringssl-static:jar:windows-x86_64",
+      "io.netty:netty-tcnative-classes"
+    ],
+    "io.netty:netty-tcnative-boringssl-static:jar:linux-x86_64": [
+      "io.netty:netty-tcnative-boringssl-static:jar:linux-aarch_64",
+      "io.netty:netty-tcnative-boringssl-static:jar:osx-aarch_64",
+      "io.netty:netty-tcnative-boringssl-static:jar:osx-x86_64",
+      "io.netty:netty-tcnative-boringssl-static:jar:windows-x86_64",
+      "io.netty:netty-tcnative-classes"
+    ],
+    "io.netty:netty-tcnative-boringssl-static:jar:osx-aarch_64": [
+      "io.netty:netty-tcnative-boringssl-static:jar:linux-aarch_64",
+      "io.netty:netty-tcnative-boringssl-static:jar:linux-x86_64",
+      "io.netty:netty-tcnative-boringssl-static:jar:osx-x86_64",
+      "io.netty:netty-tcnative-boringssl-static:jar:windows-x86_64",
+      "io.netty:netty-tcnative-classes"
+    ],
+    "io.netty:netty-tcnative-boringssl-static:jar:osx-x86_64": [
+      "io.netty:netty-tcnative-boringssl-static:jar:linux-aarch_64",
+      "io.netty:netty-tcnative-boringssl-static:jar:linux-x86_64",
+      "io.netty:netty-tcnative-boringssl-static:jar:osx-aarch_64",
+      "io.netty:netty-tcnative-boringssl-static:jar:windows-x86_64",
+      "io.netty:netty-tcnative-classes"
+    ],
+    "io.netty:netty-tcnative-boringssl-static:jar:windows-x86_64": [
+      "io.netty:netty-tcnative-boringssl-static:jar:linux-aarch_64",
+      "io.netty:netty-tcnative-boringssl-static:jar:linux-x86_64",
+      "io.netty:netty-tcnative-boringssl-static:jar:osx-aarch_64",
+      "io.netty:netty-tcnative-boringssl-static:jar:osx-x86_64",
+      "io.netty:netty-tcnative-classes"
+    ],
+    "org.hamcrest:hamcrest-core": [
+      "org.hamcrest:hamcrest"
+    ]
+  },
+  "packages": {
+    "com.google.code.findbugs:jsr305": [
+      "javax.annotation",
+      "javax.annotation.concurrent",
+      "javax.annotation.meta"
+    ],
+    "com.google.errorprone:error_prone_annotations": [
+      "com.google.errorprone.annotations",
+      "com.google.errorprone.annotations.concurrent"
+    ],
+    "com.google.guava:failureaccess": [
+      "com.google.common.util.concurrent.internal"
+    ],
+    "com.google.guava:guava": [
+      "com.google.common.annotations",
+      "com.google.common.base",
+      "com.google.common.base.internal",
+      "com.google.common.cache",
+      "com.google.common.collect",
+      "com.google.common.escape",
+      "com.google.common.eventbus",
+      "com.google.common.graph",
+      "com.google.common.hash",
+      "com.google.common.html",
+      "com.google.common.io",
+      "com.google.common.math",
+      "com.google.common.net",
+      "com.google.common.primitives",
+      "com.google.common.reflect",
+      "com.google.common.util.concurrent",
+      "com.google.common.xml",
+      "com.google.thirdparty.publicsuffix"
+    ],
+    "com.google.j2objc:j2objc-annotations": [
+      "com.google.j2objc.annotations"
+    ],
+    "io.netty:netty-tcnative-classes": [
+      "io.netty.internal.tcnative"
+    ],
+    "org.checkerframework:checker-qual": [
+      "org.checkerframework.checker.builder.qual",
+      "org.checkerframework.checker.calledmethods.qual",
+      "org.checkerframework.checker.compilermsgs.qual",
+      "org.checkerframework.checker.fenum.qual",
+      "org.checkerframework.checker.formatter.qual",
+      "org.checkerframework.checker.guieffect.qual",
+      "org.checkerframework.checker.i18n.qual",
+      "org.checkerframework.checker.i18nformatter.qual",
+      "org.checkerframework.checker.index.qual",
+      "org.checkerframework.checker.initialization.qual",
+      "org.checkerframework.checker.interning.qual",
+      "org.checkerframework.checker.lock.qual",
+      "org.checkerframework.checker.nullness.qual",
+      "org.checkerframework.checker.optional.qual",
+      "org.checkerframework.checker.propkey.qual",
+      "org.checkerframework.checker.regex.qual",
+      "org.checkerframework.checker.signature.qual",
+      "org.checkerframework.checker.signedness.qual",
+      "org.checkerframework.checker.tainting.qual",
+      "org.checkerframework.checker.units.qual",
+      "org.checkerframework.common.aliasing.qual",
+      "org.checkerframework.common.initializedfields.qual",
+      "org.checkerframework.common.reflection.qual",
+      "org.checkerframework.common.returnsreceiver.qual",
+      "org.checkerframework.common.subtyping.qual",
+      "org.checkerframework.common.util.report.qual",
+      "org.checkerframework.common.value.qual",
+      "org.checkerframework.dataflow.qual",
+      "org.checkerframework.framework.qual"
+    ],
+    "org.hamcrest:hamcrest": [
+      "org.hamcrest",
+      "org.hamcrest.beans",
+      "org.hamcrest.collection",
+      "org.hamcrest.comparator",
+      "org.hamcrest.core",
+      "org.hamcrest.internal",
+      "org.hamcrest.io",
+      "org.hamcrest.number",
+      "org.hamcrest.object",
+      "org.hamcrest.text",
+      "org.hamcrest.xml"
+    ],
+    "org.hamcrest:hamcrest-core": [
+      "org.hamcrest"
+    ]
+  },
+  "repositories": {
+    "https://repo1.maven.org/maven2/": [
+      "com.google.code.findbugs:jsr305",
+      "com.google.errorprone:error_prone_annotations",
+      "com.google.guava:failureaccess",
+      "com.google.guava:guava",
+      "com.google.guava:listenablefuture",
+      "com.google.j2objc:j2objc-annotations",
+      "io.netty:netty-tcnative-boringssl-static",
+      "io.netty:netty-tcnative-boringssl-static:jar:linux-aarch_64",
+      "io.netty:netty-tcnative-boringssl-static:jar:linux-x86_64",
+      "io.netty:netty-tcnative-boringssl-static:jar:osx-aarch_64",
+      "io.netty:netty-tcnative-boringssl-static:jar:osx-x86_64",
+      "io.netty:netty-tcnative-boringssl-static:jar:windows-x86_64",
+      "io.netty:netty-tcnative-classes",
+      "org.checkerframework:checker-qual",
+      "org.hamcrest:hamcrest",
+      "org.hamcrest:hamcrest-core"
+    ]
+  },
+  "services": {},
+  "version": "2"
+}
diff --git a/private/extensions/maven.bzl b/private/extensions/maven.bzl
index 3478d55..eb53082 100644
--- a/private/extensions/maven.bzl
+++ b/private/extensions/maven.bzl
@@ -148,9 +148,9 @@
     attrs = {
         "name": attr.string(default = DEFAULT_NAME),
         "coordinates": attr.string(doc = "Coordinates of the artifact to amend. Only `group:artifact` are used for matching.", mandatory = True),
-        "force_version": attr.bool(default = False),
-        "neverlink": attr.bool(),
-        "testonly": attr.bool(),
+        "force_version": attr.string(values = ["on", "off", "true", "false", ""], default = ""),
+        "neverlink": attr.string(values = ["on", "off", "true", "false", ""], default = ""),
+        "testonly": attr.string(values = ["on", "off", "true", "false", ""], default = ""),
         "exclusions": attr.string_list(doc = "Maven artifact tuples, in `artifactId:groupId` format", allow_empty = True),
     },
 )
@@ -277,6 +277,13 @@
 
     return root_artifacts + filtered_non_root_artifacts
 
+def _get_tri_state_bool(amend_val, original_val):
+    if amend_val in ["true", "on"]:
+        return True
+    if amend_val in ["false", "off"]:
+        return False
+    return original_val
+
 def _amend_artifact(original_artifact, amend):
     """Apply amendments to an artifact struct, returning a new amended struct."""
 
@@ -288,15 +295,16 @@
         final_exclusions = existing_exclusions + new_exclusions
 
     # Create new struct with amendments applied
+
     return struct(
         group = original_artifact.group,
         artifact = original_artifact.artifact,
         version = getattr(original_artifact, "version", None),
         packaging = getattr(original_artifact, "packaging", None),
         classifier = getattr(original_artifact, "classifier", None),
-        force_version = amend.force_version if amend.force_version else getattr(original_artifact, "force_version", None),
-        neverlink = amend.neverlink if amend.neverlink else getattr(original_artifact, "neverlink", None),
-        testonly = amend.testonly if amend.testonly else getattr(original_artifact, "testonly", None),
+        force_version = _get_tri_state_bool(amend.force_version, getattr(original_artifact, "force_version", None)),
+        neverlink = _get_tri_state_bool(amend.neverlink, getattr(original_artifact, "neverlink", None)),
+        testonly = _get_tri_state_bool(amend.testonly, getattr(original_artifact, "testonly", None)),
         exclusions = final_exclusions if final_exclusions else None,
     )
 
diff --git a/tests/custom_maven_install/amend_artifacts_install.json b/tests/custom_maven_install/amend_artifacts_install.json
new file mode 100644
index 0000000..68f7211
--- /dev/null
+++ b/tests/custom_maven_install/amend_artifacts_install.json
@@ -0,0 +1,179 @@
+{
+  "__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL",
+  "__INPUT_ARTIFACTS_HASH": -2130695768,
+  "__RESOLVED_ARTIFACTS_HASH": -1665659154,
+  "artifacts": {
+    "com.google.code.findbugs:jsr305": {
+      "shasums": {
+        "jar": "766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7"
+      },
+      "version": "3.0.2"
+    },
+    "com.google.errorprone:error_prone_annotations": {
+      "shasums": {
+        "jar": "721cb91842b46fa056847d104d5225c8b8e1e8b62263b993051e1e5a0137b7ec"
+      },
+      "version": "2.11.0"
+    },
+    "com.google.guava:failureaccess": {
+      "shasums": {
+        "jar": "a171ee4c734dd2da837e4b16be9df4661afab72a41adaf31eb84dfdaf936ca26"
+      },
+      "version": "1.0.1"
+    },
+    "com.google.guava:guava": {
+      "shasums": {
+        "jar": "a42edc9cab792e39fe39bb94f3fca655ed157ff87a8af78e1d6ba5b07c4a00ab"
+      },
+      "version": "31.1-jre"
+    },
+    "com.google.guava:listenablefuture": {
+      "shasums": {
+        "jar": "b372a037d4230aa57fbeffdef30fd6123f9c0c2db85d0aced00c91b974f33f99"
+      },
+      "version": "9999.0-empty-to-avoid-conflict-with-guava"
+    },
+    "com.google.j2objc:j2objc-annotations": {
+      "shasums": {
+        "jar": "21af30c92267bd6122c0e0b4d20cccb6641a37eaf956c6540ec471d584e64a7b"
+      },
+      "version": "1.3"
+    },
+    "org.apache.commons:commons-lang3": {
+      "shasums": {
+        "jar": "d919d904486c037f8d193412da0c92e22a9fa24230b9d67a57855c5c31c7e94e"
+      },
+      "version": "3.12.0"
+    },
+    "org.checkerframework:checker-qual": {
+      "shasums": {
+        "jar": "ff10785ac2a357ec5de9c293cb982a2cbb605c0309ea4cc1cb9b9bc6dbe7f3cb"
+      },
+      "version": "3.12.0"
+    },
+    "org.slf4j:slf4j-api": {
+      "shasums": {
+        "jar": "3624f8474c1af46d75f98bc097d7864a323c81b3808aa43689a6e1c601c027be"
+      },
+      "version": "1.7.32"
+    }
+  },
+  "dependencies": {
+    "com.google.guava:guava": [
+      "com.google.code.findbugs:jsr305",
+      "com.google.errorprone:error_prone_annotations",
+      "com.google.guava:failureaccess",
+      "com.google.guava:listenablefuture",
+      "com.google.j2objc:j2objc-annotations",
+      "org.checkerframework:checker-qual"
+    ]
+  },
+  "packages": {
+    "com.google.code.findbugs:jsr305": [
+      "javax.annotation",
+      "javax.annotation.concurrent",
+      "javax.annotation.meta"
+    ],
+    "com.google.errorprone:error_prone_annotations": [
+      "com.google.errorprone.annotations",
+      "com.google.errorprone.annotations.concurrent"
+    ],
+    "com.google.guava:failureaccess": [
+      "com.google.common.util.concurrent.internal"
+    ],
+    "com.google.guava:guava": [
+      "com.google.common.annotations",
+      "com.google.common.base",
+      "com.google.common.base.internal",
+      "com.google.common.cache",
+      "com.google.common.collect",
+      "com.google.common.escape",
+      "com.google.common.eventbus",
+      "com.google.common.graph",
+      "com.google.common.hash",
+      "com.google.common.html",
+      "com.google.common.io",
+      "com.google.common.math",
+      "com.google.common.net",
+      "com.google.common.primitives",
+      "com.google.common.reflect",
+      "com.google.common.util.concurrent",
+      "com.google.common.xml",
+      "com.google.thirdparty.publicsuffix"
+    ],
+    "com.google.j2objc:j2objc-annotations": [
+      "com.google.j2objc.annotations"
+    ],
+    "org.apache.commons:commons-lang3": [
+      "org.apache.commons.lang3",
+      "org.apache.commons.lang3.arch",
+      "org.apache.commons.lang3.builder",
+      "org.apache.commons.lang3.compare",
+      "org.apache.commons.lang3.concurrent",
+      "org.apache.commons.lang3.concurrent.locks",
+      "org.apache.commons.lang3.event",
+      "org.apache.commons.lang3.exception",
+      "org.apache.commons.lang3.function",
+      "org.apache.commons.lang3.math",
+      "org.apache.commons.lang3.mutable",
+      "org.apache.commons.lang3.reflect",
+      "org.apache.commons.lang3.stream",
+      "org.apache.commons.lang3.text",
+      "org.apache.commons.lang3.text.translate",
+      "org.apache.commons.lang3.time",
+      "org.apache.commons.lang3.tuple"
+    ],
+    "org.checkerframework:checker-qual": [
+      "org.checkerframework.checker.builder.qual",
+      "org.checkerframework.checker.calledmethods.qual",
+      "org.checkerframework.checker.compilermsgs.qual",
+      "org.checkerframework.checker.fenum.qual",
+      "org.checkerframework.checker.formatter.qual",
+      "org.checkerframework.checker.guieffect.qual",
+      "org.checkerframework.checker.i18n.qual",
+      "org.checkerframework.checker.i18nformatter.qual",
+      "org.checkerframework.checker.index.qual",
+      "org.checkerframework.checker.initialization.qual",
+      "org.checkerframework.checker.interning.qual",
+      "org.checkerframework.checker.lock.qual",
+      "org.checkerframework.checker.nullness.qual",
+      "org.checkerframework.checker.optional.qual",
+      "org.checkerframework.checker.propkey.qual",
+      "org.checkerframework.checker.regex.qual",
+      "org.checkerframework.checker.signature.qual",
+      "org.checkerframework.checker.signedness.qual",
+      "org.checkerframework.checker.tainting.qual",
+      "org.checkerframework.checker.units.qual",
+      "org.checkerframework.common.aliasing.qual",
+      "org.checkerframework.common.initializedfields.qual",
+      "org.checkerframework.common.reflection.qual",
+      "org.checkerframework.common.returnsreceiver.qual",
+      "org.checkerframework.common.subtyping.qual",
+      "org.checkerframework.common.util.report.qual",
+      "org.checkerframework.common.value.qual",
+      "org.checkerframework.dataflow.qual",
+      "org.checkerframework.framework.qual"
+    ],
+    "org.slf4j:slf4j-api": [
+      "org.slf4j",
+      "org.slf4j.event",
+      "org.slf4j.helpers",
+      "org.slf4j.spi"
+    ]
+  },
+  "repositories": {
+    "https://repo1.maven.org/maven2/": [
+      "com.google.code.findbugs:jsr305",
+      "com.google.errorprone:error_prone_annotations",
+      "com.google.guava:failureaccess",
+      "com.google.guava:guava",
+      "com.google.guava:listenablefuture",
+      "com.google.j2objc:j2objc-annotations",
+      "org.apache.commons:commons-lang3",
+      "org.checkerframework:checker-qual",
+      "org.slf4j:slf4j-api"
+    ]
+  },
+  "services": {},
+  "version": "2"
+}
diff --git a/tests/integration/amend_artifact_test/BUILD b/tests/integration/amend_artifact_test/BUILD
new file mode 100644
index 0000000..80fb083
--- /dev/null
+++ b/tests/integration/amend_artifact_test/BUILD
@@ -0,0 +1,40 @@
+load("@bazel_skylib//rules:build_test.bzl", "build_test")
+
+# This test checks if the testonly attribute was correctly applied.
+# If testonly=True applied, this target should have testonly=1.
+# But build_test doesn't check attribute values directly.
+# We can use a rule that requires testonly dependencies?
+# or just inspect with genquery.
+
+genquery(
+    name = "check_guava_testonly",
+    expression = "attr(testonly, 1, @amend_artifacts//:com_google_guava_guava)",
+    scope = ["@amend_artifacts//:com_google_guava_guava"],
+)
+
+genquery(
+    name = "check_lang3_testonly",
+    expression = "attr(testonly, 1, @amend_artifacts//:org_apache_commons_commons_lang3)",
+    scope = ["@amend_artifacts//:org_apache_commons_commons_lang3"],
+)
+
+genquery(
+    name = "check_slf4j_neverlink",
+    expression = "attr(neverlink, 1, @amend_artifacts//:org_slf4j_slf4j_api)",
+    scope = ["@amend_artifacts//:org_slf4j_slf4j_api"],
+)
+
+sh_test(
+    name = "verify_testonly",
+    srcs = ["verify.sh"],
+    args = [
+        "$(location :check_guava_testonly)",
+        "$(location :check_lang3_testonly)",
+        "$(location :check_slf4j_neverlink)",
+    ],
+    data = [
+        ":check_guava_testonly",
+        ":check_lang3_testonly",
+        ":check_slf4j_neverlink",
+    ],
+)
diff --git a/tests/integration/amend_artifact_test/verify.sh b/tests/integration/amend_artifact_test/verify.sh
new file mode 100755
index 0000000..6df5b10
--- /dev/null
+++ b/tests/integration/amend_artifact_test/verify.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+set -e
+GUAVA_OUTPUT="$1"
+LANG3_OUTPUT="$2"
+SLF4J_OUTPUT="$3"
+
+if [ -s "$GUAVA_OUTPUT" ]; then
+  echo "Error: Guava output is NOT empty. 'testonly' was not unset."
+  cat "$GUAVA_OUTPUT"
+  exit 1
+fi
+
+if [ ! -s "$LANG3_OUTPUT" ]; then
+  echo "Error: Lang3 output is empty. 'testonly_int=1' failed."
+  exit 1
+fi
+
+if [ ! -s "$SLF4J_OUTPUT" ]; then
+  echo "Error: Slf4j output is empty. 'neverlink_int=1' failed."
+  exit 1
+fi
+
+echo "All verification checks passed!"
+