lawspec 0.8.0 → 0.9.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.
package/API-MIGRATION.md CHANGED
@@ -1,11 +1,60 @@
1
1
  # Compiler API migration: schema 2 → schema 3
2
2
 
3
- LawSpec 0.8 uses API schema version **3**. Requests may omit `schemaVersion` or
3
+ LawSpec 0.8 introduced API schema version **3**, which 0.9 continues to use.
4
+ Requests may omit `schemaVersion` or
4
5
  send `3`. An explicit `2` (or any other version) receives a request diagnostic;
5
6
  it is never silently reinterpreted. LawSpec specification syntax remains compatible.
6
7
  The generated `index.d.ts` describes the public protocol. Internal Haskell
7
8
  constructors and record fields are no longer the wire format.
8
9
 
10
+ ## 0.9 structural data and definition metadata
11
+
12
+ Successful results also expose `dataTypes: DataTypeDeclaration[]`. Each named
13
+ declaration has a resolved `id`, a display `name`, parameter IDs, an origin, and
14
+ constructors with resolved IDs and ordered typed fields. Use resolved IDs to
15
+ join references; constructors with the same display name can belong to different
16
+ units. Built-in container types do not need user declarations in this array.
17
+
18
+ Example bindings now use `DataValue`: either an existing tagged scalar or
19
+ `{kind: "data", type: Type, constructor: string, fields: DataValue[]}`. List values
20
+ use `List::Nil` and `List::Cons`, with head and tail fields; Maybe and Either use
21
+ their qualified constructor IDs. Do not flatten these values to JSON arrays or
22
+ nullable fields: that would lose constructor and nested-presence distinctions.
23
+
24
+ Expressions add `construct` nodes with a constructor ID and argument expressions,
25
+ and `match` nodes with a scrutinee and cases. Each case has a constructor ID,
26
+ ordered typed binders, and a body. Its binders are local to that case. Structural
27
+ expressions are represented by these nodes, not by scalar `constant` nodes.
28
+ Exhaustive API visitors must handle the added expression variants even though
29
+ the protocol continues to use schema version 3.
30
+
31
+ Successful results add `definitions: Definition[]`. Each entry contains `owner`,
32
+ the resolved declaration `id`, typed `arguments: Binder[]`, and a typed `body`.
33
+ The matching entry in `units[].declarations` supplies the signature and origin.
34
+ Calls retain their declaration ID; consumers can join against `definitions` to
35
+ distinguish checked bodies from external adapters. An empty array means the
36
+ program has no definitions.
37
+
38
+ The native frontend checks these bodies for typing, exhaustive matching,
39
+ structural termination, and potentially failing operations. Native reference
40
+ execution and source emission for Rust, Java, Kotlin, Python, JavaScript,
41
+ TypeScript, Go, and Haskell are implemented, including generic definitions
42
+ specialized to concrete signatures. The API exposes concrete instances with
43
+ generated names and resolved IDs, not unspecialized templates. Calls sharing a
44
+ signature reuse an instance; unused templates emit none. Consumers should join
45
+ by ID rather than parse generated names. Refinement-bearing definitions are
46
+ checked and emitted by both the native compiler and bundled WASM distribution.
47
+ Definition bodies produce generated source rather than
48
+ user-owned adapter stubs. Haskell native entry points take an `LS.SymbolContext`
49
+ and return `Either String a`; generated tests allocate a context per example or
50
+ property iteration so Symbol fixture identity does not escape its scope.
51
+
52
+ Refinement and contract expressions may now contain calls whose IDs resolve to
53
+ checked `definitions`. Validation still rejects calls to external adapters in
54
+ these expressions. Test planning evaluates the closed definitions when filtering
55
+ finite cases, boundaries, and concrete example inputs. Calls remain ordinary
56
+ typed call nodes; consumers need no source-level refinement interpreter.
57
+
9
58
  ## Laws and typed expressions
10
59
 
11
60
  Read `result.laws[i].examples` instead of `law.original.examples`. A binding is
@@ -101,3 +150,55 @@ All nonempty test plans now emit the portable scalar runtime. Existing Haskell
101
150
  projects must include `text` and `bytestring` in the component that compiles
102
151
  that source. Doctor reports the missing dependencies before generation. Build
103
152
  files remain user-owned; new scaffolds already include these dependencies.
