Feat/runner native decimal slice3#443
Merged
Merged
Conversation
…at-base spec)
The discriminating 3-leg (TS/Python/runner) spec for runner-native Decimal
slice 3 — the PRODUCER / WRITE path. Defines "done" before any impl and keeps
the builder honest: 26 producer value cases (sub/neg/abs/div/mod/pow + nesting)
asserting refOut === tsOut === pyOut byte-exact, plus re-admit fail-close and
abstain regimes.
Expecteds COMPUTED under the pinned prec-28 / ROUND_HALF_EVEN / modulo-ROUND_DOWN
context (never guessed). Killers (each RED-at-base for the right reason — the
runner abstains on the unimplemented producers; the abstain cases already pass):
- div(1,3)=28 threes (kills host-float), div(2,3)=…667 (kills ROUND_DOWN)
- mod(5.5,2)=1.5 (kills int-truncation), mod(-5.5,2)=-1.5 & mod(5.5,-2)=1.5
(sign-of-dividend — kills floored-mod)
- pow(2,-1)=0.5 (negative integer exp allowed), pow(0,0)=1 (0**0 special-case)
- pow(0,-1) MUST throw POW_ZERO_NEGATIVE (kills using decimal.js .pow directly,
which yields Infinity instead of the kernel guard)
- pow(of("2"), d) with a variable exponent MUST throw POW_NON_INTEGER — THE
soundness-critical guard-in-seam case: slice-2 variable operands mean a naive
impl would resolve d and compute a value; the runner must replicate the
compile-gate and refuse exactly what the emitters refuse
- literal-zero divisor refuses BEFORE an abstaining sibling operand evaluates
(forces the syntactic gate into the pre-eval phase)
- neg(0)/sub(3,3)/mod(-4,2)=0 (signed-zero clamp via kernDecimalStr)
⚔️ Forged by [Agon](https://github.com/KERNlang/agon)
Co-Authored-By: agon (KERN) <292465531+KERN-Agon@users.noreply.github.com>
…guarded div/mod/pow
Make the ReferenceRunner EXECUTE the Decimal producer/write path natively as the
3rd leg of 3-way parity, computing on a LOCAL pinned context (prec 28,
ROUND_HALF_EVEN, modulo ROUND_DOWN via makeKDecimal() — never global Decimal.set()).
- NEW framework-free packages/core/src/decimal/probe-gates.ts: the SINGLE source of
the syntactic compile-gates (assertPortableDecimalPow / assertNonZeroDecimalDivisor /
decimalOfLiteralValue + fail-close messages), generic over a DecimalProbeAccessor.
codegen/decimal-contract.ts re-exports thin adapters (ts-morph accessor) so emitter
output stays BYTE-IDENTICAL; the runner imports the same shared impls with a ValueIR
accessor. One gate source, two typed accessors — drift-safe. Keeps the browser-spine
pin at exactly 5 typescript importers (probe-gates imports only the framework-free
kernel contract).
- portable-scalar.ts: RUNNER_DECIMAL_VALUE_METHODS extended to
{of,add,mul,sub,neg,abs,div,mod,pow}; evalDecimalNode runs 3 phases — (A) syntactic
gates on raw arg nodes BEFORE eval, (B) L-to-R operand eval with arity dispatch,
(C) kernel guards kDecimalDiv/Mod/PowInt (never decimal.js .div/.pow). The pow gate
REFUSES a variable/computed/non-integer-literal exponent and a negative base; a bound
variable exponent therefore fails closed instead of being silently computed.
- expression-v1.ts: re-admit classifier broadened from the literal-scale fail-close
only to ALL kernel decimal fail-close families (exact-prefix match), so referenceRun
surfaces the byte-identical message for div/mod-by-zero and pow refusals while every
non-fail-close throw still abstains.
Controller corrections on top of the build:
- Fixed an oracle bug: (1/3)*3 under prec-28 is 0.999…9 (28 nines), NOT 1 — corrected
the frozen fixture + comment. This kills both a host-float impl AND any "saturated
unity" normalization that would diverge the runner from the two emitted legs.
- Evolved a now-stale slice-1 fixture: Decimal.div is IN-slice as of slice-3, so the
"out-of-slice method" rejection example moved to Decimal.sqrt.
Gate green: 3-leg producer oracle (26 computed-exact value cases + re-admit/abstain
regimes), all 3 emission byte-identical locks, expression-v1 contract, browser-spine
pin=5.
⚔️ Forged by [Agon](https://github.com/KERNlang/agon)
Co-Authored-By: agon (KERN) <292465531+KERN-Agon@users.noreply.github.com>
…nt parity
Coverage hardening from the full-roster impl-review (no soundness bug found; these
close two gaps the green gate didn't exercise):
- -0 RESIDUE (3-leg value cases): mul/abs can yield a sign-bearing zero (decimal.js
.s=-1; Python str(Decimal("0")*Decimal("-1")) == "-0"). All three render paths clamp
to unsigned "0" — decimal.js native .toString, the runner's kernDecimalStr isZero-clamp,
and Python's _kern_decimal_str is_zero-clamp. mul(0,-1) is the discriminator: Python's
RAW str() leaks "-0", so the fixture proves the Python clamp is load-bearing (a
regression dropping it would diverge the Py leg while TS+runner stay "0").
- TRANSPARENT-WRAPPER exponent (runner pow-gate): a wrapped exponent `Decimal.of("3") as
Decimal` is not a provable integer literal — verified the emitters refuse it
(POW_NON_INTEGER), and the runner's gate, reading the SAME raw arg node, refuses
identically. Guards the recurring wrapper operand-bypass class.
Gate still green: slice-3 oracle 55 cases + emission byte-identical locks + expression-v1
+ browser-spine pin=5.
⚔️ Forged by [Agon](https://github.com/KERNlang/agon)
Co-Authored-By: agon (KERN) <292465531+KERN-Agon@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Why
How
Checklist
tsc -bpassespnpm testpassespnpm test:kernpassespnpm lintpasseskern review packages/ --recursivechecked