lawspec 0.9.0 → 0.11.0

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 (46) hide show
  1. package/API-MIGRATION.md +78 -2
  2. package/HASKELL.md +1 -0
  3. package/KOTLIN.md +5 -0
  4. package/LANGUAGE.md +70 -11
  5. package/NATIVE-BINDINGS.md +1049 -0
  6. package/PRIMITIVES.md +1 -1
  7. package/README.md +86 -23
  8. package/REFINEMENTS.md +6 -1
  9. package/RELEASE-0.10.md +60 -0
  10. package/RELEASE-0.11.md +62 -0
  11. package/api.mjs +23 -3
  12. package/bin/lawspec.mjs +17 -4
  13. package/build.json +60 -38
  14. package/core.wasm +0 -0
  15. package/examples/native-payments/go/example/payments/domain.go +38 -0
  16. package/examples/native-payments/go/example/payments/native_generators_test.go +13 -0
  17. package/examples/native-payments/go/lawspec.json +136 -0
  18. package/examples/native-payments/haskell/lawspec.json +149 -0
  19. package/examples/native-payments/haskell/src/PaymentsDomain.hs +21 -0
  20. package/examples/native-payments/haskell/test/PaymentGenerators.hs +12 -0
  21. package/examples/native-payments/java/lawspec.json +165 -0
  22. package/examples/native-payments/java/src/main/java/domain/PaymentsDomain.java +32 -0
  23. package/examples/native-payments/java/src/test/java/domain/PaymentGenerators.java +16 -0
  24. package/examples/native-payments/javascript/lawspec.json +149 -0
  25. package/examples/native-payments/javascript/src/payments_domain.mjs +44 -0
  26. package/examples/native-payments/javascript/test/lawspec_generators.mjs +6 -0
  27. package/examples/native-payments/kotlin/lawspec.json +165 -0
  28. package/examples/native-payments/kotlin/src/main/kotlin/domain/PaymentsDomain.kt +17 -0
  29. package/examples/native-payments/kotlin/src/test/kotlin/domain/PaymentGenerators.kt +12 -0
  30. package/examples/native-payments/python/lawspec.json +149 -0
  31. package/examples/native-payments/python/src/payments_domain.py +60 -0
  32. package/examples/native-payments/python/tests/lawspec_generators.py +15 -0
  33. package/examples/native-payments/rust/lawspec.json +167 -0
  34. package/examples/native-payments/rust/src/domain.rs +37 -0
  35. package/examples/native-payments/rust/src/lib.rs +2 -0
  36. package/examples/native-payments/rust/tests/support/lawspec_generators.rs +11 -0
  37. package/examples/native-payments/typescript/lawspec.json +149 -0
  38. package/examples/native-payments/typescript/src/payments_domain.ts +42 -0
  39. package/examples/native-payments/typescript/test/lawspec_generators.ts +8 -0
  40. package/examples/specs/indexed_families.lawspec +59 -0
  41. package/examples/specs/payments.lawspec +76 -0
  42. package/examples-command.mjs +5 -0
  43. package/files.mjs +6 -6
  44. package/index.d.ts +53 -2
  45. package/native-examples.mjs +81 -0
  46. package/package.json +2 -2