153
+
154
+ ## Formatting requests and adapter references (0.9)
155
+
156
+ `GenerationRequest` accepts `minify?: boolean`, defaulting to `false`. The CLI
157
+ passes an explicit `--minify` from `generate` and `examples`. `init --minify`
158
+ also compacts newly created scaffolds and the configuration JSON; the choice is
159
+ not saved as a project setting. Existing project build files stay user-owned. Source/test placement is independent of
160
+ formatting. Compact rendering preserves mandatory newlines, indentation, token
161
+ separators, comments, and literal contents.
162
+
163
+ User-owned artifacts may include `adapterReference`, the compiler's canonical
164
+ readable scaffold. It is comparison data, not the user's implementation and not
165
+ an additional file to write. Manifest writers should hash this reference when
166
+ present, falling back to `content` for older producers. Continue hashing actual
167
+ `content` for generated-file ownership. This keeps a switch of formatting mode
168
+ from producing false adapter-update reports, while declared interface changes
169
+ still request review. Never normalize, overwrite, or hash user implementations
170
+ as the required adapter interface. Existing version-1 manifests remain readable.
171
+
172
+ Native and bundled WASM requests share this formatting behavior. CLI scaffolds,
173
+ generated sources, and tests preserve the same ownership rules in both modes.
174
+
175
+
176
+ Scoped List payload predicates use the schema-3 expression node
177
+ `{kind: "allElements", value: Expr, binder: Binder, predicate: Expr}`. The binder
178
+ is local to `predicate`; `value` is evaluated in the surrounding scope. The
179
+ predicate and result have type Bool. Visitors must handle this node alongside
180
+ `match`, including empty-list truth and short-circuit evaluation.
181
+
182
+ The Core also defines a scoped recursive payload operation:
183
+ `{kind: "allPayloads", value: Expr, predicates: PayloadPredicate[]}`, where each
184
+ `PayloadPredicate` contains a `binder: Binder` and `predicate: Expr`. Entries
185
+ correspond, in order, to the root data type's type arguments. Each binder has
186
+ that argument's type and is local only to its own predicate; sibling predicates
187
+ cannot refer to it. The scrutinee is evaluated in the surrounding scope, and
188
+ both each predicate and the whole operation have type Bool.
189
+
190
+ Traversal follows stored parameter occurrences through recursive declarations,
191
+ including nested containers and changing type arguments. It does not constrain
192
+ unrelated fixed fields that happen to have the same concrete type. Empty and
193
+ phantom occurrences are vacuously true; rejection short-circuits traversal.
194
+
195
+ Source named-payload refinements now elaborate to this discriminator, including
196
+ recursive applications. API consumers should handle it in checked Core views.
197
+ All eight Core emitters support this operation in definitions, properties and
198
+ constructor predicates.
199
+ The internal surface predicate node is type checked and lowered through
200
+ specialization and template proofs into this same Core operation. Internal
201
+ definition and constructor contracts support recursive payload proof facts. Constructor predicates are audited in order, and callback
202
+ matches/constructions participate in the constructor dependency-cycle check.
203
+ The TypeScript declarations now include both
204
+ `allElements` and `allPayloads`; exhaustive visitors should handle both.
package/GO.md ADDED
@@ -0,0 +1,144 @@
1
+ # Native Go data
2
+
3
+ LawSpec 0.9 generates native named Go types for parameterized products and sums.
4
+ The compiler consumes checked Core declarations, plans names across all units,
5
+ and emits sealed interfaces plus named variant structs, following Go+'s enum
6
+ lowering approach.
7
+
8
+ For example:
9
+
10
+ ```lawspec
11
+ unit example.trees
12
+
13
+ type Tree (a :: Type) is
14
+ Leaf value :: a
15
+ Branch children :: List (Tree a)
16
+ end
17
+
18
+ echo :: Tree Int8 -> Tree Int8
19
+
20
+ law `echo preserves the tree` is
21
+ definition is `for all` (x :: Tree Int8) . echo x = x end
22
+ end
23
+ ```
24
+
25
+ The adapter receives `Tree[int8]`. Its native variants are `TreeLeaf[int8]`,
26
+ with an exported `Value` field, and `TreeBranch[int8]`, with an exported
27
+ `Children []Tree[int8]` field. The interface's private marker method includes
28
+ the type parameters, so even a nullary or phantom variant retains its generic
29
+ identity. Go rejects a `TreeLeaf[bool]` where `Tree[int8]` is required.
30
+
31
+ A correct identity adapter is:
32
+
33
+ ```go
34
+ func Echo(value0 Tree[int8]) Tree[int8] {
35
+ return value0
36
+ }
37
+ ```
38
+
39
+ Adapters remain user-owned. Generated files belong to the same unit package;
40
+ custom Go layouts keep source and tests in a shared directory tree. Duplicate
41
+ type names across units receive qualified generated names. The compiler rejects
42
+ adapter names that collide with generated native declarations or runtime names.
43
+
44
+ ## Containers and presence
45
+
46
+ - `List a` uses `[]T`. Nil and empty slices represent the same empty list.
47
+ - `Maybe a` uses `LawSpecMaybe[T]`, constructed with `LawSpecNothing[T]()` or
48
+ `LawSpecJust(value)`. `Value()` returns the payload and its presence flag.
49
+ - `Either a b` uses `LawSpecEither[L, R]`, constructed with
50
+ `LawSpecLeft[L, R](value)` or `LawSpecRight[L, R](value)`. Its zero value is
51
+ invalid and checked conversion rejects it.
52
+ - `Nullable a` and `Optional a` use distinct generic support structs with
53
+ `Present` and `Value` fields. These tags preserve nested absence states.
54
+
55
+ Native scalar fields retain their domains: UInt64 uses `uint64`, arbitrary
56
+ integers use `*LawSpecBigInt`, rational values use `*LawSpecRational`, and raw
57
+ UTF-16 text uses `[]uint16`. Text uses a valid UTF-8 Go string; arbitrary bytes
58
+ use `[]byte`. Unit, Null, and Undefined have distinct named support types when
59
+ stored inside data. Native void adapter results continue to normalize to Unit.
60
+
61
+ ## Total definitions
62
+
63
+ Checked source definitions emit native methods on `LawSpecDefinitions` in the
64
+ unit's package:
65
+
66
+ ```lawspec
67
+ unit example.total
68
+
69
+ definition increment (x :: Int8) :: BigInt is x + 1 end
70
+ ```
71
+
72
+ ```go
73
+ symbols := map[string]*LawSpecSymbol{}
74
+ result := LawSpecDefinitions.Increment(symbols, 127) // big integer 128
75
+ ```
76
+
77
+ The method accepts `int8` and returns `*LawSpecBigInt`. Lists, products, sums, and
78
+ nested presence retain their native parameterized types. A dedicated method
79
+ namespace allows a definition named `architecture` to coexist with the native
80
+ `Architecture` data type. Ordinary adapter functions retain their existing names.
81
+
82
+ Reuse the Symbol context within one example. Checked codecs copy and validate
83
+ native arguments and results; failures panic with the resolved definition name.
84
+ Machine-sized native bindings check the architecture across the complete type,
85
+ including alternatives not selected by the current value. Logical evaluation
86
+ still follows the explicitly selected machine profile.
87
+
88
+ `lawspec_definitions.go` belongs in source directories and does not import Rapid.
89
+ It contains the unit's native entry points and checked logical bodies. Properties
90
+ call the bodies directly; definitions never become user-owned adapter stubs.
91
+ Definitions and properties share typed expression rendering, preserving lazy
92
+ branches, short-circuit guards, single evaluation of match inputs, exact
93
+ arithmetic, and structural equality.
94
+
95
+ The frontend checks structural termination and potentially failing operations.
96
+ Generic definitions specialize to concrete uses. Refined signatures become
97
+ checked contracts, and refinement predicates may call checked definitions.
98
+
99
+ `tools/go-definitions-integration.mjs` checks source-only packages, four rejected
100
+ native type mismatches, both profiles and architecture diagnostics, recursive
101
+ properties, incorrect adapters, custom layouts, compact execution, and
102
+ regeneration protection. Readable definition source matches `gofmt` exactly.
103
+ Compact Go documents retain tabs rather than expanding them into spaces.
104
+
105
+ ## Checked bridges and tests
106
+
107
+ Generated codecs validate both conversion directions and copy mutable payloads.
108
+ An adapter cannot mutate a list, byte slice, or big integer in a test fixture
109
+ through an input alias. Unexpected or nil native variants, invalid scalar
110
+ representations, and cyclic values fail with type/field context. Shared acyclic
111
+ subtrees remain valid. Native machine-sized fields require the selected
112
+ `machineBits` profile to match the Go architecture.
113
+
114
+ Generated equality follows LawSpec semantics, including componentwise floating
115
+ comparison and Symbol identity. It does not substitute Go pointer identity or
116
+ reflection-based equality for structural equality.
117
+
118
+ Rapid generation composes native generators and shrinkers. A structural node
119
+ budget bounds recursive values, reserves each product field's minimum cost,
120
+ and permits list lengths supported by the remaining budget. Empty domains,
121
+ nullary constructors, and nested absence states are handled explicitly.
122
+
123
+ The reusable source files (`lawspec_runtime.go`, `lawspec_schema.go`,
124
+ `lawspec_codecs.go`, and generated data/schema/codec declarations) do not import
125
+ Rapid. Framework-specific generation lives in
126
+ `lawspec_data_strategies_test.go`; generated laws live in `lawspec_test.go`.
127
+
128
+ Native declarations, schema descriptions, codecs, runtime support, and generated
129
+ tests use structured formatting that matches `gofmt`. The bundled examples and
130
+ total-definition fixture are checked against `gofmt` under both machine profiles.
131
+ No external formatter is needed when generating code.
132
+
133
+ The compiler and CLI accept explicit `--minify` for generated output.
134
+ Readable output remains the default; formatting changes preserve adapter ownership
135
+ and edited-file protection. The bundled WASM uses the same layout.
136
+
137
+ Internal typed Core definitions with attached contracts are proved before Go
138
+ emission. Generated logical entry points validate arguments, check preconditions
139
+ in order, validate the result, and check postconditions; native wrappers share
140
+ these checks. The standalone contract fixture exercises both machine profiles
141
+ and formatting modes, including exact division, checked narrowing, nested calls,
142
+ and rejection of deliberately corrupted results. Readable contract bodies match
143
+ `gofmt`. Refined source definition signatures now produce these contracts through
144
+ template proof and specialization.
package/HASKELL.md ADDED
@@ -0,0 +1,171 @@
1
+ # Native Haskell data
2
+
3
+ LawSpec 0.9 emits ordinary parameterized algebraic data types from checked Core
4
+ products and sums. Constructors and record selectors have stable names planned
5
+ across all units. For example:
6
+
7
+ ```lawspec
8
+ unit example.trees
9
+
10
+ type Tree (a :: Type) is
11
+ Leaf value :: a
12
+ Branch children :: List (Tree a)
13
+ end
14
+
15
+ echo :: Tree Int8 -> Tree Int8
16
+ ```
17
+
18
+ The generated `LawSpecData` module supplies `Tree a`, `TreeLeaf`, and
19
+ `TreeBranch`. An adapter can implement identity directly:
20
+
21
+ ```haskell
22
+ echo :: Data.Tree I.Int8 -> Data.Tree I.Int8
23
+ echo value = value
24
+ ```
25
+
26
+ The generated adapter imports `LawSpecData` as `Data` and `Data.Int` as `I`.
27
+ Adapters remain user-owned. Recursive and mutually recursive fields use native
28
+ Haskell recursion; phantom parameters remain in signatures. Empty data types
29
+ have no constructors. They can appear in inhabited containers such as
30
+ `Maybe Empty`, but cannot supply a standalone generated argument.
31
+
32
+ ## Containers and scalar representations
33
+
34
+ | LawSpec | Haskell |
35
+ | --- | --- |
36
+ | `List a` | `[a]` |
37
+ | `Text` | `Data.Text.Text` |
38
+ | `List Char` | `[Char]`, the linked-list representation |
39
+ | `Maybe a` | `Maybe a`, with `Nothing` and `Just` |
40
+ | `Either a b` | `Either a b`, with `Left` and `Right` |
41
+ | `Nullable a` | `LS.Nullable a`, with `NullValue` and `NullableValue` |
42
+ | `Optional a` | `LS.Optional a`, with `UndefinedValue` and `OptionalValue` |
43
+ | `BigInt`, `BigUInt`, `Integer` | `Integer`, with domain checks |
44
+ | `Decimal` | `LS.Decimal`, wrapping an exact finite base-ten `Rational` |
45
+ | `Rational` | `Rational` |
46
+ | `Complex64`, `Complex128` | `Complex Float`, `Complex Double` |
47
+ | `CodePoint` | `Char`, including surrogate code points |
48
+ | `CodeUnit16` | `Word16` |
49
+ | `CodePointText`, `Utf16Text` | `LS.CodePointText [Char]`, `LS.Utf16Text [Word16]` |
50
+ | `Bytes` | `ByteString` |
51
+ | `Symbol` | `LS.Symbol`, with scoped fixture identities |
52
+ | `Unit` | `()` |
53
+ | `Null`, `Undefined` | `LS.Null`, `LS.Undefined` |
54
+
55
+ `Char` and `Text` exclude surrogate code points. Checked codecs reject invalid
56
+ native values rather than replacing characters. `Symbol` equality uses its
57
+ identity; matching descriptions alone do not establish equality. Distinct
58
+ presence wrappers preserve nested absence states. IEEE NaN and signed-zero
59
+ equality remain the same inside containers and custom types.
60
+
61
+ ## Generated support and testing
62
+
63
+ `LawSpecData`, `LawSpecDataSchema`, `LawSpecDataCodecs`, `LawSpecSchema`,
64
+ `LawSpecCodecs`, and `LawSpecRuntime` belong in the source directory. They have no
65
+ property-framework dependency. Native conversion returns contextual failures for
66
+ invalid domains, fields, tags, or arities. Binding machine-sized native types
67
+ requires the selected `machineBits` profile to match the host, including fields
68
+ of unselected variants.
69
+
70
+ `LawSpecDataStrategies` belongs in the test directory and composes native Hedgehog
71
+ generators and shrinkers. Bounded recursive generation reserves every product
72
+ field's minimum size before distributing spare nodes. Lists have variable lengths
73
+ within the available budget. Shrinking uses Hedgehog's choices, integers, and
74
+ lists, retaining schema-valid representations.
75
+
76
+ The Haskell scaffold uses Hspec, Hedgehog, hspec-hedgehog, containers, and mtl in
77
+ its test component. Source and test roots can be customized independently.
78
+ Readable/compact declaration fixtures are covered by
79
+ `tools/haskell-data-integration.mjs`; main compiler output and incorrect adapters
80
+ are covered by `tools/haskell-data-properties.mjs`.
81
+
82
+ ## Formatting
83
+
84
+ Haskell output uses an 80-column layout with spaces for indentation. Runtime
85
+ sources, native declarations, adapter stubs, definitions, and property files are
86
+ readable by default. Explicit `--minify` selects compact documents while retaining
87
+ the layout required by Haskell. Generation uses the same deterministic document
88
+ renderer in native and WASM builds; it does not invoke a downloaded formatter.
89
+
90
+ `tools/haskell-formatting-integration.mjs` checks the bundled corpus at both
91
+ machine widths for line length, tabs, and trailing whitespace. It compares
92
+ readable and compact parsed syntax using `tools/HaskellSyntaxCheck.hs`, built
93
+ against the installed GHC parser. The comparison discards source locations and
94
+ layout annotations while retaining literals, operators, and program structure.
95
+ Set `LAWSPEC_CORE`, `LAWSPEC_GHC`, and `LAWSPEC_HASKELL_SYNTAX_CHECK` to the
96
+ corresponding executables. This is a development check, not a package dependency.
97
+
98
+ ## Total definitions
99
+
100
+ Checked definitions become native functions in `LawSpecDefinitions.<Unit>`:
101
+
102
+ ```lawspec
103
+ unit example.total
104
+
105
+ definition increment (x :: Int8) :: BigInt is x + 1 end
106
+ ```
107
+
108
+ The generated native signature is equivalent to:
109
+
110
+ ```haskell
111
+ increment :: LS.SymbolContext -> I.Int8 -> Either String Integer
112
+ ```
113
+
114
+ Create a context with `LS.newSymbolContext`, then pass it to calls belonging to
115
+ the same example. A repeated Symbol fixture ID has the same identity in that
116
+ context; separate contexts remain distinct even when IDs and descriptions match.
117
+ Codecs preserve the identity of already-scoped native Symbols. Creating the
118
+ context uses IO; evaluating a definition is pure.
119
+
120
+ Native entry points check arguments and results and return contextual `Left`
121
+ diagnostics for invalid native representations. Native machine-sized bindings
122
+ check the whole type, including unselected constructors, against `machineBits`.
123
+ `LawSpecDefinitionBodies` contains the shared logical implementation, which uses
124
+ the configured machine profile independently of the host architecture.
125
+
126
+ Definitions do not create adapter stubs. Their source modules and scalar/schema
127
+ support have no Hspec or Hedgehog dependency. Generated tests allocate a context
128
+ per example, boundary, or property iteration. Properties and definitions share a
129
+ typed expression renderer with lazy guards, exhaustive matching, structural
130
+ equality, checked conversions, and exact integer promotion.
131
+
132
+ `tools/haskell-definitions-integration.mjs` exercises native and property calls,
133
+ both machine profiles, readable/compact definitions, complete minified projects,
134
+ custom source/test roots,
135
+ native type errors, incorrect adapters, generic specialization, and regeneration
136
+ protection. Refined definition signatures are checked before emission and
137
+ enforced at native entry points.
138
+
139
+
140
+ Hspec property files now use structured documents for helpers, examples,
141
+ boundaries/finite cases, native Hedgehog strategies, dependent refinement domains,
142
+ guarded assertions and contract wrappers. Adapter bridges compose checked codecs
143
+ and force argument values before calling native code. Contracts retain lazy
144
+ precondition checks and force the result before checking postconditions. Fresh
145
+ Symbol contexts cover refined properties as well as ordinary native strategies.
146
+ Scalar literals and diagnostic strings now use document-level encoding. Long
147
+ strings concatenate independently escaped chunks; large integers parse exact
148
+ decimal strings with their required Integer type.
149
+
150
+ `tools/haskell-data-properties.mjs` accepts `LAWSPEC_MINIFY=1` and
151
+ `LAWSPEC_MACHINE_BITS=32,64`. Its scalar scenario includes bundled examples and
152
+ shared arithmetic conformance vectors; its refinements scenario includes four
153
+ faulty adapters. Native machine-sized adapter bindings require a matching host
154
+ architecture; the scalar scenario defaults to 64 bits.
155
+
156
+ `tools/haskell-message-integration.mjs` uses native code-point strings and integer
157
+ constants independent of the emitter to check Unicode, escapes, whitespace,
158
+ large signed integers and diagnostic prefixes in readable and compact modes.
159
+ Its executable fixture lines fit within 80 columns. Long metadata comments wrap
160
+ to the output width.
161
+
162
+ Internal typed Core definitions with attached contracts are proved before Haskell
163
+ emission. Generated source checks preconditions after argument validation and
164
+ postconditions after result validation, without property-framework dependencies.
165
+ Checks sequence through Either, so a rejected precondition prevents later
166
+ predicates and the body from running. Results are forced and validated before
167
+ postconditions. Readable contract fixtures fit within 80 columns.
168
+ The shared native fixture passes both machine profiles and formatting modes,
169
+ including exact division, narrowing, nested calls, direct logical entry checks,
170
+ and rejection of corrupted results. Refined source definition signatures now
171
+ produce these contracts through template proof and specialization.
package/JAVA.md ADDED
@@ -0,0 +1,113 @@
1
+ # Java backend (0.9)
2
+
3
+ Java targets Java 25+, JUnit, and JetCheck. The compiler emits native named
4
+ products and sums, checked scalar/data codecs, reusable runtime sources, and
5
+ separate property-test helpers. Native type parameters remain visible in public
6
+ data declarations and adapter signatures.
7
+
8
+ ## Total definitions
9
+
10
+ A unit-level definition supplies its implementation together with its signature:
11
+
12
+ ```lawspec
13
+ unit example.total
14
+
15
+ definition size (xs :: List Int8) :: BigInt is
16
+ match xs with
17
+ | Nil -> 0
18
+ | Cons head tail -> 1 + size tail
19
+ end
20
+ end
21
+ ```
22
+
23
+ The compiler checks the body even when no law uses it. It requires exhaustive
24
+ matching, established structural descent for recursion, and proof that partial
25
+ operations are defined. Calls may target other checked definitions, including
26
+ forward declarations; definitions cannot call external adapters. Generic definitions specialize to concrete uses. Refined signatures become
27
+ checked contracts, and refinement predicates may call checked definitions.
28
+
29
+ Java writes native entry points beneath `lawspec.definitions`, preserving the
30
+ unit's package and class mapping. The example above provides
31
+ `lawspec.definitions.example.Total.size`:
32
+
33
+ ```java
34
+ var symbols = new java.util.HashMap<String, Object>();
35
+ var count = lawspec.definitions.example.Total.size(symbols, java.util.List.of((byte) 1, (byte) 2));
36
+ ```
37
+
38
+ Arguments and results use the same checked native representations as generated
39
+ data codecs: `List<Byte>` and `BigInteger` in this example. Domains without a
40
+ faithful Java representation retain their tagged runtime support values,
41
+ including nested Nullable/Optional states and machine-profile integers. Share
42
+ the Symbol map when fixture IDs should refer to the same identity.
43
+
44
+ `LawSpecDefinitionBodies.java` contains generated checked implementation helpers.
45
+ Generated properties call those same bodies. The native entry points validate
46
+ and copy values through codecs, and invalid native values report the definition
47
+ identity in an `IllegalArgumentException`. Logical machine integers enforce the
48
+ selected 32- or 64-bit range independently of the JVM architecture.
49
+
50
+ These files belong to source directories and have no JUnit or JetCheck dependency.
51
+ Definitions never receive user-owned adapter stubs. External declarations still
52
+ receive stubs, and regeneration preserves edited adapters. Edits to generated
53
+ definition files are protected by the generation manifest.
54
+
55
+ ## Verification and layout
56
+
57
+ `tools/java-definitions-integration.mjs` executes recursive list/tree definitions,
58
+ forward calls, scalars, sums, raw code units, Symbol identity, and nested absence
59
+ under both profiles. It checks custom source/test roots, typed native misuse,
60
+ incorrect adapters, framework-independent compilation, and ownership.
61
+
62
+ Readable generated sources and tests use structured formatting that matches
63
+ Google Java Format. `tools/java-formatting-integration.mjs` checks all bundled
64
+ examples and the total-definition fixture under both machine profiles. The
65
+ compiler emits this layout directly; generation does not invoke a formatter.
66
+ JetCheck combinators retain native shrinking and the existing scalar domains.
67
+
68
+ The CLI/API accept explicit minify. Native integration checks run
69
+ both readable and fully minified generation plans, including properties and
70
+ contracts. Independent Java execution checks preserve long diagnostics,
71
+ supplementary Unicode, escaping and arbitrary integers when literals wrap.
72
+ The bundled WASM package is checked against the native compiler.
73
+
74
+
75
+ For internal checked Core definitions, shared JVM implementation bodies now
76
+ prove attached contracts before emission and enforce ordered preconditions and
77
+ validated-result postconditions at runtime. Native wrappers and direct logical
78
+ entry points both use those checks. `tools/jvm-definition-contract-integration.mjs`
79
+ verifies both JVM languages, profiles and layouts without a test-framework
80
+ dependency, including corrupted-result rejection. Refined source signatures
81
+ now produce these contracts through template proof and specialization.
82
+
83
+
84
+ ## Constructor contracts
85
+
86
+ Public Java generation supports typed constructor callbacks, context-aware codecs
87
+ and definition boundaries. Property emission supplies validated witnesses and one
88
+ Symbol context shared by generation, adapter conversions and assertions.
89
+ Required conjunctive Symbol equalities can use fixture/prior-input values;
90
+ equalities beneath disjunctions contribute candidates without restricting the
91
+ whole domain to one alternative.
92
+
93
+ The test helper's `checkedGenerator` composes JetCheck generators with native
94
+ `suchThat` filtering at nested and outer value boundaries. False predicates reject
95
+ candidates; predicate evaluation errors are retained for the property to report.
96
+ Each filter respects the smaller of `maxAttempts` and JetCheck 0.3's native
97
+ 100-attempt limit. The counter for smaller budgets is recreated on replay, so
98
+ native filtering still discards invalid shrinks. Validated witnesses contribute typed nested seeds. Sampled seeds
99
+ can limit payload shrinking; native list and constructor generation remains an
100
+ alternative, and shrinking does not promise a globally minimal counterexample.
101
+
102
+ `tools/java-checked-strategies.mjs` verifies valid generation/shrinking, nested
103
+ witness use, exhaustion, error classification and shared Symbol identity at both
104
+ machine widths, with compiled behavioral mutants. These helpers depend on
105
+ JetCheck; the value/schema/codec runtime remains framework-independent.
106
+
107
+ Constructor-contract properties run the requested case count as one-iteration
108
+ JetCheck sessions with increasing size hints. This preserves native shrinking and
109
+ avoids session-wide draw-uniqueness exhaustion for fixture-identity domains. It
110
+ does not claim those domains are finite; domains proven finite by Core retain
111
+ exhaustive cases. `tools/java-field-properties.mjs` executes public generation at
112
+ both widths and layouts, including custom placement, adapter mutants, disjunctive
113
+ Symbol candidates and generation-time evaluator errors.