astraform-conformance 0.3.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. astraform_conformance-0.3.5/PKG-INFO +385 -0
  2. astraform_conformance-0.3.5/README.md +361 -0
  3. astraform_conformance-0.3.5/pyproject.toml +53 -0
  4. astraform_conformance-0.3.5/setup.cfg +4 -0
  5. astraform_conformance-0.3.5/setup.py +24 -0
  6. astraform_conformance-0.3.5/src/astraform/remote_domain/conformance/__init__.py +47 -0
  7. astraform_conformance-0.3.5/src/astraform/remote_domain/conformance/__main__.py +5 -0
  8. astraform_conformance-0.3.5/src/astraform/remote_domain/conformance/_contract/contracts/remote-domain.v1.lock.json +9 -0
  9. astraform_conformance-0.3.5/src/astraform/remote_domain/conformance/_contract/contracts/remote-domain.v1.snapshot.json +80 -0
  10. astraform_conformance-0.3.5/src/astraform/remote_domain/conformance/_contract/resources.json +17 -0
  11. astraform_conformance-0.3.5/src/astraform/remote_domain/conformance/_contract/samples/conformance-vectors.json +66 -0
  12. astraform_conformance-0.3.5/src/astraform/remote_domain/conformance/_contract/samples/finalized-summary.json +1 -0
  13. astraform_conformance-0.3.5/src/astraform/remote_domain/conformance/_contract/samples/rfc8785-ijson-number-vectors.json +53 -0
  14. astraform_conformance-0.3.5/src/astraform/remote_domain/conformance/_contract/schemas/domain-outcome-scorecard-roles.v1.schema.json +53 -0
  15. astraform_conformance-0.3.5/src/astraform/remote_domain/conformance/_contract/schemas/native-reference-state.schema.json +356 -0
  16. astraform_conformance-0.3.5/src/astraform/remote_domain/conformance/_contract/schemas/native-state-transform.schema.json +385 -0
  17. astraform_conformance-0.3.5/src/astraform/remote_domain/conformance/_contract/schemas/opportunity-worker-conformance-report.schema.json +104 -0
  18. astraform_conformance-0.3.5/src/astraform/remote_domain/conformance/_contract/schemas/opportunity-worker-profile.schema.json +46 -0
  19. astraform_conformance-0.3.5/src/astraform/remote_domain/conformance/_contract/schemas/remote-domain.schema.json +902 -0
  20. astraform_conformance-0.3.5/src/astraform/remote_domain/conformance/_contract/schemas/scenario-lab-finalization-conformance-vectors.schema.json +298 -0
  21. astraform_conformance-0.3.5/src/astraform/remote_domain/conformance/_contract/schemas/scenario-lab-finalization-receipt.schema.json +241 -0
  22. astraform_conformance-0.3.5/src/astraform/remote_domain/conformance/cli.py +236 -0
  23. astraform_conformance-0.3.5/src/astraform/remote_domain/conformance/py.typed +1 -0
  24. astraform_conformance-0.3.5/src/astraform/remote_domain/conformance/runner.py +4410 -0
  25. astraform_conformance-0.3.5/src/astraform_conformance.egg-info/PKG-INFO +385 -0
  26. astraform_conformance-0.3.5/src/astraform_conformance.egg-info/SOURCES.txt +29 -0
  27. astraform_conformance-0.3.5/src/astraform_conformance.egg-info/dependency_links.txt +1 -0
  28. astraform_conformance-0.3.5/src/astraform_conformance.egg-info/entry_points.txt +2 -0
  29. astraform_conformance-0.3.5/src/astraform_conformance.egg-info/requires.txt +10 -0
  30. astraform_conformance-0.3.5/src/astraform_conformance.egg-info/top_level.txt +1 -0
  31. astraform_conformance-0.3.5/tests/test_runner.py +2990 -0