@@ -0,0 +1,1049 @@
1
+ # Native domain bindings: 0.10 acceptance scope
2
+
3
+ Status: implementation and local acceptance complete; remote CI remains pending. The payment example now executes with
4
+ compiler-generated Rust bridges and application-library linkage. Rust supports
5
+ generic products/sums, regular recursive mappings, nested built-in containers,
6
+ and native Proptest factories that compose child strategies and retain shrinking.
7
+ Python now has checked application-class bridges with renamed fields, shared
8
+ schema validation and native Hypothesis factories. JavaScript and TypeScript
9
+ have application-class bridges and native fast-check factories.
10
+ Java now emits typed codecs for application records, sum variants and enum
11
+ constants, with native JetCheck factories. Kotlin has checked application-class
12
+ bridges and native Kotest factories. Go has checked application bridges and native Rapid factories in local or
13
+ explicitly imported packages. Haskell has application-owned types and native
14
+ Hedgehog factories. All eight targets now have custom codec-hook implementations. Full release acceptance remains incomplete. Unsupported
15
+ emission requests fail explicitly.
16
+
17
+ ## Audit of 0.9
18
+
19
+ The checked-in compiler, generated API, and WASM fingerprints agree
20
+ (`node tools/build-integrity.mjs`). The audit inspected the following boundaries:
21
+
22
+ | Boundary | Existing machinery | Missing for 0.10 |
23
+ | --- | --- | --- |
24
+ | Public request and CLI | Schema v3 requests pass sources, target, layout, machine profile, generation limits and formatting through `Api.hs` and `npm/bin/lawspec.mjs`. | Per-target external type and generator bindings, validation, public declarations and config forwarding. |
25
+ | Typed front end | Resolved declaration IDs, parameterized data declarations, constructor fields, contracts and total definitions. | Binding resolution against those identities; native names must not enter language inference or change equality. |
26
+ | Testing plan | `Testing.hs` plans finite domains, deterministic boundaries, examples and framework generation requirements. | Explicit generator selection while retaining independent examples and boundary coverage. |
27
+ | Rust | `RustData.hs` generates enums plus `IntoValue`/`FromValue`; `RustEmit.hs` checks schema values around adapter calls. | Application-owned struct/enum representations and framework strategy bindings. |
28
+ | Java | `JavaData.hs` generates domain types; `LawSpecSchema.java` exposes typed `Codec<T>` conversions with validation. | External constructors/accessors, native type selection and JetCheck generator selection. |
29
+ | Python | `PythonData.hs` generates dataclasses; `lawspec_schema.py` associates constructor metadata with native classes. | Explicit native imports and renamed fields/factories; Hypothesis strategy selection. |
30
+ | JavaScript/TypeScript | `WebData.hs` and `WebTypes.hs` generate classes and native signatures; `lawspec_schema.mjs` validates constructor identities and fields. | External classes/representations and fast-check arbitrary selection without losing shrinking. |
31
+ | Go | `GoData.hs` generates types and codecs; `lawspec_codecs.go` supplies typed checked conversions and contextual errors. | Application types, explicit field mappings and Rapid generator selection. |
32
+ | Haskell | `HaskellData.hs` generates ADTs; `LawSpecCodecs.hs` supplies compositional typed codecs. | Application modules/constructors/selectors and Hedgehog generator selection. |
33
+ | Kotlin | `KotlinData.hs` generates classes with checked schema bridges and native Kotest properties. | External classes/accessors and Kotest arbitrary selection. |
34
+ | File ownership | Source/test placement is separate from generated/user ownership; `npm/files.mjs` protects edited artifacts and reports adapter changes. | Apply these protections to binding support and generator stubs, including migration from existing adapters. |
35
+
36
+ The word “native” in 0.9 means target-language representations of LawSpec types.
37
+ It does not mean an application can configure its own pre-existing domain model.
38
+ Users can hand-write conversions in their adapters today, but the compiler does
39
+ not select or generate those conversions. Likewise, using native property
40
+ frameworks today does not provide a user-configurable generator binding.
41
+
42
+ The Rust test emitter currently includes generated source/runtime modules by
43
+ path. External-library bindings must use the application library's type identity
44
+ in tests; compiling a second copy of a runtime-backed `Decimal` creates a
45
+ different Rust type. The manual baseline recompiles the domain alongside the
46
+ fixture and therefore does not yet prove external-library linkage.
47
+
48
+ The first implementation component, `LawSpec.NativeBinding`, resolves structured
49
+ native references and complete constructor/field mappings against Core. It
50
+ normalizes fields to declaration order and resolves generic generator arities.
51
+ `NativeBindingSpec` tests its validation. Public request parsing, CLI target
52
+ forwarding, generated TypeScript declarations and initial Rust emission are
53
+ implemented. Unknown binding fields are rejected. Binding requests require
54
+ schema version 4 so older schema-3 compilers reject them rather than ignoring
55
+ native representation choices. Existing requests without bindings retain
56
+ schema-3 compatibility.
57
+
58
+ ## Acceptance domain
59
+
60
+ [`payments.lawspec`](examples/specs/payments.lawspec) defines `Currency`, `Money`
61
+ and `Payment`, with adapters for fee calculation, payment round trips and archives
62
+ of optional payments. It fixes the following observable behavior:
63
+
64
+ - Adding a fee of exactly 0.2 preserves currency and arbitrary decimal precision.
65
+ - Successful and declined payments retain their variant and payload.
66
+ - Archives retain order, duplicates, empty lists and the difference between a
67
+ missing payment and a present declined payment.
68
+
69
+ The application model deliberately uses different names:
70
+
71
+ | LawSpec | Application model |
72
+ | --- | --- |
73
+ | `Currency.USD`, `.EUR`, `.GBP` | `CurrencyCode.Dollars`, `.Euros`, `.Pounds` |
74
+ | `Money` / constructor `Money` | `Price` product |
75
+ | `amount`, `currency` | `major`, `unit` |
76
+ | `Payment.Paid.value` | `PaymentStatus.Settled.price` |
77
+ | `Payment.Declined.reason` | `PaymentStatus.Rejected.explanation` |
78
+ | `addFee`, `roundTrip`, `archive` | `apply_fee`, `restore`, `store` |
79
+
80
+ The Rust application fixture is
81
+ [`domain.rs`](test/fixtures/native-payments/domain.rs). It does not import the
82
+ generated domain types. It uses LawSpec's framework-independent exact Decimal
83
+ runtime. Its hand-written adapter records the conversion work 0.10 must remove;
84
+ merely bundling that adapter does not satisfy native binding support.
85
+
86
+ Run the baseline with:
87
+
88
+ ```sh
89
+ node tools/native-payments-integration.mjs
90
+ ```
91
+
92
+ This checks/generates the model through the packaged WASM on all eight targets,
93
+ executes generated Rust properties/examples/boundaries against application types,
94
+ and confirms three deliberately broken applications fail laws rather than fail
95
+ compilation. The three mutations change the fee, erase currency and erase missing
96
+ payments. Logs and generated projects are in `.artifacts/native-payments/`.
97
+ Generation on a target is not evidence of execution on that target.
98
+
99
+ ## Current generated Rust path
100
+
101
+ `test/fixtures/native-payments/bindings.json` is the concrete configuration.
102
+ Pass it as `nativeBindings` in a schema-4 `planGeneration` request, or set
103
+ `nativeBindings` on a Rust target in `lawspec.json`. The JavaScript API selects
104
+ schema 4 automatically when that option is supplied. `check` validates binding
105
+ identities; `planGeneration` additionally checks target support.
106
+
107
+ Native references are arrays of identifier components, never code snippets.
108
+ `types` maps qualified type identities, all their constructors and all fields.
109
+ `functions` maps qualified adapter identities to application functions.
110
+ `rustCrate` names the application library for test linkage. A bound unit must
111
+ currently map every adapter; its generated bridge is compiler-owned. Existing
112
+ user adapters are protected by the ownership manifest and cannot be overwritten
113
+ silently when adopting bindings.
114
+
115
+ ```sh
116
+ LAWSPEC_CORE=/absolute/path/to/lawspec-core node tools/native-bound-payments.mjs
117
+ ```
118
+
119
+ Unlike the manual baseline, this generates every conversion from configuration,
120
+ links generated tests to the application library's runtime/data/adapter modules,
121
+ and executes both 32-bit and 64-bit semantic profiles, including a custom layout.
122
+ Total-definition bodies are compiled in the test crate against those shared
123
+ runtime types because their evaluators are crate-private. The three negative
124
+ adapters must fail executable laws. Output is in `.artifacts/native-bound-payments/`.
125
+ Generator-only native machine-sized boundaries are additionally checked by
126
+ `tools/rust-native-shapes.mjs`: the host-width profile passes and the other
127
+ profile fails contextually with an architecture mismatch.
128
+
129
+ ### Rust custom generators
130
+
131
+ Add a generator binding such as:
132
+
133
+ ```json
134
+ {"type":"example.payments::type::Money","factory":["lawspec_generators","prices"]}
135
+ ```
136
+
137
+ The application supplies `prices()` in `<testDir>/support/lawspec_generators.rs`,
138
+ returning a Proptest strategy whose values have the mapped application type.
139
+ Factories for parameterized types receive one boxed native strategy per type
140
+ argument. Generated conversions map these strategies directly, preserving their
141
+ value trees and shrinkers. Native samples and shrinks must satisfy the schema;
142
+ invalid values fail contextually. Exhausted custom strategies cannot fall back
143
+ to deterministic witnesses. Explicit examples, boundaries and finite-domain
144
+ enumeration still run independently of the custom distribution.
145
+
146
+ ```sh
147
+ LAWSPEC_CORE=/absolute/path/to/lawspec-core LAWSPEC_NATIVE_GENERATORS=1 node tools/native-bound-payments.mjs
148
+ LAWSPEC_CORE=/absolute/path/to/lawspec-core LAWSPEC_NATIVE_GENERATORS=1 node tools/rust-native-shapes.mjs
149
+ ```
150
+
151
+ The payment strategy deliberately omits several explicit examples and shrinks
152
+ to EUR 1. The shapes fixture checks generic child shrinking, recursive mappings,
153
+ empty records, refined quantifiers and finite singleton enumeration in readable
154
+ and compact output. Direct mappings currently require recursive indirection
155
+ compatible with the generated representation; alternate storage and phantom
156
+ representations still need codec-hook support.
157
+
158
+ ## Custom codec hooks
159
+
160
+ A named type can select a pair of conversion hooks instead of constructor/field
161
+ mappings. Hooks are structured function references, not embedded source code:
162
+
163
+ ```json
164
+ {
165
+ "type": "native.codecs::type::Parcel",
166
+ "native": ["crate", "domain", "Parcel"],
167
+ "codec": {
168
+ "toNative": ["crate", "codecs", "to_parcel"],
169
+ "fromNative": ["crate", "codecs", "from_parcel"]
170
+ }
171
+ }
172
+ ```
173
+
174
+ Both directions are required. Supplying constructor mappings as well is an error.
175
+ The canonical side uses generated LawSpec data types; the native side uses the
176
+ application type. For each type parameter, the hook receives a child conversion
177
+ function in that direction. Rust hooks return `lawspec_runtime::Result<T>`.
178
+ For example, `to_parcel<T, N>` takes a canonical `Parcel<T>` and `&dyn Fn(T) -> N`,
179
+ and returns `Result<domain::Parcel<N>>`. The reverse receives the native value
180
+ and `&dyn Fn(N) -> T`. Returned errors include the type identity and direction.
181
+
182
+ Hooks are application-owned source functions with no testing dependency. Schema
183
+ validation still surrounds adapter calls and native generator values; hooks cannot
184
+ remove range checks or constructor contracts. The compiler continues to select
185
+ native generators independently, preserving their shrink trees through conversions.
186
+
187
+ `test/fixtures/native-codecs` demonstrates a private-field generic product and a
188
+ recursive chain represented by a flat vector plus an explicit termination flag.
189
+ It preserves the distinction between an absent tail and a tail containing Stop.
190
+ Both profiles and output formats are compiled and executed with native/WASM
191
+ parity. Tests verify generic Proptest shrinking through the hooks, contextual
192
+ errors from either direction, and rejection of invalid codec results and native
193
+ generator samples. The source library is checked separately from test code.
194
+
195
+ ```sh
196
+ LAWSPEC_CORE=/absolute/path/to/lawspec-core node tools/rust-native-codecs.mjs
197
+ ```
198
+
199
+ Haskell hooks return `Either String value`. A generic hook has the shape:
200
+
201
+ ```haskell
202
+ toParcel :: Data.Parcel a -> (a -> b) -> Either String (Domain.Parcel b)
203
+ fromParcel :: Domain.Parcel b -> (b -> a) -> Either String (Data.Parcel a)
204
+ ```
205
+
206
+ The generated bridge keeps logical type-parameter payloads opaque and supplies
207
+ checked child converters. Hooks must use those converters to cross between the
208
+ logical payload and the application's native payload. The enclosing codec retains
209
+ schema validation and the example's Symbol context. Hook errors identify the type
210
+ and conversion direction.
211
+
212
+ `bindings-haskell.json` and the Haskell modules in `test/fixtures/native-codecs`
213
+ exercise private products, a flattened recursive representation, nested generic
214
+ payloads and refined fields. The integration checks source compilation with test
215
+ packages hidden, both machine profiles, both output formats, custom layouts and
216
+ native/WASM parity. A failing generic property retains Hedgehog shrinking to a
217
+ payload of 61. Invalid hook results and native generator samples fail contextually.
218
+
219
+ ```sh
220
+ LAWSPEC_CORE=/absolute/path/to/lawspec-core LAWSPEC_GHC=/absolute/path/to/ghc node tools/haskell-native-codecs.mjs
221
+ ```
222
+
223
+ Python hooks return the converted value and raise an exception on failure. For
224
+ example, `to_parcel(value, convert_item)` receives a generated canonical
225
+ `ParcelParcel` and returns the application's `Parcel`; `from_parcel` reverses
226
+ that conversion. Generic hooks use each directional child converter when moving
227
+ payloads between canonical and native representations. Unlike Haskell's opaque
228
+ payload bridge, Python supplies canonical native payloads to these converters.
229
+
230
+ The Python bridge checks the declared native class, validates canonical results,
231
+ and wraps hook exceptions with the type identity and direction. Hooks compose
232
+ with direct field mappings, preserve the shared Symbol context and do not import
233
+ Hypothesis. The `codec_domain.py`, `codec_hooks.py` and `codec_generators.py`
234
+ fixtures exercise private storage, flattened recursion and nested generic values.
235
+ The integration checks source execution with site packages disabled, native/WASM
236
+ parity, all profile/format combinations, custom layouts and Hypothesis shrinking
237
+ to 61. Faulty hooks, invalid generator samples and collapsed chain endings fail
238
+ executable tests.
239
+
240
+ ```sh
241
+ LAWSPEC_CORE=/absolute/path/to/lawspec-core node tools/python-native-codecs.mjs
242
+ ```
243
+
244
+ JavaScript and TypeScript use the same canonical-value and child-converter
245
+ interface as Python. Hooks return values or throw exceptions. The bridge checks
246
+ the declared application class, validates canonical results, and attaches type
247
+ identity and direction to errors while retaining the original cause. Hook tables
248
+ are copied when binding a schema, so later configuration mutations cannot change
249
+ its conversions.
250
+
251
+ The TypeScript fixtures use ECMAScript private fields and typed generic hook
252
+ signatures. They also transpile to JavaScript for the same executable acceptance
253
+ cases. Source code compiles independently of testing types. Both web targets
254
+ execute the private product, flattened chain and refined Positive examples under
255
+ both profiles, formats and custom layouts, with native/WASM parity. fast-check
256
+ retains child shrinking to 61. Tests reject failures in either hook direction,
257
+ invalid canonical results, invalid native generator values and collapsed endings.
258
+
259
+ ```sh
260
+ LAWSPEC_CORE=/absolute/path/to/lawspec-core node tools/web-native-codecs.mjs
261
+ ```
262
+
263
+ Java hooks use typed `java.util.function.Function` child converters. For example,
264
+ `to_parcel(Parcel<A> value, Function<A, B> convert)` returns an application-owned
265
+ `CodecDomain.Parcel<B>`. The generated bridge instantiates canonical generic
266
+ payloads as checked `LawSpecRuntime.Value` values, supplies the native child codec
267
+ methods, and validates the result against the schema. Hooks throw exceptions on
268
+ failure; the bridge adds the type identity and conversion direction while retaining
269
+ the cause. No testing library is needed by the hooks or generated source codecs.
270
+
271
+ The Java fixtures use private fields and a flattened recursive representation.
272
+ The integration compiles source independently, executes nested codec conversions,
273
+ and checks both profiles, formats and custom layouts with native/WASM parity.
274
+ The emitted JetCheck factory demonstrably shrinks generic payloads and matches
275
+ an independent run of the application generator (98 to 49 for the chosen predicate
276
+ and seed). JetCheck does not guarantee the smallest mathematical counterexample.
277
+ Incorrect hooks, invalid refined outputs, invalid generator samples and collapsed
278
+ chain endings fail executable properties/examples after successful compilation.
279
+
280
+ ```sh
281
+ LAWSPEC_CORE=/absolute/path/to/lawspec-core node tools/java-native-codecs.mjs
282
+ ```
283
+
284
+ Kotlin hooks follow the same opaque canonical-payload convention as Java, using
285
+ ordinary Kotlin function parameters. For example,
286
+ `to_parcel(value: Parcel<A>, convert: (A) -> B): CodecDomain.Parcel<B>` returns the
287
+ application type. The reverse hook receives `(B) -> A`. Both directions retain
288
+ schema validation, Symbol context, generic child codecs and contextual exceptions.
289
+ The conversion source compiles and executes without Kotest dependencies.
290
+
291
+ Kotlin's private-storage product, flattened chain, refined value and native
292
+ factories execute under both profiles, formats and custom layouts, with native/WASM
293
+ parity. The emitted generic Kotest factory retains its shrink tree (66 to 1 in the
294
+ fixture). Incorrect hooks, collapsed endings, invalid results and invalid native
295
+ samples compile before failing tests.
296
+
297
+ ```sh
298
+ LAWSPEC_CORE=/absolute/path/to/lawspec-core node tools/kotlin-native-codecs.mjs
299
+ ```
300
+
301
+ Go hooks return `(value, error)`, with generic converters represented by ordinary
302
+ function parameters. The canonical type parameters carry checked `LawSpecValue`
303
+ payloads. The bridge preserves the active Symbol context and encoder traversal
304
+ path when invoking child conversions, and wraps returned errors or panics with the
305
+ type identity and direction. Framework-independent source compiles with `go build`.
306
+
307
+ The Go fixture defines hooks in the generated canonical type's package. This lets
308
+ hooks name canonical variants without creating an import cycle. Its application
309
+ model uses private pointer-backed product storage and a flat slice representation
310
+ of the recursive chain. Both profiles, formats and custom layouts execute with
311
+ native/WASM parity. An intentionally failing property proves that the emitted
312
+ Rapid factory still shrinks its payload to 61. Faulty conversions, collapsed
313
+ endings and invalid refined results/generator values fail executable tests.
314
+
315
+ ```sh
316
+ LAWSPEC_CORE=/absolute/path/to/lawspec-core node tools/go-native-codecs.mjs
317
+ ```
318
+
319
+ The imported-model fixture in `test/fixtures/native-go-codecs` additionally places
320
+ the private application model and Rapid factories in separate packages. Local hooks
321
+ call the model's public constructors and accessors, so the application package has
322
+ no dependency on generated types. Generated codecs import only the application
323
+ model; factories remain a test dependency. This path compiles source independently
324
+ and executes the same profile/format/layout, shrinking and negative-test matrix.
325
+
326
+ ```sh
327
+ LAWSPEC_CORE=/absolute/path/to/lawspec-core node tools/go-imported-codecs.mjs
328
+ ```
329
+
330
+ All eight targets now implement codec hooks. Hooks that name generated canonical
331
+ types belong beside those types: placing them in a package that imports the
332
+ canonical package while the generated bridge imports that hook package would
333
+ create an ordinary Go import cycle.
334
+
335
+ ## Implementation contract
336
+
337
+ ### Current Python path
338
+
339
+ `test/fixtures/native-payments/bindings-python.json` maps the same payment domain
340
+ to application classes in `domain.py`. Python native references contain module
341
+ components followed by an exported class or function name. A bound unit must
342
+ map every adapter. Classes are checked by exact constructor identity; fields
343
+ are read by mapped attribute name and constructed with keyword arguments, so
344
+ keyword-only dataclasses and reordered fields work. Generic and recursive schema
345
+ traversal retains constructor predicates and canonical diagnostic field names.
346
+
347
+ `lawspec_native.py` and bound adapters are generated source files. Runtime schema
348
+ rebinding is independent of Hypothesis. Native function failures and invalid
349
+ results receive adapter context. Python integers have no architecture-sized
350
+ representation, so the semantic machine-width profile is enforced by validation.
351
+
352
+ ```sh
353
+ LAWSPEC_CORE=/absolute/path/to/lawspec-core node tools/python-native-payments.mjs
354
+ ```
355
+
356
+ This fixture covers both semantic profiles, both layouts, custom source/test
357
+ directories, keyword-only fields, and incorrect fee/currency/absence adapters.
358
+ Schema tests cover recursive generic mappings, Symbol identity, invalid mappings
359
+ and retained constructor predicates.
360
+
361
+ Python generator bindings reference factories in importable test modules. Each
362
+ factory receives one native Hypothesis strategy per type parameter and returns
363
+ a strategy producing the application representation. The generated test helper
364
+ maps native values through the checked schema, retaining Hypothesis shrinking.
365
+ Invalid samples and shrinks fail contextually instead of being filtered. An
366
+ exhausted custom strategy cannot fall back to a deterministic witness.
367
+
368
+ ```sh
369
+ LAWSPEC_CORE=/absolute/path/to/lawspec-core LAWSPEC_NATIVE_GENERATORS=1 node tools/python-native-payments.mjs
370
+ ```
371
+
372
+ This mode checks the emitted Money factory's shrinking, a refined scalar's use
373
+ of its custom factory, and exhaustive Unit enumeration without factory sampling.
374
+ Runtime checks cover generic child strategies and nested custom scalars. Factory
375
+ modules remain application-owned. Their regeneration protection is covered by the
376
+ all-target ownership matrix below. Optional Python generator stubs are described
377
+ below; all eight targets support scaffolds.
378
+
379
+ ### Current JavaScript and TypeScript path
380
+
381
+ `bindings-web.json` maps the payment model to the application classes in
382
+ `domain.ts`. References use module path segments followed by an exported name;
383
+ source references resolve from the source root, and generator references from
384
+ the test root. The emitter selects `.mjs` for JavaScript and `.js` imports for
385
+ TypeScript. Payload classes receive one object whose keys are mapped native
386
+ field names; unit classes receive no arguments. Classes must expose mapped
387
+ fields as own properties. Alternate constructor conventions need codec hooks.
388
+
389
+ Generated bridges retain canonical typed adapter signatures and convert through
390
+ an application schema. Generic and recursive traversal preserves class identity,
391
+ Symbol identity, constructor predicates, and tagged absence states. The emitted
392
+ native-generator helper composes fast-check arbitraries, maps their values through
393
+ checked conversions, and keeps their shrink contexts. Invalid samples/shrinks
394
+ fail contextually; exhausted custom generators cannot use witness fallback.
395
+
396
+ ```sh
397
+ LAWSPEC_CORE=/absolute/path/to/lawspec-core LAWSPEC_NATIVE_GENERATORS=1 node tools/web-native-payments.mjs
398
+ ```
399
+
400
+ The integration compiles TypeScript, executes both targets in readable/compact
401
+ mode at both machine profiles with custom layouts, and rejects incorrect fee,
402
+ currency and absence handling. Runtime checks also exercise generic native child
403
+ arbitraries and deliberately invalid shrink values. Full release acceptance,
404
+ including broader generator/refinement coverage, remains pending.
405
+
406
+ ### Current Java path
407
+
408
+ `bindings-java.json` maps the payment types to records, sealed variants and enum
409
+ constants nested in the application-owned `PaymentsDomain` class. Java references
410
+ are fully qualified type, constructor or static method names. Mapped payload
411
+ fields use accessor methods; constructors receive fields in LawSpec declaration
412
+ order. `unit` mappings refer to enum constants. An empty application record uses
413
+ `record` or `variant` style instead. Alternate conventions need codec hooks.
414
+
415
+ `LawSpecNativeCodecs` composes typed codecs over the shared schema. Application
416
+ types stay separate from generated canonical declarations, while validation,
417
+ constructor predicates and Symbol contexts are shared. Generic recursive codecs
418
+ are constructed lazily during traversal. Bound units map every adapter; generated
419
+ bridges are source-owned and retain canonical typed signatures.
420
+
421
+ ```sh
422
+ LAWSPEC_CORE=/absolute/path/to/lawspec-core node tools/java-native-payments.mjs
423
+ ```
424
+
425
+ The fixture executes the payment laws and recursive generic shape laws under
426
+ both profiles and formatting modes, with custom directories and three incorrect
427
+ payment adapters. Native generator factories can be selected with `generators`
428
+ entries referencing static methods. Generic factories receive a typed JetCheck
429
+ generator for each type argument; the compiler specializes reachable concrete
430
+ types and composes checked application codecs around those strategies.
431
+
432
+ The JetCheck runtime now provides native factory hooks and checked strategy
433
+ mapping. `tools/java-native-generator-runtime.mjs` checks generic child
434
+ composition, actual shrinking, invalid sample/shrink replay failures, exhaustion
435
+ without witness fallback, and the existing constructor-contract behavior at both
436
+ machine profiles. The generated path is exercised with:
437
+
438
+ ```sh
439
+ LAWSPEC_CORE=/absolute/path/to/lawspec-core LAWSPEC_NATIVE_GENERATORS=1 node tools/java-native-payments.mjs
440
+ ```
441
+
442
+ This adds Money and generic Box factories, a refined Int8 factory and a finite
443
+ Seal factory that fails if sampled. The tests check emitted Money shrinking,
444
+ refined-input factory use and finite enumeration. Native conversion failures
445
+ are carried through composed draws to property callbacks, including during
446
+ shrink replay. Runtime control exceptions remain under JetCheck's control.
447
+ Generator source is application-owned and stays in test directories; generated
448
+ source codecs do not depend on JetCheck. Formatting and wider release acceptance
449
+ remain pending.
450
+
451
+ ### Current Kotlin path
452
+
453
+ `bindings-kotlin.json` maps the payment model to application-owned Kotlin classes
454
+ in `PaymentsDomain.kt`. Payload mappings read properties and call constructors
455
+ in LawSpec field order. Unit mappings reference enum constants or singleton
456
+ objects and compare identity. Payload constructors are checked by exact runtime
457
+ class. Generic and recursive codecs compose through the same shared schema used
458
+ by canonical Kotlin data, retaining contracts and logical diagnostic field names.
459
+
460
+ `LawSpecNativeCodecs.kt` and bound canonical adapters are generated source files;
461
+ neither requires Kotest. A bound unit currently maps every adapter. Alternate
462
+ construction conventions still need codec hooks.
463
+
464
+ Kotlin generator bindings select application-owned factory functions returning
465
+ Kotest `Arb` values. Generic factories receive one typed native arbitrary per type
466
+ argument. Generated helpers compose checked codecs around those arbitraries,
467
+ retaining their shrink trees. Invalid samples and shrink candidates reach the
468
+ property callback as contextual failures; custom strategies cannot fall back to
469
+ witnesses when exhausted. Refinements filter the configured distribution while
470
+ explicit examples, boundaries and finite-domain enumeration remain independent.
471
+
472
+ ```sh
473
+ LAWSPEC_CORE=/absolute/path/to/lawspec-core LAWSPEC_NATIVE_GENERATORS=1 node tools/kotlin-native-payments.mjs
474
+ node tools/kotlin-native-generator-runtime.mjs
475
+ ```
476
+
477
+ The generated checks exercise generic factories, Money shrinking, refined scalar
478
+ factory use, finite singleton enumeration without invoking its factory, and an
479
+ invalid Text factory whose surrogate value must fail in the generated property.
480
+ Runtime checks additionally exercise invalid native shrink candidates reaching
481
+ Kotest callbacks and exhausted custom strategies with available witnesses.
482
+
483
+ ```sh
484
+ LAWSPEC_CORE=/absolute/path/to/lawspec-core node tools/kotlin-native-payments.mjs
485
+ ```
486
+
487
+ The integration executes payment and recursive generic shape laws, examples and
488
+ boundaries under both machine profiles and formatting modes, including custom
489
+ source/test directories. It compares native/WASM emission and checks that
490
+ incorrect fee, currency and absence adapters fail executable laws.
491
+ `tools/kotlin-native-source.mjs` additionally compiles only generated source,
492
+ application types and codec checks without Kotest dependencies. It executes exact
493
+ decimal, raw code-point/UTF-16/byte, Symbol identity, nested absence and unmapped
494
+ variant checks under both machine profiles.
495
+
496
+ ### Current Go path
497
+
498
+ `bindings-go.json` maps the payment and recursive shape domains to application
499
+ structs, interfaces and enum constants in their existing generated-test packages.
500
+ References contain either one package-local identifier or a declared import alias
501
+ and an exported identifier. Payload fields use
502
+ explicit native names and keyed struct construction; unit mappings name enum
503
+ constants. Application functions can retain names such as `AddFee`: checked Core
504
+ calls are lowered to separate generated bridge names, including contract calls.
505
+
506
+ `lawspec_native_codecs.go` contains framework-independent checked conversions.
507
+ Only reachable native codecs are emitted per package. The bridge preserves exact
508
+ scalar values, generic child codecs, recursion and schema field diagnostics.
509
+ Application symbols are reserved before Go emission. If a canonical type or variant
510
+ would collide, the compiler gives that generated family a fresh `Canonical`-prefixed
511
+ name. Existing names are considered too: an application `Box` and an existing
512
+ canonical `CanonicalBox` produce `Canonical1Box` for the conflicting generated
513
+ family. Qualified logical identities, schema values and propositions remain
514
+ unchanged. Codec hooks support alternate pointer/storage conventions.
515
+
516
+ ```sh
517
+ LAWSPEC_CORE=/absolute/path/to/lawspec-core node tools/go-native-payments.mjs
518
+ ```
519
+
520
+ The integration builds source packages and executes laws/examples/boundaries for
521
+ payments, recursive generic shapes and scalar/absence adapters under both machine
522
+ profiles and output formats, with custom directories. It compares native/WASM output and checks Go formatting, raw UTF-16/bytes, Symbol
523
+ identity, invalid Text context, constructor contracts with a shared Symbol context,
524
+ and bound adapter postconditions. Three incorrect payment adapters must fail
525
+ executable laws.
526
+
527
+ Go generator bindings name package-local factories returning Rapid generators.
528
+ Generic factories receive a native generator per type argument. The generated
529
+ `lawspec_native_generators_test.go` composes these with checked codecs, preserving
530
+ Rapid's draw/replay stream and shrinking. Native validation failures use a distinct
531
+ panic type so they reach properties without swallowing Rapid's discard control.
532
+ Custom factories bypass witness fallback and constructor rejection; their invalid
533
+ values and shrink candidates are failures. Refinements still filter the custom
534
+ distribution, and finite domains are enumerated without invoking factories.
535
+
536
+ ```sh
537
+ LAWSPEC_CORE=/absolute/path/to/lawspec-core LAWSPEC_NATIVE_GENERATORS=1 node tools/go-native-payments.mjs
538
+ node tools/go-native-generator-runtime.mjs
539
+ ```
540
+
541
+ These checks cover typed generic composition, emitted Money shrinking to 1.61,
542
+ refined scalar factory use, finite singleton handling, invalid Text samples and
543
+ exhausted refined distributions. Runtime tests also demonstrate invalid native
544
+ shrink candidates reaching property callbacks, invalid constructor contracts and
545
+ exhaustion despite an available witness. Factory files are application-owned test
546
+ code. Regeneration protection and optional Go generator stubs are covered below.
547
+
548
+ ### Go external packages
549
+
550
+ Declare package paths separately from structured native references:
551
+
552
+ ```json
553
+ {
554
+ "goImports": [{"alias": "domain", "path": "example.org/application/domain"}],
555
+ "functions": [{"declaration": "example::echo", "native": ["domain", "Echo"]}]
556
+ }
557
+ ```
558
+
559
+ The same alias can qualify native types, constructors and generator factories.
560
+ External names and mapped fields must be exported. Aliases are resolved to
561
+ compiler-owned import names, so configuration aliases such as `schema` and `rapid`
562
+ cannot shadow generated locals or framework imports. Each artifact imports only
563
+ its dependencies; an unused configured import does not create a package dependency.
564
+ Duplicate aliases/paths, traversal paths and undeclared aliases fail planning.
565
+ `goImports` is rejected for other targets.
566
+
567
+ `test/fixtures/native-go-external` supplies application-owned generic products,
568
+ recursive sums, enums and Rapid factories in separate Go packages. The fixture
569
+ executes checked bridges under both profiles and custom layouts, including a
570
+ UInt64 maximum example. Generated source builds independently of the generator
571
+ package, and a broken application must compile before failing its laws. A separate
572
+ failing property verifies that the imported generic factory retains native Rapid
573
+ shrinking down to a Box payload of 61. Native and WASM emission are compared.
574
+
575
+ ```sh
576
+ LAWSPEC_CORE=/absolute/path/to/lawspec-core node tools/go-native-external.mjs
577
+ ```
578
+
579
+ Direct mappings require compatible field representations. Application packages
580
+ with their own wrappers or alternate recursive storage can use the codec hooks
581
+ described above. Canonical name reservation applies consistently to generated data,
582
+ codecs, adapter bridges, native factories, definitions and tests in both output
583
+ formats. Imported names do not occupy the local application namespace.
584
+
585
+ `test/fixtures/native-go-names` exercises colliding generic products and recursive
586
+ sums, an occupied canonical prefix, native generator selection and a broken adapter
587
+ that compiles before failing its laws. The hook fixture can also run with a native
588
+ `Parcel` name, verifying that user hooks and generated codecs agree on the renamed
589
+ canonical family.
590
+
591
+ ```sh
592
+ LAWSPEC_CORE=/absolute/path/to/lawspec-core node tools/go-native-names.mjs
593
+ LAWSPEC_CORE=/absolute/path/to/lawspec-core LAWSPEC_GO_COLLISIONS=1 node tools/go-native-codecs.mjs
594
+ ```
595
+
596
+ ### Current Haskell path
597
+
598
+ `bindings-haskell.json` maps the payment domain to application-owned types in
599
+ `PaymentsDomain.hs`. Generated codecs construct and match records by their mapped
600
+ field names, independently of native declaration order. Canonical adapter bridges
601
+ validate both directions and carry each example's Symbol context into codecs.
602
+ Unit-returning application calls are forced before encoding their result. Application
603
+ imports receive distinct aliases, including modules named `P`, `Data` or `Codec`;
604
+ references that shadow generated module files are rejected during planning.
605
+
606
+ ```sh
607
+ LAWSPEC_CORE=/absolute/path/to/lawspec-core LAWSPEC_GHC=/absolute/path/to/ghc node tools/haskell-native-payments.mjs
608
+ ```
609
+
610
+ Set `LAWSPEC_GHC_PACKAGE_DB` when Hspec/Hedgehog live in a separate package database.
611
+ The integration executes payments under both machine profiles, readable and compact
612
+ output, and custom directories, with native/WASM emission parity. Bound adapter
613
+ postconditions are executed. Incorrect fee, currency and absence implementations,
614
+ and a throwing Unit adapter, must compile and then fail executable laws. The same matrix includes generic records, recursive sums, nested instances and
615
+ finite singleton types from `native_shapes.lawspec`.
616
+
617
+ Haskell factories return native Hedgehog `Gen` values and receive a native child
618
+ generator per type parameter. Generated codecs map those trees without replacing
619
+ their shrinking. Custom factories bypass witness fallback and constructor
620
+ rejection; invalid native values are contextual failures. Finite domains are
621
+ still enumerated without invoking their factories. Framework helpers remain in
622
+ test directories, and source compilation is checked with testing packages hidden.
623
+
624
+ ```sh
625
+ LAWSPEC_CORE=/absolute/path/to/lawspec-core LAWSPEC_GHC=/absolute/path/to/ghc LAWSPEC_NATIVE_GENERATORS=1 node tools/haskell-native-payments.mjs
626
+ node tools/haskell-native-generator-runtime.mjs
627
+ ```
628
+
629
+ The emitted factories retain Money shrinking to 1.61 and generic Box shrinking
630
+ to 13. Invalid Decimal samples fail emitted properties, and a custom Int8
631
+ distribution containing only zero exhausts the refined input instead of using a
632
+ witness. The runtime checks also cover invalid shrink candidates and empty factories.
633
+ Source-only execution additionally checks raw code points, UTF-16 units, bytes,
634
+ supplementary characters, nested absence states, scoped Symbol constructor contracts,
635
+ and native architecture mismatch diagnostics. Regeneration protection is covered below; generator stubs remain unfinished.
636
+
637
+ ### Shared requirements
638
+
639
+ 1. **Resolve bindings once.** Add per-target configuration/API bindings keyed by
640
+ qualified LawSpec declaration identity. Resolve and validate them against
641
+ typed Core before emission. Reject unknown types, constructors or fields,
642
+ duplicate/incomplete mappings, incompatible type arities, malformed target
643
+ references and unsupported representations with contextual diagnostics.
644
+ Ordinary specifications retain their meaning and default generated types.
645
+ 2. **Generate checked native bridges.** Support application-owned products and
646
+ sums with explicit constructor/field mappings and callable codec hooks for
647
+ representations that cannot be expressed as direct mappings. Compose through
648
+ type parameters, recursion, `List`, `Maybe`, `Either`, `Nullable` and `Optional`.
649
+ Preserve exact values, Symbol identity, distinct absence states, constructor
650
+ contracts and both machine profiles. Validate adapter inputs and outputs;
651
+ invalid native values fail rather than becoming rejected generator samples.
652
+ 3. **Connect native generators.** Bind factories returning the target framework's
653
+ generator/strategy/arbitrary. Compose and map those objects directly; do not
654
+ sample them into a separate random-value generator or replace their shrinkers.
655
+ Factories for parameterized types receive generators for their type arguments.
656
+ Validate generated values, including shrinks, through the same bridge. Retain
657
+ refinement predicates and their existing failure-versus-rejection distinction.
658
+ Custom random distributions never remove explicit examples, deterministic
659
+ boundaries or exhaustive finite-domain cases.
660
+ 4. **Keep target details out of propositions.** Binding resolution produces a
661
+ backend binding plan alongside the existing typed testing plan. Arithmetic,
662
+ equality, total definitions and refinements continue to use checked Core
663
+ semantics. Schema/codec source remains independent of test frameworks.
664
+ 5. **Preserve application ownership.** Import existing application code; never
665
+ rewrite it. Generate bridge source and framework-specific test helpers in
666
+ their respective directories. Keep optional implementation/generator stubs
667
+ user-owned. Support custom layouts, regeneration and adapter-update reporting.
668
+ 6. **Ship one coherent interface.** Update the public API declarations and their
669
+ generator, CLI config validation, diagnostics, documentation and examples
670
+ together. Decide schema versioning from the actual wire changes; do not
671
+ silently accept and ignore requested binding configuration.
672
+
673
+ ## Ownership, regeneration and migration
674
+
675
+ Generated bridges and numeric/schema runtimes belong in source directories.
676
+ Framework helpers belong in test directories (Go test files share their package's
677
+ source directory). Application models, conversion hooks and generator factories
678
+ remain application-owned. The ownership manifest records generated-file hashes;
679
+ it does not take ownership of existing application files.
680
+
681
+ When adopting bindings, an existing user-owned adapter at the new bridge's path
682
+ blocks generation, even if it still contains an untouched scaffold. Move the
683
+ implementation into the configured application module and save the old adapter
684
+ outside the generated bridge path before regenerating. Do not edit the manifest
685
+ to make application code appear compiler-owned. The compiler can then create its
686
+ bridge without overwriting the saved adapter.
687
+
688
+ Removing bindings preserves the former bridge when that path becomes a user-owned
689
+ adapter and reports the required adapter scaffold as an update. Review that update
690
+ and implement the ordinary adapter before running tests: obsolete generated
691
+ binding helpers can be removed during this migration. Source/test layout changes
692
+ relocate generated files; application code stays where it is until the user moves
693
+ it or adjusts project configuration.
694
+
695
+ The all-target filesystem matrix checks:
696
+
697
+ - Adoption blocks writes until the user adapter has been moved aside.
698
+ - Unchanged generation is a no-op, including after profile/format changes.
699
+ - Edits to generated files block replacement or removal during relocation.
700
+ - Edits detected between planning and applying abort before writes begin.
701
+ - Application generator files and saved adapters remain byte-for-byte intact.
702
+ - Removing bindings preserves adapter content and reports the required update.
703
+ - Custom source/test layouts retain artifact placement and ownership separately.
704
+
705
+ ```sh
706
+ node --test npm/test/native-ownership.test.mjs
707
+ ```
708
+
709
+ ### Optional generator scaffolds
710
+
711
+ A generator binding may opt into a user-owned factory scaffold with `"stub": true`:
712
+
713
+ ```json
714
+ {
715
+ "generators": [
716
+ {"type": "List", "factory": ["application_generators", "lists"], "stub": true}
717
+ ]
718
+ }
719
+ ```
720
+
721
+ All eight targets implement this option.
722
+ Omitting `stub` (or setting it to false) keeps the existing import-only behavior on every target.
723
+
724
+ For this Python example, generation creates `tests/application_generators.py`
725
+ (or the equivalent under a custom test directory). `lists(argument_0)` receives
726
+ its element Hypothesis strategy and must return a native `SearchStrategy`. The
727
+ initial body raises `NotImplementedError`; implement it using native strategy
728
+ composition to preserve shrinking. Multiple requested factories in the same module
729
+ share one file. Use a dedicated test module: names that conflict with generated
730
+ support, application binding modules, or another scaffold are rejected. A
731
+ scaffolded factory must belong to exactly one logical type.
732
+
733
+ Scaffolds remain readable and PEP 8 formatted in either output format. Existing
734
+ files are preserved, including edited implementations. Changes to the requested
735
+ type or type-parameter arity are reported through `adapterUpdates`; they never
736
+ replace the implementation. Changing the test layout leaves the old user-owned
737
+ file intact and creates a scaffold at the new path if absent. Move your actual
738
+ implementation to the new path before running its tests.
739
+
740
+ ```sh
741
+ node --test npm/test/native-bindings.test.mjs
742
+ LAWSPEC_CORE="$PWD/.artifacts/native-binding-core" LAWSPEC_GENERATOR_STUBS=1 node tools/python-native-payments.mjs
743
+ ```
744
+
745
+ The Python integration compiles and invokes the unimplemented factories, then
746
+ implements them with the application generators and runs the payment properties
747
+ in both machine profiles and output formats. Native/WASM plans must match.
748
+ Rust factories return `proptest::strategy::BoxedStrategy<NativeType>` and take one
749
+ boxed strategy for each type parameter. Type parameters carry `Debug + 'static`
750
+ bounds. A reference such as `["factories", "collections", "values"]` creates
751
+ `tests/support/factories.rs` with a public `collections` module and `values`
752
+ function; `crate` and `self` prefixes refer to that same integration-test module.
753
+ Factories sharing a root share one user-owned file. Test modules import this
754
+ support automatically. Explicit `crate`/`self` references keep importing the local
755
+ support module even with `stub: false`; the existing factory file is preserved.
756
+ For an unprefixed custom root, retain `stub: true` after implementation, or make
757
+ the local reference explicit before disabling scaffolding. The application crate named by `rustCrate` remains the
758
+ source of native types and the shared runtime. Scaffolds cannot use that crate
759
+ name, framework imports, or generated support names as their local root.
760
+
761
+ Rust scaffold bodies use `unimplemented!` until the user supplies a strategy.
762
+ Regeneration preserves the implementation, and changes to native return types or
763
+ parameter signatures appear in `adapterUpdates`. Generated scaffold files remain
764
+ readable in compact mode. Nested modules and raw Rust keyword identifiers are
765
+ supported; ambiguous factory/module paths and case-insensitive file collisions
766
+ are rejected. Existing external-crate factories remain import-only when `stub`
767
+ is omitted.
768
+
769
+ ```sh
770
+ LAWSPEC_CORE="$PWD/.artifacts/native-binding-core" node tools/rust-generator-scaffolds.mjs
771
+ ```
772
+
773
+ The Rust matrix compiles framework-independent source and test scaffolds, verifies
774
+ explicit failure before implementation, then runs the generic application factories
775
+ and their native shrinkers after implementation. It also compiles signatures for
776
+ all scalar types, built-in containers, and an unbound generic data type. Both
777
+ machine profiles, readable/compact output, custom directories, native/WASM parity,
778
+ file preservation and signature-change reporting are covered.
779
+
780
+ JavaScript and TypeScript factories are exported functions returning native
781
+ fast-check arbitraries. A factory reference `["factories", "collections", "lists"]`
782
+ creates `test/factories/collections.mjs` (or `.ts`). Factories in one module share
783
+ one user-owned file. TypeScript signatures use `fc.Arbitrary<T>` child arguments
784
+ and the bound native result type; unbound types use the ordinary generated data
785
+ representation. Source-type imports are adjusted from the actual nested factory
786
+ directory when custom source/test layouts are selected.
787
+
788
+ Both web formats keep scaffolds readable and throw a contextual error until
789
+ implemented. They preserve existing implementations and report changed signatures,
790
+ including native-class changes, through `adapterUpdates`. JavaScript and Python
791
+ include a native-result label so a class change also updates the untyped scaffold
792
+ contract. Conflicts with generated test modules or scaffold signature dependencies
793
+ are diagnosed before writing files.
794
+
795
+ ```sh
796
+ LAWSPEC_CORE="$PWD/.artifacts/native-binding-core" LAWSPEC_GENERATOR_STUBS=1 node tools/web-native-payments.mjs
797
+ LAWSPEC_CORE="$PWD/.artifacts/native-binding-core" node tools/web-generator-scaffolds.mjs
798
+ ```
799
+
800
+ The web matrix compiles and invokes the initial scaffolds, then runs implemented
801
+ payment and generic list factories with native shrinking. The signature catalog
802
+ covers every scalar, built-in container, native generic class and unbound generic
803
+ data type. TypeScript also rejects an intentionally wrong arbitrary result type.
804
+ Both profiles, formats, nested custom layouts and native/WASM parity are checked.
805
+
806
+ Java factories are public static methods returning native JetCheck
807
+ `Generator<NativeType>` values. A reference such as
808
+ `["application", "Factories", "prices"]` creates the user-owned test file
809
+ `application/Factories.java` under the configured test directory. The last two
810
+ segments name the class and method; earlier segments name the package. Generic
811
+ methods take one `Generator<T>` per type parameter. Scalar payloads use boxed
812
+ native types; Nullable/Optional keep their tagged runtime representation.
813
+
814
+ The initial methods throw `UnsupportedOperationException`. Implement them using
815
+ JetCheck composition to retain shrinking. Scaffolds require a named package
816
+ because generated framework helpers cannot access classes in the unnamed package.
817
+ Classes that conflict with generated/application classes or signature packages,
818
+ and methods that conflict with inherited Object methods, are rejected. Factories
819
+ in one class share one file. Existing implementations, custom layouts and
820
+ signature-update reporting use the same ownership rules as other targets.
821
+
822
+ ```sh
823
+ LAWSPEC_CORE="$PWD/.artifacts/native-binding-core" LAWSPEC_GENERATOR_STUBS=1 node tools/java-native-payments.mjs
824
+ LAWSPEC_CORE="$PWD/.artifacts/native-binding-core" node tools/java-generator-scaffolds.mjs
825
+ ```
826
+
827
+ The Java matrix compiles the scaffold before implementation, verifies explicit
828
+ runtime failure, then executes native payment and generic-shape generators,
829
+ shrinking checks, finite-domain handling and invalid-adapter/generator mutants.
830
+ The catalog compiles every scalar and container signature, native and canonical
831
+ generic result types, and rejects an intentionally wrong generator result type.
832
+ Both machine profiles, output formats, custom layouts and native/WASM parity are
833
+ covered.
834
+
835
+ Kotlin scaffolds use named objects with functions returning Kotest `Arb<Native>`.
836
+ The last two reference segments name the object and function; earlier segments
837
+ name its package. For example, `["application", "Factories", "prices"]` creates
838
+ `application/Factories.kt` under the configured test directory. Generic factories
839
+ receive one `Arb<T>` child per type parameter. Native generic classes, generated
840
+ unbound data types, and tagged Nullable/Optional types share the compiler's Kotlin
841
+ type mapping. The initial bodies throw contextual `NotImplementedError` values.
842
+
843
+ Objects must be in named packages and must not collide with generated/application
844
+ classes, Kotest support, runtime packages or signature dependencies. Inherited Any
845
+ method conflicts are rejected. The file remains user-owned; readable/compact
846
+ switches preserve it, while native-result or generic-signature changes are reported
847
+ as adapter updates. Keep existing top-level factories import-only, or use a named
848
+ object when requesting scaffolds.
849
+
850
+ ```sh
851
+ LAWSPEC_CORE="$PWD/.artifacts/native-binding-core" LAWSPEC_GENERATOR_STUBS=1 node tools/kotlin-native-payments.mjs
852
+ LAWSPEC_CORE="$PWD/.artifacts/native-binding-core" node tools/kotlin-generator-scaffolds.mjs
853
+ ```
854
+
855
+ The Kotlin integration compiles and invokes the initial factories, implements them
856
+ with native application arbitraries, then checks payments, generic/recursive
857
+ shapes, shrinking, finite enumeration, invalid text, exhausted refinements and
858
+ incorrect adapters. Its signature catalog checks all scalars and containers,
859
+ native/canonical generic classes, source-only compilation without Kotest, and
860
+ rejection of a deliberately wrong `Arb` result type. Both machine profiles,
861
+ formats, custom layouts and native/WASM parity are covered.
862
+
863
+ Go scaffolds are package-local functions returning `*rapid.Generator[Native]`,
864
+ with one generic child generator per type parameter. Each consuming unit gets a
865
+ user-owned `native_generators_test.go` beside its generated tests. Only the
866
+ factories used by that package are included. Named Go imports are supported in
867
+ native result types, while imported **factories** stay import-only: scaffolding
868
+ does not write into dependencies. A requested factory with no quantified use is
869
+ rejected because there is no consuming package in which to place its scaffold.
870
+
871
+ The scaffold initially panics with its logical type identity. Existing files are
872
+ preserved, signature/native-result changes produce adapter updates, and compact
873
+ mode keeps the user file readable and gofmt compatible. Factory names must not
874
+ shadow application declarations in the same package, built-ins, runtime imports,
875
+ generated support or Go test entry points. Type-parameter names avoid canonical
876
+ and application type names. Source and test layouts continue sharing the same Go
877
+ package directories.
878
+
879
+ ```sh
880
+ LAWSPEC_CORE="$PWD/.artifacts/native-binding-core" LAWSPEC_GENERATOR_STUBS=1 node tools/go-native-payments.mjs
881
+ LAWSPEC_CORE="$PWD/.artifacts/native-binding-core" node tools/go-generator-scaffolds.mjs
882
+ ```
883
+
884
+ The Go matrix compiles the initial factory files, verifies explicit missing-body
885
+ failures, then executes application payment/shape factories with native shrinking,
886
+ finite-domain/refinement behavior and broken adapters/generators. The catalog
887
+ compiles every scalar and container signature, imported generic models, and a
888
+ canonical type named `T0` to check that generic parameters cannot capture type
889
+ names. It rejects an intentionally wrong Rapid result type. Both profiles,
890
+ formats, custom layouts, source-only builds and native/WASM parity are covered.
891
+
892
+ Haskell scaffolds group typed Hedgehog factories in a user-owned module under the
893
+ test directory. For example, `["Application", "Generators", "lists"]` produces
894
+ `Application/Generators.hs` with `lists :: H.Gen a0 -> H.Gen [a0]`. Each type
895
+ parameter receives a native child generator; the result uses the application type
896
+ when bound, otherwise the canonical generated type. Scalar signatures preserve
897
+ the existing native representations, including `Data.Text.Text` versus `[Char]`
898
+ and tagged nullable/optional values.
899
+
900
+ Bodies initially call `error` with the logical type identity. Implement them by
901
+ composing Hedgehog generators to retain shrinking. Modules that conflict with
902
+ application models/functions/hooks, generated modules or reserved runtime modules
903
+ are rejected, including case-insensitive filename collisions. Nested modules and
904
+ custom test roots are supported; scaffolds remain readable in compact mode.
905
+ Edits remain user-owned and changes to native types or factory arity appear in
906
+ `adapterUpdates`.
907
+
908
+ ```sh
909
+ LAWSPEC_CORE="$PWD/.artifacts/native-binding-core" LAWSPEC_GENERATOR_STUBS=1 node tools/haskell-native-payments.mjs
910
+ LAWSPEC_CORE="$PWD/.artifacts/native-binding-core" node tools/haskell-generator-scaffolds.mjs
911
+ ```
912
+
913
+ Set `LAWSPEC_GHC` and, when required, `LAWSPEC_GHC_PACKAGE_DB` for both commands.
914
+ The payment matrix compiles and invokes the initial scaffold before supplying
915
+ application factories and exercising native shrinking and invalid-generator
916
+ diagnostics. The signature catalog compiles all scalar/container signatures,
917
+ canonical and native generic models, rejects an incorrect `Gen String` result,
918
+ and checks explicit missing-body failures. Both profiles, formats, custom layouts,
919
+ framework-independent source builds and native/WASM parity are covered.
920
+
921
+ ## Release evidence required
922
+
923
+ ### Bundled application projects
924
+
925
+ `lawspec examples --example payments` exports one project for each of the eight
926
+ targets under `native_payments/`. Use `--target rust` (or another target) to select
927
+ one, `--output` to choose a directory, and `--machine-bits 32` to select the other
928
+ machine profile. Each project includes the shared specification, application-owned
929
+ domain types and functions, a native price generator, binding configuration, build
930
+ files and a README with commands. Run `lawspec check`, `lawspec generate`, and the
931
+ native test command after installing its dependencies.
932
+
933
+ The native generator intentionally restricts prices to EUR 1.00–2.00. Explicit
934
+ USD/GBP and exact-decimal examples remain in the law, demonstrating that custom
935
+ distributions do not replace those checks. The applications use host exact decimal
936
+ types when faithful and framework-independent support otherwise.
937
+
938
+ Exports use `.lawspec/example.json`; compilation uses `.lawspec/generated.json`.
939
+ This separation lets repeated export preserve edited application files without
940
+ removing or overwriting generated code, including edited generated code that the
941
+ compiler will separately protect. Updated bundled user files are reported for
942
+ review through the existing update channel. Export does not run dependency
943
+ installation or native tests.
944
+
945
+ `tools/native-example-package.mjs` packs and locally installs the npm artifact,
946
+ exports and checks all eight projects, then runs Rust generation, native tests,
947
+ re-export and `generate --check` through the installed CLI. After that script,
948
+ `tools/native-example-runtime.mjs` accepts the other seven target names to execute
949
+ the exported projects with the installed compiler and cached native toolchains.
950
+ For Haskell set `LAWSPEC_GHC` and `LAWSPEC_GHC_PACKAGE_DB`; other cached dependency
951
+ locations can be overridden where the runner exposes environment variables.
952
+
953
+ `node tools/native-example-integration.mjs <target>` performs the public installed
954
+ CLI acceptance path: pack and install, export the payment project, prepare native
955
+ dependencies, check and generate, run the normal native build tool, reject an
956
+ incorrect fee implementation, restore application source, re-export, and check
957
+ regeneration. Logs for every command are retained under
958
+ `.artifacts/native-example-integration/`. CI runs this for every target with the
959
+ default profile and with `LAWSPEC_MACHINE_BITS=32 LAWSPEC_MINIFY=1`.
960
+ `LAWSPEC_PYTHON` selects the Python version for uv; an existing interpreter can be
961
+ selected with `LAWSPEC_PYTHON_EXECUTABLE`. `LAWSPEC_NODE_MODULES` and
962
+ `LAWSPEC_GRADLE` select existing web dependencies and Gradle respectively.
963
+ `LAWSPEC_OFFLINE=1` uses offline npm, uv, Maven and Cargo operations and disables
964
+ Go proxy access; Stack still requires its normal configured dependency cache.
965
+ `STACK_ROOT` and `GRADLE_USER_HOME` can select writable copies of existing caches.
966
+
967
+ The installed CLI/native-tool path has passed for all eight targets in both CI
968
+ configurations: 64-bit readable output and 32-bit compact output. TypeScript
969
+ uses the exact declared dependencies recovered from the existing npm cache;
970
+ Haskell uses a writable copy of the existing Stack cache. Kotlin's Gradle 9.3.0
971
+ checks were run in the user's normal terminal because this sandbox prohibits
972
+ Gradle's coordination socket. The saved logs confirm successful native tests,
973
+ seven expected failures among 45 tests for the deliberately incorrect fee, and
974
+ zero planned regeneration changes in both configurations. This verifies the
975
+ installed CLI/Gradle path as well as the separate compilation/runtime harness.
976
+ The remote run of these CI additions exposed failures in the Kotlin and Haskell
977
+ target jobs. They came from the 0.9 narrowing of abstract `Integer` adapter
978
+ results, not from bindings, and are fixed in 0.11
979
+ ([release notes](RELEASE-0.11.md#tower-polymorphic-integer-results-restored)).
980
+
981
+ The runnable assets live in `examples/native-payments/` and are copied into the
982
+ npm package by `tools/wasm.sh`. The original `lawspec examples` command retains its
983
+ inspection-artifact behavior.
984
+
985
+ ### Remaining acceptance gates
986
+
987
+ The release audit maps the six shared requirements to these executable checks:
988
+
989
+ | Requirement | Evidence and checks |
990
+ | --- | --- |
991
+ | Resolve bindings once | `NativeBindingSpec` checks identities, complete mappings, ordering, arities, reference validation and unchanged defaults. `NativeRequestSpec` checks the public request boundary. `stack test` passes 509 examples. |
992
+ | Checked native bridges | The target-specific native-payment, native-codec and native-shapes runners compile application models and reject incorrect conversions, precision loss, altered variants and collapsed absence. They compare native/WASM plans across machine profiles, layouts and formatting. |
993
+ | Native generation and shrinking | The native-generator runtime checks and payment/codec runners verify framework factories, shrinking, invalid samples/shrinks, contracts and exhaustion. The shared empty-domain runners cover ignored and demanded empty parameters on all eight targets. |
994
+ | Core semantics and source independence | `tools/check-boundaries.mjs` checks all eight emitter dependency boundaries. The codec/source runners build generated source without test-framework dependencies; native representations are checked against the shared schema. |
995
+ | Application ownership | `npm/test/native-ownership.test.mjs` checks all-target migration, edited files, custom layouts, profile/format changes and adapter updates. `npm/test/native-bindings.test.mjs` covers optional generator scaffolds and signature changes. |
996
+ | Coherent public interface | Schema negotiation and declarations are covered by compiler/npm tests; `tools/build-integrity.mjs` checks compiler/WASM/API fingerprints. Bundled projects are exercised by the installed-package runners. The migration guide and release notes document the interface. |
997
+
998
+ The full npm regression suite passes 77 tests, and the package smoke test passes
999
+ installed API generation on all eight targets plus executable Rust scaffold,
1000
+ doctor, adapter and regeneration checks. The package contains the binding guide,
1001
+ migration notes, release notes and all eight application example configurations.
1002
+ The remote CI gate for these checks was reviewed during the 0.11 release, which
1003
+ re-ran every target job, including both installed native-binding profiles.
1004
+
1005
+ The empty-parameter audit must distinguish an empty type from an inhabited type
1006
+ that mentions it. A native factory for `Phantom Empty` may ignore its child
1007
+ generator; it must not fail merely because `Empty` has no values. Demanding an
1008
+ empty child still cannot produce a sample or make a property pass vacuously.
1009
+ Finite containers such as `List Empty` retain exhaustive enumeration.
1010
+
1011
+ Python supplies Hypothesis `st.nothing()` for an uninhabited native generator
1012
+ argument. Rust supplies a Proptest strategy with a rejecting filter, bounded by
1013
+ Proptest's rejection budget. Haskell supplies Hedgehog `Gen.discard`, Go uses
1014
+ Rapid's native discard control, and Java uses JetCheck's bounded rejecting
1015
+ filter. Kotlin supplies an Arb that fails when sampled; JavaScript and TypeScript
1016
+ supply a fast-check Arbitrary that throws when generation is requested. They do
1017
+ not use an always-false fast-check filter, which can loop indefinitely.
1018
+ Each permits a factory to ignore an empty parameter without inventing a
1019
+ value for that type. Actually demanding the empty child fails generation.
1020
+
1021
+ The shared `test/fixtures/native_empty_domains.lawspec` gives the phantom type a
1022
+ stored Int8 field and sets a low exhaustive limit in the runners, ensuring that
1023
+ the native factory is exercised rather than hidden by singleton enumeration.
1024
+ The Python, Rust, Haskell, Go, Java, Kotlin and web `tools/<target>-native-empty-domains.mjs`
1025
+ runners execute the generated properties and
1026
+ reject a mutant factory that demands its empty child. Both machine profiles and
1027
+ formats pass with native/WASM parity; direct runtime checks also verify retained
1028
+ shrinking and rejection of an empty root. Python additionally binds an
1029
+ application-owned phantom class. Java's empty native codec decoder throws
1030
+ directly, avoiding an invalid switch expression with no result branches. Kotlin,
1031
+ JavaScript and TypeScript also pass their native payment/generator regressions
1032
+ after the empty-parameter changes.
1033
+
1034
+ - Compiler tests for valid mappings, rejected malformed/incomplete mappings,
1035
+ generic specialization, recursion, symbol/absence semantics and contracts.
1036
+ - Lossless native/WASM request and diagnostic parity for the binding interface.
1037
+ - Payment domain builds and executes on Java, Python, JavaScript, TypeScript,
1038
+ Go, Haskell, Kotlin and Rust using genuinely application-owned types.
1039
+ - Native custom generators are invoked, their shrinkers demonstrably shrink
1040
+ failing domain values, invalid values/shrinks fail contextually, and explicit
1041
+ examples/boundaries still run when a generator omits those values.
1042
+ - Deliberately broken field/variant mappings and precision-losing adapters fail
1043
+ deterministically. Empty/exhausted generator behavior cannot pass vacuously.
1044
+ - Both machine profiles, architecture mismatch diagnostics, custom layouts,
1045
+ regeneration protection and packaged installation remain tested.
1046
+ - Python follows PEP 8; Rust remains a first-class acceptance target throughout.
1047
+
1048
+ GADTs, dependent indices and cross-unit package resolution are subsequent work.
1049
+ They are not prerequisites for binding ordinary 0.9 products and sums.