Skip to content

Commit ff00fa5

Browse files
[cross-repo from workflow#159] GitHub #692: Future work: preserve protocol neutrality for possible SDKs beyond PHP and Python (#129)
1 parent 0c3d659 commit ff00fa5

2 files changed

Lines changed: 85 additions & 0 deletions

File tree

app/Http/Controllers/Api/HealthController.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Workflow\Serializers\CodecRegistry;
2020
use Workflow\V2\Support\PlatformConformanceSuite;
2121
use Workflow\V2\Support\PlatformProtocolSpecs;
22+
use Workflow\V2\Support\SdkNeutralityContract;
2223
use Workflow\V2\Support\StandaloneWorkerVisibility;
2324
use Workflow\V2\Support\StructuralLimits;
2425
use Workflow\V2\Support\SurfaceStabilityContract;
@@ -157,6 +158,10 @@ public function clusterInfo(Request $request): JsonResponse
157158
$response['embedded_v2_import_contract'] = $embeddedV2ImportContract::manifest();
158159
}
159160

161+
if (class_exists(SdkNeutralityContract::class)) {
162+
$response['sdk_neutrality_contract'] = SdkNeutralityContract::manifest();
163+
}
164+
160165
if ($serviceExecutionAvailable) {
161166
$response['service_execution_contract'] = $serviceExecutionContract::manifest();
162167
}

tests/Feature/ClusterInfoCompatibilityTest.php

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Workflow\Serializers\CodecRegistry;
1515
use Workflow\V2\Support\PlatformConformanceSuite;
1616
use Workflow\V2\Support\PlatformProtocolSpecs;
17+
use Workflow\V2\Support\SdkNeutralityContract;
1718
use Workflow\V2\Support\SurfaceStabilityContract;
1819
use Workflow\V2\Support\WorkerProtocolVersion;
1920

@@ -160,6 +161,20 @@ public function test_cluster_info_is_a_versionless_protocol_discovery_contract()
160161
'release_gates',
161162
],
162163
'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+
],
163178
'control_plane',
164179
'worker_protocol',
165180
'bridge_adapter_outcome_contract',
@@ -197,9 +212,74 @@ public function test_cluster_info_is_a_versionless_protocol_discovery_contract()
197212
->assertJsonPath(
198213
'platform_conformance_suite.surface_stability_authority',
199214
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,
200229
);
201230
}
202231

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+
203283
public function test_cluster_info_publishes_the_canonical_surface_stability_contract(): void
204284
{
205285
$response = $this->getJson('/api/cluster/info')->assertOk();

0 commit comments

Comments
 (0)