The backend, and how the four language adoptions compare against it, are documented once in
+ * aepfli/flagsmith-tck-testbed rather
+ * than restated in each adoption.
+ */
+public class FlagsmithProviderTckTest extends ContainerizedProviderTckTest {
+
+ /** Fixed by the testbed, because the control API cannot hand connection parameters to a provider. */
+ private static final String SERVER_SIDE_KEY = "ser.provider-tck-server-key";
+
+ private static final int PROXY_PORT = 8000;
+
+ @Override
+ public File composeFile() {
+ return new File("src/test/resources/tck/docker-compose.yaml");
+ }
+
+ @Override
+ public List {@code VARIANTS} is withheld for the reason the Go adoption established: Flagsmith has no
+ * variant concept for a plain feature, the evaluation response carries no variant key, and no
+ * seeding can produce one. That is permitted rather than defective -- 2.2.4 makes populating
+ * the variant a SHOULD -- so it carries no deviation entry.
+ *
+ * {@code LARGE_INTEGERS} is withheld here and declared in Go, and the difference is real
+ * rather than an oversight: Java's integer accessor is a 32-bit {@code Integer}, so 2^53-1
+ * cannot be asked for at all. This is the same reason Java withholds it for flagd.
+ *
+ * {@code STANDARD_REASONS} and {@code NUMERIC_COERCION} are declared and both fail: this
+ * provider attempts each and gets it wrong, so the failures belong in the results.
+ *
+ * {@code STRING_TYPING} is declared and {@code FULLY_TYPED_VALUES} is withheld, and
+ * this is the backend that pair of capabilities was created for. The previous pass
+ * measured all four scenarios under one tag: {@code boolean-flag} and {@code integer-flag}
+ * reported {@code TYPE_MISMATCH} correctly, while {@code float-flag} through the String accessor
+ * resolved to {@code "0.5"} and {@code object-flag} to its raw JSON text. That split is exactly
+ * Flagsmith's type system: {@code feature_state_value} is natively boolean, integer or string,
+ * so a boolean flag really is a boolean and an integer really is an integer — but a float and a
+ * structure have no native type and are stored as strings. Asked for as strings, they
+ * are returned, and that is the resolved flag value.
+ *
+ * So the declaration now follows the backend rather than averaging over it. Specification
+ * revision {@code bda599f1} split the tag along that line — {@code @string-typing} keeps the
+ * boolean and integer rows, {@code @fully-typed-values} takes the float and the structure — and
+ * this provider declares the first and withholds the second. The reason for withholding is a
+ * fact about the store and not about the provider: Flagsmith records no native float or
+ * structure type, so there is no mismatch here to report.
+ *
+ * Withholding rather than a {@link KnownDeviation}, which is the opposite call from
+ * {@code NUMERIC_COERCION} above, and Appendix F's declaring rules are what separate them. The
+ * rule about scenarios being askable is subordinate to a prior question — whether the provider
+ * owes an answer at all — and for these tags it does not: {@code TYPE_MISMATCH} is obliged by no
+ * requirement, and the only normative statement about value type is Requirement 1.3.4, a
+ * {@code SHOULD} on the client. Where the specification permits declining, withholding is the
+ * honest report however askable the scenarios are, and a deviation would assert a defect that
+ * does not exist. {@code NUMERIC_COERCION} is declared because flagd's ADR is a rule this suite
+ * binds providers to; nothing binds Flagsmith to report a type its backend does not have.
+ *
+ * The cost the previous pass recorded is gone, and recording it is what removed it. Under one
+ * tag, withholding skipped the two scenarios this provider gets right along with the two it does
+ * not, and that note ended "revisit if the capability is ever split by flag type". It was — the
+ * measurement above is cited in Appendix F as the case that motivated the split, alongside a
+ * language that failed the boolean and integer rows and would have had that defect published as
+ * a permitted absence. Declaring the narrower tag now holds this provider to the two questions
+ * its backend can answer.
+ *
+ * {@code DISABLED_FLAGS} is declared. Flagsmith's native model is {@code enabled} plus a
+ * value, so the canonical set's four disabled-* flags map straight onto it.
+ *
+ * The lifecycle and event capabilities are withheld pending the run. Go's provider
+ * implements no {@code StateHandler} whatsoever; whether Java's does is the first thing this
+ * run answers, and declaring them afterwards is the correct follow-up. Withholding a capability
+ * a provider genuinely has is the expensive mistake, because it makes the suite blind to it.
+ */
+ @Override
+ public Set