|
14 | 14 | use Workflow\Serializers\CodecRegistry; |
15 | 15 | use Workflow\V2\Support\PlatformConformanceSuite; |
16 | 16 | use Workflow\V2\Support\PlatformProtocolSpecs; |
| 17 | +use Workflow\V2\Support\SdkNeutralityContract; |
17 | 18 | use Workflow\V2\Support\SurfaceStabilityContract; |
18 | 19 | use Workflow\V2\Support\WorkerProtocolVersion; |
19 | 20 |
|
@@ -160,6 +161,20 @@ public function test_cluster_info_is_a_versionless_protocol_discovery_contract() |
160 | 161 | 'release_gates', |
161 | 162 | ], |
162 | 163 | 'auth_composition_contract', |
| 164 | + 'sdk_neutrality_contract' => [ |
| 165 | + 'schema', |
| 166 | + 'version', |
| 167 | + 'authority_doc', |
| 168 | + 'surface_stability_authority', |
| 169 | + 'protocol_specs_authority', |
| 170 | + 'conformance_suite_authority', |
| 171 | + 'scope', |
| 172 | + 'sdk_breadth_policy', |
| 173 | + 'neutrality_rules', |
| 174 | + 'audit_checklist', |
| 175 | + 'audit_scope_surface_families', |
| 176 | + 'release_gates', |
| 177 | + ], |
163 | 178 | 'control_plane', |
164 | 179 | 'worker_protocol', |
165 | 180 | 'bridge_adapter_outcome_contract', |
@@ -197,9 +212,74 @@ public function test_cluster_info_is_a_versionless_protocol_discovery_contract() |
197 | 212 | ->assertJsonPath( |
198 | 213 | 'platform_conformance_suite.surface_stability_authority', |
199 | 214 | SurfaceStabilityContract::SCHEMA, |
| 215 | + ) |
| 216 | + ->assertJsonPath('sdk_neutrality_contract.schema', SdkNeutralityContract::SCHEMA) |
| 217 | + ->assertJsonPath('sdk_neutrality_contract.version', SdkNeutralityContract::VERSION) |
| 218 | + ->assertJsonPath( |
| 219 | + 'sdk_neutrality_contract.surface_stability_authority', |
| 220 | + SurfaceStabilityContract::SCHEMA, |
| 221 | + ) |
| 222 | + ->assertJsonPath( |
| 223 | + 'sdk_neutrality_contract.protocol_specs_authority', |
| 224 | + PlatformProtocolSpecs::SCHEMA, |
| 225 | + ) |
| 226 | + ->assertJsonPath( |
| 227 | + 'sdk_neutrality_contract.conformance_suite_authority', |
| 228 | + PlatformConformanceSuite::SCHEMA, |
200 | 229 | ); |
201 | 230 | } |
202 | 231 |
|
| 232 | + public function test_cluster_info_publishes_the_canonical_sdk_neutrality_contract(): void |
| 233 | + { |
| 234 | + $response = $this->getJson('/api/cluster/info')->assertOk(); |
| 235 | + |
| 236 | + $this->assertSame( |
| 237 | + SdkNeutralityContract::manifest(), |
| 238 | + $response->json('sdk_neutrality_contract'), |
| 239 | + 'cluster info must re-export the workflow package SDK neutrality manifest verbatim', |
| 240 | + ); |
| 241 | + |
| 242 | + $rules = $response->json('sdk_neutrality_contract.neutrality_rules'); |
| 243 | + $this->assertIsArray($rules); |
| 244 | + foreach ([ |
| 245 | + 'protocol_neutrality', |
| 246 | + 'codec_neutrality', |
| 247 | + 'error_shape_neutrality', |
| 248 | + 'type_identity_neutrality', |
| 249 | + 'replay_fixture_neutrality', |
| 250 | + 'discovery_neutrality', |
| 251 | + 'documentation_neutrality', |
| 252 | + ] as $expectedRule) { |
| 253 | + $this->assertArrayHasKey( |
| 254 | + $expectedRule, |
| 255 | + $rules, |
| 256 | + "sdk_neutrality_contract.neutrality_rules must include $expectedRule", |
| 257 | + ); |
| 258 | + } |
| 259 | + |
| 260 | + $policy = $response->json('sdk_neutrality_contract.sdk_breadth_policy'); |
| 261 | + $this->assertSame( |
| 262 | + SdkNeutralityContract::POSTURE_PRIORITY, |
| 263 | + $policy['first_party']['php_workflow_package']['posture'], |
| 264 | + ); |
| 265 | + $this->assertSame( |
| 266 | + SdkNeutralityContract::POSTURE_PRIORITY, |
| 267 | + $policy['first_party']['python_sdk']['posture'], |
| 268 | + 'python SDK is the highest-value non-PHP first-party priority', |
| 269 | + ); |
| 270 | + foreach (['typescript_sdk', 'go_sdk', 'java_sdk', 'dotnet_sdk'] as $demandDriven) { |
| 271 | + $this->assertArrayHasKey( |
| 272 | + $demandDriven, |
| 273 | + $policy['demand_driven'], |
| 274 | + "sdk_breadth_policy.demand_driven must include $demandDriven", |
| 275 | + ); |
| 276 | + $this->assertSame( |
| 277 | + SdkNeutralityContract::POSTURE_DEMAND_DRIVEN, |
| 278 | + $policy['demand_driven'][$demandDriven]['posture'], |
| 279 | + ); |
| 280 | + } |
| 281 | + } |
| 282 | + |
203 | 283 | public function test_cluster_info_publishes_the_canonical_surface_stability_contract(): void |
204 | 284 | { |
205 | 285 | $response = $this->getJson('/api/cluster/info')->assertOk(); |
|
0 commit comments