@@ -0,0 +1,385 @@
1
+ Metadata-Version: 2.4
2
+ Name: astraform-conformance
3
+ Version: 0.3.5
4
+ Summary: Conformance runner for Astraform domain providers using remote-domain.v1
5
+ License-Expression: Apache-2.0
6
+ Project-URL: Documentation, https://astraform.ai/python-quickstart#step-4
7
+ Project-URL: Source, https://github.com/astraform/sdk-python
8
+ Project-URL: Publishing, https://github.com/astraform/sdk-python#readme
9
+ Keywords: astraform,domain-provider,simulation,conformance
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Classifier: Typing :: Typed
13
+ Requires-Python: >=3.12
14
+ Description-Content-Type: text/markdown
15
+ Requires-Dist: httpx<1.0,>=0.28
16
+ Requires-Dist: anyio<5.0,>=4.14.2
17
+ Requires-Dist: jsonschema<5.0,>=4.23
18
+ Requires-Dist: cryptography<51.0,>=50.0.0
19
+ Requires-Dist: rfc8785==0.1.4
20
+ Provides-Extra: test
21
+ Requires-Dist: fastapi<1.0,>=0.115; extra == "test"
22
+ Requires-Dist: starlette<2.0,>=1.3.1; extra == "test"
23
+ Requires-Dist: pytest<10.0,>=9.0.3; extra == "test"
24
+
25
+ # Astraform Domain Provider Conformance for Python
26
+
27
+ Version **0.3.5** is prepared with the checksum-pinned, published **1.2.3**
28
+ (`v1.2.3`) provider contract. Install this version after publication, or build
29
+ from the checkout beforehand. Published 0.3.4 keeps its 1.2.2 contracts.
30
+ The provider wire protocol remains **`remote-domain.v1`**.
31
+
32
+ The validation tool is distributed as `astraform-conformance`, replacing
33
+ `astraform-remote-domain-conformance`. The platform client and provider helpers
34
+ are supplied by the separate `astraform-sdk` distribution.
35
+ Existing Python imports and CLI commands are unchanged. See the
36
+ [0.3.5 release notes](https://github.com/astraform/sdk-python/blob/main/docs/releases/0.3.5.md)
37
+ for upgrade guidance.
38
+
39
+ This is the reusable conformance harness for Python domain providers using
40
+ `remote-domain.v1`.
41
+
42
+ Use it to validate your provider's protocol behavior before connecting the
43
+ service to Astraform.
44
+
45
+ This package exercises the real lifecycle:
46
+
47
+ - `manifest`
48
+ - `prepare`
49
+ - `status`
50
+ - `execute-work`
51
+ - `inspection`
52
+ - `shutdown`
53
+
54
+ It validates payloads against the exact embedded `remote-domain.v1` contract
55
+ release resolved automatically during package builds. The package includes its
56
+ release lock and provenance under `_contract/contracts/`; a
57
+ `LOCAL_PRERELEASE` snapshot is distinguishable from the published baseline.
58
+
59
+ It also includes a lightweight remote Policy Wind Tunnel provider conformance
60
+ path for `/policy-wind-tunnel/...` routes. That path checks pack metadata,
61
+ domain/report labels, `outcomeSchema`, CEL-compatible `policyExpressions`,
62
+ presets, run creation, status, lifecycle control, the generic
63
+ `policy_wind_tunnel_bundle.v1` envelope, artifact, and evidence-pack
64
+ availability. A weak bundle that only returns `schemaVersion` and `runId` is
65
+ not conformant; it must expose the
66
+ domain, pack, preset, branches, metrics, segments, timeline, decision gates,
67
+ artifacts, and domain payload that the dashboard and outcome report can render
68
+ without custom frontend code.
69
+
70
+ ## Install
71
+
72
+ Version **0.3.2** hardens response correlation, JSON structure, finalization
73
+ artifact collections and native/scorecard validation. See the
74
+ [resource and response limits](#conformance-resource-and-response-integrity-limits)
75
+ for intentional rejection boundaries and configurable artifact/role budgets.
76
+ Its package and harness versions follow the SDK patch release. Version
77
+ **0.3.5** includes the **1.2.3** contract and both native profile schemas. Python
78
+ **3.12+** is required.
79
+ This validation tool is installed separately from the SDK; it is not a
80
+ runtime dependency of domain services or simulation launchers. The
81
+ `remote-domain-conformance` command is unchanged.
82
+
83
+ The [PyPI package page](https://pypi.org/project/astraform-conformance/)
84
+ lists published versions.
85
+ Install it with:
86
+
87
+ ```bash
88
+ python -m pip install astraform-conformance==0.3.5
89
+ ```
90
+ When upgrading from 0.3.4 or older, uninstall the old distribution first. Both
91
+ distributions provide the same Python modules and must not be installed together:
92
+
93
+ ```bash
94
+ python -m pip uninstall astraform-remote-domain-conformance
95
+ python -m pip install astraform-conformance==0.3.5
96
+ ```
97
+
98
+ Update dependency declarations and regenerate application locks. Published
99
+ 0.3.4 and older releases retain the original distribution name.
100
+
101
+
102
+ See the [0.3.2 release notes](https://github.com/astraform/sdk-python/blob/main/docs/releases/0.3.2.md)
103
+ (repository access required).
104
+ Repository-local development resolves published contract 1.2.3:
105
+
106
+ ```bash
107
+ pip install -e './conformance-python[test]'
108
+ ```
109
+
110
+ ## Run Against A Live Service
111
+
112
+ ```bash
113
+ remote-domain-conformance \
114
+ --base-url http://localhost:8092 \
115
+ --domain-id my-domain
116
+ ```
117
+
118
+ Require Population Builder catalog conformance:
119
+
120
+ ```bash
121
+ remote-domain-conformance \
122
+ --base-url http://localhost:8092 \
123
+ --domain-id my-domain \
124
+ --population-catalog
125
+ ```
126
+
127
+ Validate a catalog file before the provider serves it:
128
+
129
+ ```bash
130
+ remote-domain-conformance \
131
+ --domain-id my-domain \
132
+ --population-catalog-file ./population_catalog.json
133
+ ```
134
+
135
+ ## Run Against A Local ASGI App
136
+
137
+ ```bash
138
+ remote-domain-conformance \
139
+ --app my_remote_domain.main:app \
140
+ --domain-id my-domain
141
+ ```
142
+
143
+ Baseline conformance performs the published v1 lifecycle once. To prove the
144
+ stronger async worker transport/effect boundary, pass an explicit out-of-band
145
+ profile:
146
+
147
+ ```bash
148
+ remote-domain-conformance \
149
+ --app my_remote_domain.main:app \
150
+ --domain-id my-domain \
151
+ --opportunity-worker-profile conformance/opportunity-worker-profile.json \
152
+ --provider-artifact-digest "sha256:<64 lowercase hex characters>" \
153
+ > build/conformance-run-report.json
154
+ ```
155
+
156
+ Extract the nested `opportunityWorkerConformanceReport`, then sign that file in
157
+ a separate protected job which runs no provider or repository code:
158
+
159
+ ```bash
160
+ remote-domain-conformance \
161
+ --sign-conformance-report build/opportunity-worker-conformance-report.json \
162
+ --opportunity-worker-profile conformance/opportunity-worker-profile.json \
163
+ --attestation-private-key /secure/release-ed25519-private-key.pem \
164
+ --attestation-key-id partner-release \
165
+ --attestation-output build/opportunity-worker-attestation.dsse.json
166
+ ```
167
+
168
+ The protected signer recomputes the supplied profile digest and requires
169
+ exactly one matching passing result for every classified tool. The signed
170
+ `conformanceReportDigest` covers the report's passing baseline
171
+ lifecycle, cross-attempt replay, and per-tool probe outcomes, plus its exact OCI
172
+ subject binding. The public report schema is shipped in the opportunity-worker
173
+ contract profile. Release automation must fail when the protected signer is
174
+ unavailable; an ephemeral-key fallback is not a release proof.
175
+
176
+ The profile schema version is
177
+ `remote_domain_opportunity_worker_conformance_profile.v1`; it contains exact
178
+ `toolEffects`, one safe probe per tool, and optional `personaConfiguration`.
179
+ It is not part of the `remote-domain.v1` manifest schema.
180
+
181
+ Worker-profile responses are consumed from `response.content`, not decoded
182
+ response text. Before a passing report can exist, the runner requires one exact
183
+ JSON Content-Type, strict UTF-8, valid Unicode scalar text without U+0000,
184
+ unique object keys, one JSON value, and lossless I-JSON/RFC 8785 numbers. Signed
185
+ worker proof binds protocol responses to the manifest-advertised media type;
186
+ the historical `application/json` fallback remains baseline-v1 compatibility
187
+ only.
188
+
189
+ ## Native Profile Metadata
190
+
191
+ The native state-transform and reference-state schemas introduced in 0.2.0
192
+ remain included in SDK **0.3.4**, from published contract **1.2.2**.
193
+ Checkout builds include those schemas from contract **1.2.3**.
194
+ SDK 0.3.3 uses contract 1.2.1; SDK 0.3.2 retains the original contract 1.2.0 inputs.
195
+ The existing manifest validation accepts both `capabilities.nativeSimulation`
196
+ profiles and validates complete customer-scoped read-only tool descriptors.
197
+ Legacy manifests remain supported.
198
+
199
+ Validate a native metadata object with the existing validator:
200
+
201
+ ```python
202
+ from astraform.remote_domain.conformance.runner import RemoteDomainSchemaValidator
203
+
204
+ validator = RemoteDomainSchemaValidator()
205
+ validator.validate("manifest", provider_manifest)
206
+ validator.validate_native(
207
+ "remote-domain.native-reference-state.v1",
208
+ "stateMetadata",
209
+ provider_checkpoint["data"]["nativeSimulation"],
210
+ )
211
+ ```
212
+
213
+ The definition selects the exact canonical `$defs` entry: for example `manifest`,
214
+ `prepareHints`, `windowContext`, `stateMetadata` or `resultMetadata`. The
215
+ reference-state profile also supplies `customerContext`, `readContext` and
216
+ `checkpoint`; the pure-state profile supplies `readOnlyToolDescriptor` and
217
+ `readOnlyToolPayload`. Unknown profiles and definitions fail explicitly.
218
+
219
+ These checks validate wire shape and scope metadata. They do not prove native
220
+ transaction atomicity, restart recovery, customer authorization, or complete
221
+ native simulation behavior. The generic lifecycle CLI does not become native
222
+ execution certification merely because it accepts a native manifest.
223
+
224
+ ## Run Policy Wind Tunnel Provider Conformance
225
+
226
+ ```bash
227
+ remote-domain-conformance \
228
+ --wind-tunnel \
229
+ --base-url http://localhost:8092 \
230
+ --pack-id my-domain-policy-pack \
231
+ --preset-id conformance-proof
232
+ ```
233
+
234
+ When the pack advertises
235
+ `opportunityGenerationFinalizationMode=PLATFORM_OWNED_V2`, the wind-tunnel
236
+ runner automatically executes a clock-driven V2 probe. It pins the immutable
237
+ provider revision, cancels a generated run, finalizes it with a stable operation
238
+ ID, validates the strict receipt schema, downloads and hashes every declared
239
+ artifact, proves an exact replay, and rejects contradictory reuse of the
240
+ operation ID.
241
+
242
+ V2 conformance requires a `ScenarioLabFinalizationV2ProbeDriver` backed by real
243
+ OS processes. The driver supplies a started `subprocess.Popen` handle bound to
244
+ the provider base URL under test, exposes
245
+ the durable PREPARED receipt and artifact bytes, terminates the original
246
+ provider, and launches a distinct process against the same durable state. The
247
+ harness independently verifies that the old process exited and its endpoint is
248
+ unavailable before accepting the replacement PID, then requires the replacement
249
+ process to publish the byte-equivalent canonical `/pack` identity. Legacy V1
250
+ coverage is provisioned out of band as recovery state; the harness never launches
251
+ a fresh `PLATFORM_OWNED_V1` run. The driver also runs two distinct child processes
252
+ against the configured receipt/artifact store so the harness can verify lock
253
+ exclusion, cross-process visibility, and atomic publication. Both the successful
254
+ and terminal-precedence paths cross a real process restart. Completion delivery
255
+ is failed once deliberately and must retry independently without another
256
+ `FINALIZE` request. The harness also injects each
257
+ published artifact and receipt fault through the driver and verifies rejection
258
+ through the provider HTTP boundary; an in-process ASGI app swap or a relabelled
259
+ process is not restart proof.
260
+
261
+ ## Python Usage
262
+
263
+ ```python
264
+ import asyncio
265
+
266
+ from astraform.remote_domain.conformance.runner import ConformanceScenario
267
+ from astraform.remote_domain.conformance.runner import OpportunityWorkerConformanceProfile
268
+ from astraform.remote_domain.conformance.runner import PolicyWindTunnelConformanceScenario
269
+ from astraform.remote_domain.conformance.runner import ToolProbe
270
+ from astraform.remote_domain.conformance.runner import run_conformance
271
+ from astraform.remote_domain.conformance.runner import run_opportunity_worker_conformance
272
+ from astraform.remote_domain.conformance.runner import run_policy_wind_tunnel_conformance
273
+
274
+
275
+ report = asyncio.run(
276
+ run_conformance(
277
+ base_url="http://localhost:8092",
278
+ scenario=ConformanceScenario(domain_id="my-domain"),
279
+ )
280
+ )
281
+
282
+ print(report.to_dict())
283
+
284
+ worker_report = asyncio.run(
285
+ run_opportunity_worker_conformance(
286
+ base_url="http://localhost:8092",
287
+ scenario=ConformanceScenario(domain_id="my-domain"),
288
+ profile=OpportunityWorkerConformanceProfile(
289
+ tool_effects={"lookup_case": "READ_ONLY"},
290
+ tool_probes=(ToolProbe("lookup_case", {"caseId": "case-1"}),),
291
+ ),
292
+ provider_artifact_digest="sha256:<64 lowercase hex characters>",
293
+ )
294
+ )
295
+
296
+ wind_tunnel_report = asyncio.run(
297
+ run_policy_wind_tunnel_conformance(
298
+ base_url="http://localhost:8092",
299
+ scenario=PolicyWindTunnelConformanceScenario(
300
+ pack_id="my-domain-policy-pack",
301
+ preset_id="conformance-proof",
302
+ ),
303
+ )
304
+ )
305
+
306
+ print(wind_tunnel_report.to_dict())
307
+ ```
308
+
309
+ ## Publishing Status
310
+
311
+ Release validation starts with the standalone package tests:
312
+
313
+ ```bash
314
+ pytest sdk-python/tests conformance-python/tests
315
+ ```
316
+
317
+ PyPI artifacts are immutable. Do not rerun a publish for an already published
318
+ version; run smoke-only verification or bump the SDK version.
319
+
320
+ Public package note: PyPI distributions expose this SDK implementation. Keep
321
+ host runtime internals and domain-private logic out of this package.
322
+
323
+
324
+ ### HTTP safety limits
325
+
326
+ All provider calls stay on the configured HTTP(S) origin. Advertised operation
327
+ paths must be relative paths; absolute URLs, authority paths (`//host/path`),
328
+ backslashes, fragments and control/space characters are rejected before lifecycle
329
+ operations start. Redirects are never followed. Localhost, private-network URLs
330
+ and base URLs mounted under a path remain supported.
331
+
332
+ The Python runners accept `limits=ConformanceHttpLimits(...)` (exported from
333
+ `astraform.remote_domain.conformance`). Defaults are 4 MiB per JSON response,
334
+ 64 MiB per artifact/evidence-pack response, and a 30-second total deadline per
335
+ HTTP request, including headers and streamed body. The same settings apply to
336
+ polling, tool probes and restart requests. CLI equivalents are `--max-json-bytes`,
337
+ `--max-artifact-bytes` and `--request-timeout-seconds`. Limits must be positive;
338
+ the deadline must also be finite. The deadline is per request, not for a full run.
339
+
340
+ The runner requests `Accept-Encoding: identity` and rejects HTTP content
341
+ compression before reading the body, preventing decompression from bypassing the
342
+ byte limit. Providers must honor this request. ZIP artifacts are still supported
343
+ as ordinary `application/zip` bytes. Both successful and error responses are
344
+ bounded; exceeding a limit or hitting an HTTP transport timeout is a conformance
345
+ failure, never successful crash or restart evidence. Connection-refused and
346
+ disconnect errors remain available to the existing restart checks.
347
+
348
+ Imported `app=` implementations, custom transports and restart probe drivers run
349
+ trusted Python in the harness process. In particular, HTTPX's ASGI transport
350
+ buffers local app output before returning it; these limits do not sandbox local
351
+ Python code or bound memory allocated inside that app. Use a separate provider
352
+ process with `base_url=` to enforce the streamed network response boundary.
353
+
354
+ ### Conformance resource and response integrity limits
355
+
356
+ Conformance treats the selected provider's responses as untrusted protocol data.
357
+ Every lifecycle, replay and tool envelope must echo the originating request ID
358
+ exactly; a successful schema check cannot substitute for that correlation.
359
+
360
+ JSON parsing and public canonicalization enforce a structural budget before
361
+ recursive normalization or RFC 8785 serialization: maximum depth 64, 100,000
362
+ values/property names, and 4,096 characters per property name. These limits
363
+ apply to arrays as well as objects. Diagnostics display at most 256 path
364
+ characters plus an ellipsis; payloads are rejected, never truncated.
365
+
366
+ The existing ConformanceHttpLimits additionally accepts
367
+ max_finalization_artifacts (64), max_finalization_total_bytes (128 MiB), and
368
+ max_scorecard_roles (256). CLI flags use the corresponding hyphenated names.
369
+ All three are positive integer limits. Existing first-three positional arguments
370
+ retain their meaning.
371
+
372
+ V2 collectors reject excessive counts and declared aggregate lengths before
373
+ fetching or reading prepared artifacts, then enforce actual byte totals.
374
+ PUBLISHED verification does not retain a full collection, and restart comparison
375
+ checks one response at a time against the original bounded snapshots rather
376
+ than retaining another collection. A comparison can hold the original bounded
377
+ collection and one bounded response at once; HTTP buffering has a bounded
378
+ temporary copy. Zero-byte artifacts remain valid. The trusted probe driver
379
+ returns already allocated bytes; these limits cannot sandbox allocation inside
380
+ that operator-provided driver.
381
+
382
+ Scorecard role counts are checked before schema evaluation; duplicates remain
383
+ forbidden by exact scorecard ID and catalog coverage. Native manifests reject
384
+ non-string, oversized or overlong workKinds before uniqueness validation,
385
+ including standalone native-profile validation.