# Define numeric diagnostics and acceptance evidence Label: wayfinder:grilling Type: grilling Status: ready-for-human Wayfinding state: resolved Assignee: Codex Blocked by: 07 Parent: [Find the ASPL numeric type expansion specification](https://github.com/mohammed-najib/project_language/blob/4261eb11728d7d66bd16865454104711383f7e09/.scratch/aspl-numeric-types/map.md) ## Question Which diagnostics, bilingual examples, documentation changes, and focused acceptance checks make this numeric expansion precise enough to hand off for implementation? Define the distinction between checking errors, ASPL traps, and recoverable parsing/conversion failures, with useful source locations and numeric type/range information. Select evidence for each width boundary, `f32` rounding, full-range `u64`, mixed expressions, bitwise/shift edge cases, compact list storage and independent copies, numeric text round trips, and invalid bytecode. Cover direct execution, generated native programs, the online playground, and ASPL Console's existing workflow without requiring an exhaustive host matrix. Identify current examples and documentation that must change, preserve existing useful behavior, and confirm that every requirement has an acceptance obligation. Close or graduate the remaining in-scope fog before declaring the map complete; implementation and publication remain separate work. ## Answer Resolved with the user on 2026-09-19. ASPL 0.4.0 keeps numeric checking errors, runtime traps, recoverable numeric-text failures, bytecode load failures, and host or resource outcomes distinct. Their structured records preserve exact numeric types and full-width values before Arabic or English rendering. A focused development record traces every numeric requirement to acceptance evidence without turning this work into release certification. The user explicitly requires a clean break. No production user depends on the current development implementation, so compatibility with ASPL 0.3.0, bytecode version 3, or the current numeric trap layout is not an objective. ### Clean version boundary ASPL 0.4.0 uses bytecode version 4 and browser-result wire version 3. Version 4 loaders reject every other bytecode version. Browser-result wire version 3 replaces version 2 where the expanded trap metadata changes the record. The implementation adds no old-bytecode reader, result-wire compatibility path, trap-reason alias, migration fixture, or dual representation. The narrow `invalid-f64-to-i64-conversion` trap disappears. Version 4 uses the general `invalid-numeric-conversion` trap. Bitwise and shift fixtures that currently prove those tokens invalid become positive or edge-case fixtures under the new grammar. Historical release manifests and evidence stay unchanged as records of their own versions; they do not constrain the new development implementation. ### Failure boundaries The following categories do not substitute for one another: | Situation | Outcome | Program-visible recovery | | --- | --- | --- | | Malformed or out-of-range source literal, unsupported numeric operator, mixed already-typed operands, or invalid conversion operand type | checking error with an ASPL diagnostic | none; compilation fails | | Reached integer overflow, zero divisor, invalid shift count, or value-dependent invalid explicit conversion | ASPL trap | none; execution stops | | Malformed or out-of-range runtime text passed to a numeric parser | failed `result[T]` | ordinary result branching | | Malformed, inconsistent, or wrong-version bytecode | load failure | none inside the ASPL program | | Memory or instruction limit, cancellation, allocator failure, or host failure | its existing non-trap execution outcome | none inside the ASPL program | An explicit checked numeric conversion is not recoverable. A well-typed conversion that cannot represent its reached value raises an ASPL trap. Only the `parse_T` numeric-text builtins return recoverable numeric failures. ### Checking diagnostics Numeric diagnostics retain the existing structured ASPL diagnostic contract: a stable reason, severity, typed arguments, a primary source span, ordered secondary spans, and bilingual rendering. Canonical numeric type arguments use `i8`, `i16`, `i32`, `i64`, `u8`, `u16`, `u32`, `u64`, `f32`, and `f64` regardless of which source alias was written. Operators, reason keys, type names, classifications, bounds, and numeric values remain canonical ASCII technical fields in both catalogs. The renderer quotes and directionally isolates them and writes all digits as ASCII. The numeric source reasons are: - `invalid-numeric-literal` retains its existing identity and bilingual wording. Its `spelling` argument contains the complete invalid candidate. - `numeric-literal-out-of-range` has two exact record shapes. An integer record carries `spelling`, `type`, `minimum`, and `maximum`, with exact inclusive decimal bounds able to represent the full `u64` range. A floating record carries `spelling`, `type`, and the `finite-overflow` classification. - `type-mismatch` continues to report different already-typed operands and every other exact-type boundary. Numeric contexts include binary operand, assignment, initializer, argument, return, record field, list element, indexed replacement, result payload, and explicit conversion. - `numeric-operator-not-supported` is a new reason for a numeric type that does not provide the written operator. It carries `operator` and `type`. Examples include unary minus on an unsigned value, remainder on a floating value, and bitwise or shift operations on a floating value. The fixed new or revised catalog text is: | Reason shape | Arabic | English | | --- | --- | --- | | Integer `numeric-literal-out-of-range` | `القيمة {spelling} خارج مجال النوع {type} من {minimum} إلى {maximum}.` | `{spelling} is outside the range of type {type}, {minimum} through {maximum}.` | | Floating `numeric-literal-out-of-range` | `القيمة {spelling} تتجاوز المجال المنتهي للنوع {type}.` | `{spelling} exceeds the finite range of type {type}.` | | `numeric-operator-not-supported` | `المعامل {operator} غير معرّف للنوع {type}.` | `Operator {operator} is not defined for type {type}.` | A malformed or out-of-range literal uses the complete numeric candidate as its primary span. A directly applied unary minus joins the literal for range reporting, so a signed minimum or an out-of-range negative value points to the complete negative expression. An unsupported operator or mixed-type binary expression uses the operator token as primary and labels the operand expressions as ordered secondary spans with their canonical types. An invalid explicit-conversion operand uses the argument expression as primary and the target type token as secondary. Source-stage recovery, ordering, duplicate removal, diagnostic caps, safe excerpts, and Arabic-default versus explicitly selected English behavior do not change. ### Runtime traps and locations The numeric trap reasons and ordered machine fields are: ```text integer-overflow: type= operation= operand-count= operands=[...] integer-zero-divisor: type= operation= dividend= invalid-shift-count: left-type= count-type= count= width= invalid-numeric-conversion: source-type= target-type= classification= source-value= ``` For a floating conversion source, `source-bits` replaces `source-value`. It uses exactly eight lowercase hexadecimal digits for `f32` and sixteen for `f64`, after a `0x` prefix. Integer fields retain exact signed or unsigned mathematical values. They never pass through a signed representation that changes a `u64` value. Conversion classifications are `below-range`, `above-range`, `nan`, `positive-infinity`, and `negative-infinity`. The renderer retains the localized Arabic or English trap shell, while reason keys, field names, operations, canonical types, classifications, decimal values, and hexadecimal bits remain the same technical text in either language. Browser-result wire version 3 carries raw 64-bit words plus type and signedness metadata. JavaScript reconstructs them with `BigInt`; it never converts a diagnostic integer through `Number`. Direct CLI execution and the online playground map a reached numeric trap to the complete responsible expression, with the existing bounded call trace. Generated native programs retain the function name and function-relative instruction index because their bytecode contains no source map. A source map remains out of serialized bytecode and the generated executable. ### Recoverable numeric-text failures Each `parse_T` builtin retains the existing `result[T]` shape. A malformed complete spelling returns code `invalid-number`; a grammatically valid value outside the target range returns `number-out-of-range`. The failure is an ordinary value, so it has no source span, trace, or diagnostic record. Arabic and English aliases return identical values. Messages are deterministic ASCII across hosts and aliases: - malformed text uses `invalid number for T`, such as `invalid number for u8`; - an integer range failure uses `number out of range for T (MIN through MAX)`, with exact decimal bounds; and - a floating range failure uses `finite number out of range for T`. Programs branch on the stable code rather than the message. The result type and the selected parser identify the target even if a program discards the message. ### Documentation and examples The implementation updates the canonical authoring inputs `browser/documentation-content.json` and `browser/documentation-examples.json`, then regenerates the browser data and Arabic and English pages through the existing generators. Generated files are not edited as independent sources. The reference material must update: - the storable type inventory and all ten Arabic and English aliases; - numeric literal grammar, inference, exact-type operators, conversions, and the absence of implicit conversion; - arithmetic, bitwise, shift, floating, parsing, formatting, aggregate, and compact-list contracts; - numeric diagnostic reasons, trap fields, recoverable parse codes, and the outcome distinctions above; - ASPL 0.4.0, bytecode version 4, and browser-result wire version 3 where the development documentation exposes them; and - the unchanged `i64` boundaries for indexes, lengths, Unicode operations, `start_main`, and the existing foreign profiles. Keep the existing `sum` and general diagnostic examples as simple baselines. Add `numeric-types.ar.aspl`, `numeric-types.en.aspl`, and an independently authored `numeric-types.mixed.aspl`. Together they demonstrate the paired type aliases, English and Arabic radix forms, full-range `u64`, direct `f32` rounding, explicit conversion, bitwise operations, shifts, and independent `list[u8]` copies. Extend the existing parse-integer, parse-float, list, and list-mutation examples to cover a narrow type while retaining useful `i64` and `f64` coverage. The Arabic and English reference text uses this contrast to teach the outcome boundary: ```aspl let byte: u8 = 256; // checking error: numeric-literal-out-of-range let converted = u8(256); // valid source; traps if executed let parsed = parse_u8("256"); // ordinary failed result: number-out-of-range ``` A contributor-only example corrupts version 4 bytecode and demonstrates `load-failure / invalid-bytecode`. The documentation also states that limits, cancellation, allocation failure, and host failure remain separate outcomes. It does not call any of these outcomes exceptions. ASPL Console documentation continues to describe its CLI launch, selected file working directory, diagnostic-language selection, and separate standard streams. This effort updates development docs and generated local site output; it does not publish or deploy ASPL 0.4.0, alter release history, or claim a release. ### Focused development acceptance record Implementation creates `conformance/numeric-focused-0.4.md`. It is a development traceability record, not release evidence and not a replacement for the archived 0.1.1 manifest. Each normative rule in this map's decisions must link to at least one named obligation, exact fixture or generated table, oracle, and focused test target. | ID | Acceptance obligation | | --- | --- | | `NT01` | Arabic and English type aliases, radix forms, separators, precedence, and invalid numeric candidates | | `NT02` | Contextual literal inference, defaults, direct signed minima, full-range `u64`, and range diagnostics | | `NT03` | Typed arithmetic, comparisons, equality, checked overflow, division, and remainder | | `NT04` | Fixed-width complement, bitwise operations, shifts, and invalid counts | | `NT05` | Binary32 and binary64 rounding, subnormals, zeros, infinities, canonical NaNs, and comparisons | | `NT06` | Every conversion category, boundary classification, evaluation order, and runtime timing | | `NT07` | Absence of implicit conversion across expressions, assignments, calls, returns, records, lists, and results | | `NT08` | All per-type parse and format builtins, recoverable failures, extrema, and round trips | | `NT09` | Existing `i64` interfaces, foreign profiles, aggregates, and exact stored types | | `NT10` | Exact-width numeric-list storage, capacity accounting, copying, nesting, mutation, and reclamation | | `NT11` | Allocation failure, memory limits, cancellation, and absence of partial mutation | | `NT12` | Bytecode version 4 type identities, constants, serialization, version rejection, and lossless loading | | `NT13` | Validator rejection, runtime-only failures, instruction charging, and defensive VM failures | | `NT14` | Structured checking diagnostics, trap payloads, recoverable results, and outcome-class separation | | `NT15` | Direct CLI and generated-native success, failure, location, and payload parity | | `NT16` | WebAssembly worker and playground value, payload, source-map, and `BigInt` transport parity | | `NT17` | ASPL Console's existing CLI launch, working-directory, language, and stream workflow | | `NT18` | Bilingual documentation, checked examples, generated-site parity, and development version accuracy | ### Shared semantic and storage matrix Table-driven shared compiler, validator, VM, and resource checks cover: - every integer type at its minimum and maximum, one below and one above, with negative one included for every unsigned type; - decimal, hexadecimal, binary, and representative Arabic-radix forms; - arithmetic boundaries, zero divisors, and every signed minimum divided or remaindered by negative one; - complement, AND, OR, XOR, and shifts by zero, width minus one, negative one, width, and width plus one; - every integer source and target conversion pair at meaningful successful and failing boundaries; - both floating widths at positive and negative zero, the smallest subnormal, the normal and subnormal boundary, finite extrema, infinities, canonical NaNs, and primitive-operation rounding points; - direct decimal rounding of `1.0000000596046448` to binary32 bits `0x3f800001`, contrasted with conversion through binary64 to `0x3f800000`; - every parse and format pair at integer extrema, floating finite round trips, negative zero, subnormals, infinities, canonical NaNs, malformed text, and finite overflow; - exact types through bindings, calls, returns, records, lists, and successful results, with representative rejection of mixed already-typed values; and - every compact numeric-list backing at empty, exact-capacity, spare-capacity, and one-growth states in native and WebAssembly test builds. The compact-list accounting seam proves logical length, capacity, scalar-width element charge, and fixed charge directly. It also covers one shared copy before mutation, two independently charged compact backings afterward, nested numeric lists, records and results retaining a list, reclamation, old-plus-new peak charging, injected allocation failure, configured memory exhaustion, cancellation, and no partial mutation. A representative `list[u8]` source program supplies public integration evidence; total program memory and C structure sizes are not compactness oracles. ### Bytecode rejection and runtime timing Focused validator cases cover every rejection class rather than every possible corrupt byte sequence: - bytecode version 3 and every non-version-4 input; - a corrupted fixed numeric type identity or type descriptor; - noncanonical or out-of-width signed and unsigned constants; - noncanonical binary32 and binary64 NaNs; - disagreement between a constant, load, register, or aggregate destination; - illegal arithmetic, comparison, equality, bitwise, shift, and conversion types; - noninteger shift counts and nonnumeric conversion endpoints; - mismatched numeric parse or format operations; - exact-type violations in calls, returns, records, lists, and results; and - malformed full-range `u64` transport. A separate pair of cases proves that well-typed bytecode with a constant invalid shift count or failing numeric conversion loads successfully and traps only if execution reaches the instruction. No compatibility corpus, exhaustive malformed-input matrix, or long fuzz campaign is required. ### Cross-path fixtures The repeated public-path corpus stays small: - `numeric-success` combines aliases, `u64` maximum parsing and formatting, the direct `f32` rounding discriminator, explicit conversion, bitwise operations, shifts, and independent `list[u8]` copies. - `numeric-range-check` rejects an out-of-range contextual literal and checks the complete bilingual record and source span. - `numeric-mixed-check` rejects two already-typed different numeric operands and checks the operator primary span and operand secondary spans. - `numeric-u64-overflow` checks unsigned trap transport above both `2^63 - 1` and JavaScript's exact `Number` range. - `numeric-shift-trap` uses a count equal to the left width. - `numeric-conversion-trap` checks the general conversion reason and one exact classification. - `numeric-zero-divisor` checks the enriched existing trap payload. Direct CLI checks and the actual production WebAssembly worker run the success fixture, both checking failures, and all four trap fixtures. Generated native programs run the success fixture and all four traps, verifying unmapped function and instruction locations. The browser harness checks native and WebAssembly bytecode parity, structured records, source mapping, exact `BigInt` reconstruction, and the public playground presentation. These are representative path checks; the shared harness owns the complete type matrix. ASPL Console runs one short, environment-supported smoke that selects and launches the numeric success example through its existing CLI workflow. It does not implement or retest numeric semantics inside Qt. ### Completion policy The shared focused suite, direct CLI, generated native programs, production WebAssembly worker and playground, documentation checks, site parity, and the focused 0.4 record must pass. One available headless browser is sufficient. The Qt Console smoke runs when its build and display environment are available; an unavailable check is recorded as unavailable and does not block the development handoff. The final implementation report names ASPL 0.4.0 and bytecode version 4, lists the exact commands and focused checks that completed, and records any environment-dependent check that could not run. It never describes an unrun check as passed or a development build as published. The full historical conformance suite, release evidence, clean-system matrix, publication, deployment, repeated browser matrix, compatibility testing, performance qualification, and multi-hour fuzzing remain outside this effort. The map has no remaining in-scope fog. Its resolved tickets and named decision pointers are the implementation-ready specification; no duplicate monolithic specification is required.