Provider guarantees and features
Identity guarantees, supported integrations, and operator-controlled feature policies.
A provider tells Identica two things about itself: what it guarantees about its identities, and which features it works with. Operators then choose, per provider, which features are used.
Provider guarantees
IdenticaProvider.guarantees() returns Set<ProviderGuarantee>. A guarantee states what the implementation guarantees about its identities. It is not an operator toggle, and username conflict rules match on it.
ProviderGuarantee.OWNED_USERNAME means the provider owns its players' usernames: no two of its players hold one at once, and it verifies that a player owns the name they join with. Identica follows that name for the account the provider is the primary link of, unless an administrator set it by hand. Premium declares this guarantee. Credential does not. Provider configuration cannot grant a guarantee.
Usernames are core behavior, not a feature, and are never listed in supportedFeatures(). See Usernames and conflicts for what operators see.
Conflict outcomes
Conflicts between two accounts over something only one may have go through ConflictService in me.whereareiam.identica.conflict. A kind of conflict, such as UsernameConflict.KIND, keeps its rules in its own document; the service finds the most specific rule that applies and the outcome the rule names. Outcomes are registered by id with their settings, so an addon or provider can add its own, either with ConflictService.register or by returning them from IdenticaProvider.conflictOutcomes(), which registers them while the provider is enabled. An outcome only decides what each side keeps; none lets a player into another account.
public final class LongestPlaytimeOutcome implements ConflictOutcome<UsernameConflict, UsernameConflictDecision, LongestPlaytime> {
@Override
public ConflictKind<UsernameConflict, UsernameConflictDecision> kind() {
return UsernameConflict.KIND;
}
@Override
public String id() {
return "longest-playtime";
}
@Override
public Class<LongestPlaytime> settingsType() {
return LongestPlaytime.class;
}
@Override
public LongestPlaytime defaults() {
return new LongestPlaytime();
}
@Override
public UsernameConflictDecision decide(UsernameConflict conflict, LongestPlaytime settings) {
return playtime.longer(conflict.getSituation())
? UsernameConflictDecision.renameHolder(settings.getHolderRename())
: UsernameConflictDecision.renameArriving(settings.getRename());
}
}An outcome has an id in lowercase kebab case, a typed settings model and its defaults. Once it is registered, Identica writes the defaults under outcomes.longest-playtime; an administrator changes them there, under providers.<provider>.longest-playtime, or on one rule, and a rule names it with outcome: longest-playtime. actsOn() tells which side's provider settings apply.
Supported features
IdenticaProvider.supportedFeatures() returns the feature IDs the provider integrates with. Support is declared by the provider developer; enablement is chosen by the operator. Declaring support does not activate the feature or override configuration.
@Override
public Set<ProviderGuarantee> guarantees() {
return Set.of(ProviderGuarantee.OWNED_USERNAME);
}
@Override
public Set<String> supportedFeatures() {
return Set.of("recognition", "verification", "restriction", "restriction-join");
}Providers expose a no-argument constructor so the loader can inspect their declarations before injection. Declarations must not rely on injected services. Declaring an unknown feature prevents that provider from loading. Explicitly enabling a known feature that the provider does not support also produces a provider loading error.
Checking whether a feature is on
Operators set each feature globally and per provider, as described in Features.
FeatureRegistry.isEnabled(providerId, featureId) combines declared support and the effective enable policy. isAvailable(featureId) only describes compiled availability and is not a check for operator enablement. Provider integrations must use the former when deciding whether to execute optional behavior.
Verification's global provider policy is defaults in features/verification/settings. Recognition and sentinel use their settings' enabled value. Restriction has its own enabled default; join restriction adds enabled and allow in features/restriction/join/settings. Disabling the enclosing features.restriction.enabled switch also disables join restriction for that provider.
Protected actions evaluate verification for the current session's provider. A target provider's settings must not bypass the source session's verification policy.
