@nudojs/core 1.14.1 → 1.15.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/dist/index.js CHANGED
@@ -74,7 +74,7 @@ import {
74
74
  takeInterfaceDiagsSince,
75
75
  takeRefineDiags,
76
76
  takeRefineDiagsSince
77
- } from "./chunk-4GZPH6YL.js";
77
+ } from "./chunk-47UPDZHE.js";
78
78
  import {
79
79
  $add,
80
80
  $arguments,
@@ -190,6 +190,7 @@ import {
190
190
  CONSTRAINT_BUILDER_NAMES,
191
191
  CONSTRAINT_EXPR_RE,
192
192
  DEFAULT_MAX_LOOP_ITERS,
193
+ DIAG,
193
194
  FORK_TRUNCATION_LABEL,
194
195
  HOST_EFFECT_LABEL_PREFIX,
195
196
  LOOP_TRUNCATION_LABEL,
@@ -535,7 +536,7 @@ import {
535
536
  withExecPhi,
536
537
  withInvariantSpecs,
537
538
  withVar
538
- } from "./chunk-JMOQEJTD.js";
539
+ } from "./chunk-NUTYUT3I.js";
539
540
 
540
541
  // src/environment.ts
541
542
  function createEnvironment(parent, bindings = /* @__PURE__ */ new Map()) {
@@ -657,7 +658,7 @@ function checkArg(arg, expect, phi = pTrue) {
657
658
  if (arg.shape.k === "unknown" && !arg.term) {
658
659
  return {
659
660
  severity: "warning",
660
- code: "nudo:arg-opaque",
661
+ code: DIAG.argOpaque,
661
662
  message: `argument type is unknown; cannot verify constraint ${predToString(expect)}`,
662
663
  suggestion: "add a call site or @nudo:case, or provide preconditions via --assume"
663
664
  };
@@ -671,7 +672,7 @@ function checkArg(arg, expect, phi = pTrue) {
671
672
  if (ok === false) {
672
673
  return {
673
674
  severity: "error",
674
- code: "nudo:constraint-violated",
675
+ code: DIAG.constraintViolated,
675
676
  message: `argument ${JSON.stringify(lvR.value)} does not satisfy ${predToString(expect)}`,
676
677
  suggestion: `use a value satisfying the constraint, or relax the function precondition`
677
678
  };
@@ -679,7 +680,7 @@ function checkArg(arg, expect, phi = pTrue) {
679
680
  }
680
681
  return {
681
682
  severity: "warning",
682
- code: "nudo:constraint-unproven",
683
+ code: DIAG.constraintUnproven,
683
684
  message: `cannot prove the argument satisfies ${predToString(expect)}`,
684
685
  suggestion: `not enough information; use --assume or add a case`
685
686
  };
@@ -708,7 +709,7 @@ function checkCall(source, fnName, args, phi = pTrue) {
708
709
  if (!g) {
709
710
  diags.push({
710
711
  severity: "error",
711
- code: "nudo:fn-not-found",
712
+ code: DIAG.fnNotFound,
712
713
  message: `function ${fnName} not found`
713
714
  });
714
715
  return diags;
@@ -716,7 +717,7 @@ function checkCall(source, fnName, args, phi = pTrue) {
716
717
  if (args.length !== g.params.length) {
717
718
  diags.push({
718
719
  severity: "error",
719
- code: "nudo:arg-count",
720
+ code: DIAG.argCount,
720
721
  message: `${fnName} expects ${g.params.length} argument(s), got ${args.length}`,
721
722
  fn: fnName
722
723
  });
@@ -731,7 +732,7 @@ function checkCall(source, fnName, args, phi = pTrue) {
731
732
  if (g.symbolic.conf === "partial" || g.symbolic.conf === "opaque") {
732
733
  diags.push({
733
734
  severity: "info",
734
- code: "nudo:partial-result",
735
+ code: DIAG.partialResult,
735
736
  message: `${fnName}(...) result confidence ${g.symbolic.conf}`,
736
737
  suggestion: "add a call site or constraint to improve precision",
737
738
  fn: fnName
@@ -1499,7 +1500,7 @@ function interfaceDriftIssues(candidates, callRecords, evalResult) {
1499
1500
  if (leqAbs(today2, expected2).ok && leqAbs(expected2, today2).ok) continue;
1500
1501
  out.push({
1501
1502
  severity: "warning",
1502
- code: "nudo:interface-drift",
1503
+ code: DIAG.interfaceDrift,
1503
1504
  message: `${cand.fnName}[${param}]: persisted @generated segment \u2260 today's call-site domain`,
1504
1505
  actual: formatAbs(today2),
1505
1506
  expected: formatConstraint(constraint),
@@ -1524,7 +1525,7 @@ function interfaceDriftIssues(candidates, callRecords, evalResult) {
1524
1525
  if (leqAbs(today, expected).ok && leqAbs(expected, today).ok) continue;
1525
1526
  out.push({
1526
1527
  severity: "warning",
1527
- code: "nudo:interface-drift",
1528
+ code: DIAG.interfaceDrift,
1528
1529
  message: `${cand.fnName}[return]: persisted @generated segment \u2260 today's inferred return`,
1529
1530
  actual: formatAbs(today),
1530
1531
  expected: formatConstraint(retC),
@@ -1725,7 +1726,9 @@ function moduleMapId(m) {
1725
1726
  function checkMemoKey(filePath, source, identityOpts, deps, sidecarFp) {
1726
1727
  return [
1727
1728
  hashSource(source),
1728
- filePath,
1729
+ // filePath 过 stablePathKey 归一(与依赖索引/逐出同口径):同一文件的
1730
+ // 裸路径与 file:// URL 两种形态不得各占一条 memo 条目(命中率损耗)。
1731
+ stablePathKey(filePath),
1729
1732
  `${loadModuleId(identityOpts.loadModule)}:${identityOpts.fromFile ?? ""}`,
1730
1733
  deps.fp,
1731
1734
  sidecarFp ?? "-",
@@ -1943,7 +1946,7 @@ function structuralAssignIssues(records) {
1943
1946
  if (!leq.ok) {
1944
1947
  out.push({
1945
1948
  severity: "error",
1946
- code: "nudo:assign-mismatch",
1949
+ code: DIAG.assignMismatch,
1947
1950
  message: `${r.name}: assignment \u22AD existing shape`,
1948
1951
  actual: formatAbs(r.next),
1949
1952
  expected: formatAbs(r.prev),
@@ -2086,7 +2089,7 @@ function scanCaseInconsistency(source, knownFns, opts) {
2086
2089
  const field = fieldPath.join(".");
2087
2090
  out.push({
2088
2091
  severity: "error",
2089
- code: "nudo:case-inconsistency",
2092
+ code: DIAG.caseInconsistency,
2090
2093
  message: `${fnName} case "${caseName}": witness \u22AD contract`,
2091
2094
  actual: formatAbs(arg),
2092
2095
  expected: `missing field ${field}`,
@@ -2110,7 +2113,7 @@ function scanCaseInconsistency(source, knownFns, opts) {
2110
2113
  const paramName = entry.param || paramNames[idx] || `arg${idx}`;
2111
2114
  out.push({
2112
2115
  severity: "error",
2113
- code: "nudo:case-inconsistency",
2116
+ code: DIAG.caseInconsistency,
2114
2117
  message: `${fnName} case "${caseName}": witness \u22AD contract`,
2115
2118
  actual: formatAbs(arg),
2116
2119
  expected: formatConstraint(entry.constraint),
@@ -2126,7 +2129,7 @@ function scanCaseInconsistency(source, knownFns, opts) {
2126
2129
  const paramName = entry.param || paramNames[idx] || `arg${idx}`;
2127
2130
  out.push({
2128
2131
  severity: "error",
2129
- code: "nudo:case-inconsistency",
2132
+ code: DIAG.caseInconsistency,
2130
2133
  message: `${fnName} case "${caseName}": witness \u22AD contract`,
2131
2134
  actual: formatAbs(arg),
2132
2135
  expected: formatConstraint(entry.constraint),
@@ -2148,7 +2151,7 @@ function scanCaseInconsistency(source, knownFns, opts) {
2148
2151
  const paramName = entry.param || paramNames[idx] || `arg${idx}`;
2149
2152
  out.push({
2150
2153
  severity: "error",
2151
- code: "nudo:case-inconsistency",
2154
+ code: DIAG.caseInconsistency,
2152
2155
  message: `${fnName} case "${caseName}": witness \u22AD contract`,
2153
2156
  actual: formatAbs(arg),
2154
2157
  expected: predToString(p),
@@ -2375,7 +2378,7 @@ function sidecarDiagIssues(diags) {
2375
2378
  const k = `${d.code}\0${d.message}`;
2376
2379
  if (seen.has(k)) continue;
2377
2380
  seen.add(k);
2378
- const severity = d.code === "nudo:contract-syntax" || d.code === "nudo:directive-syntax" ? "warning" : "error";
2381
+ const severity = d.code === DIAG.contractSyntax || d.code === DIAG.directiveSyntax ? "warning" : "error";
2379
2382
  out.push({ severity, code: d.code, message: d.message });
2380
2383
  }
2381
2384
  return out;
@@ -2397,7 +2400,7 @@ function assumePremisesPhiOf(name, source, file, issues) {
2397
2400
  if (seg.kind === "bad") {
2398
2401
  issues.push({
2399
2402
  severity: "error",
2400
- code: "nudo:assume-invalid",
2403
+ code: DIAG.assumeInvalid,
2401
2404
  message: `${name}: malformed @nudo:assume '${seg.raw}' (expected <param> <= <param> or <param> >= <param>; constant bounds belong to sidecar contracts)`,
2402
2405
  actual: seg.raw,
2403
2406
  expected: "<param> <= <param>",
@@ -2410,7 +2413,7 @@ function assumePremisesPhiOf(name, source, file, issues) {
2410
2413
  if (bad.length > 0) {
2411
2414
  issues.push({
2412
2415
  severity: "error",
2413
- code: "nudo:assume-invalid",
2416
+ code: DIAG.assumeInvalid,
2414
2417
  message: `${name}: @nudo:assume name(s) not bound as parameters or top-level locals (${bad.join(", ")})`,
2415
2418
  actual: bad.join(", "),
2416
2419
  expected: surface || "(no params/locals)",
@@ -2441,7 +2444,7 @@ function invariantSpecsOf(name, source, file, issues) {
2441
2444
  if (seg.kind === "bad") {
2442
2445
  issues.push({
2443
2446
  severity: "warning",
2444
- code: "nudo:invariant-invalid",
2447
+ code: DIAG.invariantInvalid,
2445
2448
  message: `${name}: malformed @nudo:invariant '${seg.raw}' (expected <name><path> <rel> <number>; path = [*] or .member steps)`,
2446
2449
  actual: seg.raw,
2447
2450
  expected: "<name><path> <rel> <number>",
@@ -2453,7 +2456,7 @@ function invariantSpecsOf(name, source, file, issues) {
2453
2456
  if (!bindable.has(seg.name)) {
2454
2457
  issues.push({
2455
2458
  severity: "warning",
2456
- code: "nudo:invariant-invalid",
2459
+ code: DIAG.invariantInvalid,
2457
2460
  message: `${name}: @nudo:invariant name not bound as a parameter or top-level local (${seg.name})`,
2458
2461
  actual: seg.name,
2459
2462
  expected: surface || "(no params/locals)",
@@ -2592,7 +2595,7 @@ function checkSourceInner(filePath, source, file, phi, opts, issues, signatures,
2592
2595
  const loc = findFnLoc(file, name);
2593
2596
  issues.push({
2594
2597
  severity: entryThrowsMode === "warning" ? "warning" : "error",
2595
- code: "nudo:entry-may-throw",
2598
+ code: DIAG.entryMayThrow,
2596
2599
  message: `${name} (export): may throw ${gateDisplay}`,
2597
2600
  actual: `${name}(\u2026) throws ${gateDisplay}`,
2598
2601
  expected: "entry total, or @nudo:throws / try-catch",
@@ -2617,7 +2620,7 @@ function checkSourceInner(filePath, source, file, phi, opts, issues, signatures,
2617
2620
  }
2618
2621
  issues.push({
2619
2622
  severity: "warning",
2620
- code: "nudo:no-signature",
2623
+ code: DIAG.noSignature,
2621
2624
  message: `${name}: could not generalize a symbolic Abs`,
2622
2625
  suggestion: "add @nudo:case or make the body algebraically evaluable",
2623
2626
  fn: name
@@ -2637,7 +2640,7 @@ function checkSourceInner(filePath, source, file, phi, opts, issues, signatures,
2637
2640
  const loc = findFnLoc(file, name);
2638
2641
  issues.push({
2639
2642
  severity: entryThrowsMode === "warning" ? "warning" : "error",
2640
- code: "nudo:entry-may-throw",
2643
+ code: DIAG.entryMayThrow,
2641
2644
  message: `${name} (export): may throw ${gateDisplay}`,
2642
2645
  actual: `${formatEntrySigLine(name, g, gateDisplay)}`,
2643
2646
  expected: "entry total, or @nudo:throws / try-catch",
@@ -2681,7 +2684,7 @@ function checkSourceInner(filePath, source, file, phi, opts, issues, signatures,
2681
2684
  const where = symbolicTrueUnknown ? `${name} => unknown` : `${name} param ${g.params[unknownParamIdx] ?? `#${unknownParamIdx}`}: unknown`;
2682
2685
  issues.push({
2683
2686
  severity: "warning",
2684
- code: "nudo:unknown-inference",
2687
+ code: DIAG.unknownInference,
2685
2688
  message: `${name}: signature has true unknown (inference failed)`,
2686
2689
  actual: where,
2687
2690
  expected: "computable Abs (any = unconstrained, unknown = engine debt)",
@@ -2702,7 +2705,7 @@ function checkSourceInner(filePath, source, file, phi, opts, issues, signatures,
2702
2705
  const surface = [...contractNames].filter((n) => !n.startsWith("_p") && n !== "_").join(", ");
2703
2706
  issues.push({
2704
2707
  severity: "error",
2705
- code: "nudo:interface-param-mismatch",
2708
+ code: DIAG.interfaceParamMismatch,
2706
2709
  message: `${name}: contract parameter name(s) not in the formal parameter list (${unknownParams.join(", ")})`,
2707
2710
  actual: unknownParams.join(", "),
2708
2711
  expected: surface || g.params.join(", ") || "(no params)",
@@ -2715,7 +2718,7 @@ function checkSourceInner(filePath, source, file, phi, opts, issues, signatures,
2715
2718
  if (eff.conflict.params.length > 0) {
2716
2719
  issues.push({
2717
2720
  severity: "error",
2718
- code: "nudo:interface-conflict",
2721
+ code: DIAG.interfaceConflict,
2719
2722
  message: `${name}: handwritten contract conjunction unsatisfiable (${eff.conflict.params.join(", ")})`,
2720
2723
  suggestion: "check whether the source @nudo:contract and the same-name sidecar binding have contradictory constant bounds",
2721
2724
  fn: name
@@ -2724,7 +2727,7 @@ function checkSourceInner(filePath, source, file, phi, opts, issues, signatures,
2724
2727
  if (eff.conflict.returns) {
2725
2728
  issues.push({
2726
2729
  severity: "error",
2727
- code: "nudo:interface-conflict",
2730
+ code: DIAG.interfaceConflict,
2728
2731
  message: `${name}: handwritten contract conjunction unsatisfiable on the return slot`,
2729
2732
  suggestion: "check whether the source @nudo:contract return and the sidecar fn() return constraint are contradictory (the return slot is not enforced when they are)",
2730
2733
  fn: name
@@ -2760,7 +2763,7 @@ function checkSourceInner(filePath, source, file, phi, opts, issues, signatures,
2760
2763
  if (g.symbolic.conf === "opaque" && !truncated.has(name)) {
2761
2764
  issues.push({
2762
2765
  severity: "info",
2763
- code: "nudo:opaque-result",
2766
+ code: DIAG.opaqueResult,
2764
2767
  message: `${name}(...): conf=opaque (path not covered, or native)`,
2765
2768
  suggestion: opaqueEnvHint ? OPAQUE_ENV_HINT : OPAQUE_EVIDENCE_HINT,
2766
2769
  fn: name
@@ -2771,7 +2774,7 @@ function checkSourceInner(filePath, source, file, phi, opts, issues, signatures,
2771
2774
  if (label === FORK_TRUNCATION_LABEL) {
2772
2775
  issues.push({
2773
2776
  severity: "info",
2774
- code: "nudo:fork-truncated",
2777
+ code: DIAG.forkTruncated,
2775
2778
  message: `Branch expansion was truncated (fork budget); affected results widened to unknown#opaque (budget)`,
2776
2779
  suggestion: "optional: raise nudo.analysis.maxForks, or @nudo:budget forks=\u2026 on the function \u2014 non-blocking"
2777
2780
  });
@@ -2780,7 +2783,7 @@ function checkSourceInner(filePath, source, file, phi, opts, issues, signatures,
2780
2783
  if (label === PROMISE_MICRO_OVERFLOW_LABEL) {
2781
2784
  issues.push({
2782
2785
  severity: "info",
2783
- code: "nudo:promise-micro-truncated",
2786
+ code: DIAG.promiseMicroTruncated,
2784
2787
  message: `Promise microtask queue hit its hard cap; further then/catch callbacks were dropped (results stay fail-closed)`,
2785
2788
  suggestion: "optional: reduce top-level Promise.then fan-out \u2014 non-blocking"
2786
2789
  });
@@ -2789,7 +2792,7 @@ function checkSourceInner(filePath, source, file, phi, opts, issues, signatures,
2789
2792
  if (label === PROMISE_MICRO_ERROR_LABEL) {
2790
2793
  issues.push({
2791
2794
  severity: "info",
2792
- code: "nudo:promise-micro-error",
2795
+ code: DIAG.promiseMicroError,
2793
2796
  message: `A promise microtask threw while draining; the error was recorded and did not rewrite the synchronous return value`,
2794
2797
  suggestion: "optional: inspect the then/catch callback for a throw path \u2014 non-blocking"
2795
2798
  });
@@ -2798,7 +2801,7 @@ function checkSourceInner(filePath, source, file, phi, opts, issues, signatures,
2798
2801
  if (label === MATH_FOLD_ERROR_LABEL) {
2799
2802
  issues.push({
2800
2803
  severity: "info",
2801
- code: "nudo:math-fold-error",
2804
+ code: DIAG.mathFoldError,
2802
2805
  message: `A Math native fold threw during analysis (host-tampered or divergent Math.*); the result was widened to number`,
2803
2806
  suggestion: "optional: keep Math.* builtins unmodified in analyzed code, or mock them with @nudo:mock \u2014 non-blocking"
2804
2807
  });
@@ -2808,7 +2811,7 @@ function checkSourceInner(filePath, source, file, phi, opts, issues, signatures,
2808
2811
  const hostName = label.slice(HOST_EFFECT_LABEL_PREFIX.length);
2809
2812
  issues.push({
2810
2813
  severity: "info",
2811
- code: "nudo:host-effect-blocked",
2814
+ code: DIAG.hostEffectBlocked,
2812
2815
  message: `Host function '${hostName}' is not executed during analysis (network/timer side effect); result widened to unknown#opaque`,
2813
2816
  suggestion: "optional: mock it with @nudo:mock / @nudo:env, or pass the value in from a call site",
2814
2817
  fn: hostName
@@ -2818,7 +2821,7 @@ function checkSourceInner(filePath, source, file, phi, opts, issues, signatures,
2818
2821
  if (label === LOOP_TRUNCATION_LABEL) {
2819
2822
  issues.push({
2820
2823
  severity: "info",
2821
- code: "nudo:loop-truncated",
2824
+ code: DIAG.loopTruncated,
2822
2825
  message: `A loop did not terminate within its iteration budget (abstract unroll cap reached and the exit condition stayed concrete-true); affected loop state was widened (bounded, not exact)`,
2823
2826
  suggestion: "optional: restructure so the exit condition becomes abstract (data-dependent) within a few iterations, or pin the result with @nudo:case / @nudo:contract \u2014 non-blocking"
2824
2827
  });
@@ -2829,7 +2832,7 @@ function checkSourceInner(filePath, source, file, phi, opts, issues, signatures,
2829
2832
  const calls = reasons.has("calls");
2830
2833
  issues.push({
2831
2834
  severity: "info",
2832
- code: "nudo:recursion-truncated",
2835
+ code: DIAG.recursionTruncated,
2833
2836
  message: allCycle ? `Recursive evaluation of '${label}' hit a call cycle (same abstract arguments already on the stack); result widened to unknown#opaque (cycle \u2014 budget cannot lift this)` : `Recursive evaluation of '${label}' was truncated (${depth && calls ? "depth/size budget" : depth ? "call-depth budget" : calls ? "total-calls budget" : "depth/size budget"}); result widened to unknown#opaque (budget \u2014 not inference debt)`,
2834
2837
  suggestion: allCycle ? "a call cycle is not a budget: make the recursion arguments vary per level, narrow the base case, or declare @nudo:contract \u2014 raising @nudo:budget will not change this" : depth && !calls ? "raise the function budget with @nudo:budget depth=\u2026 (or narrow the recursion base case / declare @nudo:contract return)" : calls && !depth ? "raise the function budget with @nudo:budget calls=\u2026 (or narrow the recursion base case / declare @nudo:contract return)" : "raise the function budget with @nudo:budget calls=\u2026 depth=\u2026 (or narrow the recursion base case / declare @nudo:contract return)",
2835
2838
  reason: allCycle ? "cycle" : depth && calls ? "budget" : depth ? "depth" : calls ? "calls" : "budget",
@@ -2952,7 +2955,7 @@ function checkReturnConstraint(fnName, cName, constraint, ret, assumeDisplay, in
2952
2955
  if (assumeDisplay && assumeDisplay.length > 0) {
2953
2956
  relied.push({
2954
2957
  severity: "info",
2955
- code: "nudo:assume-relied",
2958
+ code: DIAG.assumeRelied,
2956
2959
  message: `${fnName}: return contract proved via @nudo:assume ${assumeDisplay.join("; ")}`,
2957
2960
  actual: `proof relies on user lemma${assumeDisplay.length > 1 ? "s" : ""}`,
2958
2961
  expected: "engine verifies the obligation, not the lemma itself",
@@ -2963,7 +2966,7 @@ function checkReturnConstraint(fnName, cName, constraint, ret, assumeDisplay, in
2963
2966
  if (invariantDisplay && invariantDisplay.length > 0) {
2964
2967
  relied.push({
2965
2968
  severity: "info",
2966
- code: "nudo:invariant-relied",
2969
+ code: DIAG.invariantRelied,
2967
2970
  message: `${fnName}: return contract proved via @nudo:invariant ${invariantDisplay.join("; ")}`,
2968
2971
  actual: `proof relies on user invariant${invariantDisplay.length > 1 ? "s" : ""}`,
2969
2972
  expected: "engine verifies the obligation, not the loop invariant itself",
@@ -2976,7 +2979,7 @@ function checkReturnConstraint(fnName, cName, constraint, ret, assumeDisplay, in
2976
2979
  const push = (severity, actual, expected, suggestion) => [
2977
2980
  {
2978
2981
  severity,
2979
- code: severity === "error" ? "nudo:constraint-violated" : "nudo:unproven-return",
2982
+ code: severity === "error" ? DIAG.constraintViolated : DIAG.unprovenReturn,
2980
2983
  message: `${fnName}: return value \u22AD @nudo:contract return ${cName}`,
2981
2984
  actual,
2982
2985
  expected,
@@ -4,6 +4,86 @@ import { A as Abs, T as Term, c as AbsModuleExports, d as AstEnv } from './run-D
4
4
  export { $ as $tryDigestSoft, e as $tryMarkSoft, f as $tryReleaseSoft, E as ERROR_FAMILY, g as EvalFallbackStats, M as MayThrowEffect, h as absLit, i as absNumLit, j as absStrLit, k as allAbsStr, l as clearPureCallMemo, m as clearPureMemo, n as enterEvalCallBudgetSession, o as errorTypeAbs, p as exitEvalCallBudgetSession, q as filterDeclaredThrows, r as filterGateThrows, s as filterIgnoredThrows, t as flushMayThrowEffects, u as formatThrowsAbs, v as getEvalCallBudgetState, w as getEvalFallbackStats, x as getMayThrowCollector, y as isThrowsIgnored, z as mayThrowEffectsToAbs, B as orphanMayThrowEffects, D as popMayThrowFrame, F as pushMayThrowFrame, G as recordMayThrow, H as resetEvalFallbackStats, I as runWithMayThrowSession, J as setMayThrowCollector, K as throwAbsToKinds, N as throwsKindCovered, O as withEvalBudgetOverride } from './run-DfloWX6i.js';
5
5
  import { File, Node } from '@babel/types';
6
6
 
7
+ /**
8
+ * 诊断码唯一注册表(P3-7):所有 `nudo:*` 诊断码字符串的单一真理源。
9
+ *
10
+ * - 零依赖叶子:core 内部相对 import,跨包(parser/service/lsp/nudojs)
11
+ * 走 `@nudojs/core/internal`——不引环、加载零成本。
12
+ * - 拼写漂移在类型层不可表达:键不存在 → tsc 报错,新增码只能落在本表。
13
+ * - 门禁联动:packages/website/tests/docs-coverage.test.ts 的 emittedCodes()
14
+ * 以「本注册表 ∪ src 残留字面量」双源强制诊断术语表(en+zh)锚点——
15
+ * 注册表里每个码都必须有 `{#nudo-<code>}` 锚点(冒号转连字符)。
16
+ * - 非诊断码的 `nudo:*` 字符串**不进**本表:指令名(`nudo:case` 等)、
17
+ * 控制流/Error 标记(`nudo:throw` / `nudo:return` / `nudo:loop` /
18
+ * `nudo:unsupported`)、Symbol 哨兵(`nudo:not-literal` / `nudo:json-omit` /
19
+ * `nudo:no-lit-key`)。
20
+ */
21
+ /** 键名 = 码去掉 `nudo:` 前缀后按 `-` 分段转 camelCase。 */
22
+ declare const DIAG: {
23
+ readonly argCount: "nudo:arg-count";
24
+ readonly argOpaque: "nudo:arg-opaque";
25
+ readonly argStructure: "nudo:arg-structure";
26
+ readonly assignMismatch: "nudo:assign-mismatch";
27
+ readonly constraintUnproven: "nudo:constraint-unproven";
28
+ readonly constraintViolated: "nudo:constraint-violated";
29
+ readonly fnNotFound: "nudo:fn-not-found";
30
+ readonly partialResult: "nudo:partial-result";
31
+ readonly unprovenReturn: "nudo:unproven-return";
32
+ readonly assumeInvalid: "nudo:assume-invalid";
33
+ readonly assumeRelied: "nudo:assume-relied";
34
+ readonly contractSyntax: "nudo:contract-syntax";
35
+ readonly directiveSyntax: "nudo:directive-syntax";
36
+ readonly invariantInvalid: "nudo:invariant-invalid";
37
+ readonly invariantRelied: "nudo:invariant-relied";
38
+ readonly mockInvalid: "nudo:mock-invalid";
39
+ readonly caseExpected: "nudo:case-expected";
40
+ readonly caseInconsistency: "nudo:case-inconsistency";
41
+ readonly dualEntry: "nudo:dual-entry";
42
+ readonly entryMayThrow: "nudo:entry-may-throw";
43
+ readonly mayThrow: "nudo:may-throw";
44
+ readonly noSignature: "nudo:no-signature";
45
+ readonly builtinUnknown: "nudo:builtin-unknown";
46
+ readonly forkTruncated: "nudo:fork-truncated";
47
+ readonly hostEffectBlocked: "nudo:host-effect-blocked";
48
+ readonly loopTruncated: "nudo:loop-truncated";
49
+ readonly mathFoldError: "nudo:math-fold-error";
50
+ readonly opaqueResult: "nudo:opaque-result";
51
+ readonly promiseMicroError: "nudo:promise-micro-error";
52
+ readonly promiseMicroTruncated: "nudo:promise-micro-truncated";
53
+ readonly recursionTruncated: "nudo:recursion-truncated";
54
+ readonly unknownInference: "nudo:unknown-inference";
55
+ readonly unknownRecv: "nudo:unknown-recv";
56
+ readonly missingSlot: "nudo:missing-slot";
57
+ readonly noMethod: "nudo:no-method";
58
+ readonly interfaceConflict: "nudo:interface-conflict";
59
+ readonly interfaceCycle: "nudo:interface-cycle";
60
+ readonly interfaceDomainExceeds: "nudo:interface-domain-exceeds";
61
+ readonly interfaceDrift: "nudo:interface-drift";
62
+ readonly interfaceEmitDenied: "nudo:interface-emit-denied";
63
+ readonly interfaceEntryOnly: "nudo:interface-entry-only";
64
+ readonly interfaceLoad: "nudo:interface-load";
65
+ readonly interfaceMultiDeclarator: "nudo:interface-multi-declarator";
66
+ readonly interfaceNameClash: "nudo:interface-name-clash";
67
+ readonly interfaceNotProjectable: "nudo:interface-not-projectable";
68
+ readonly interfaceParamMismatch: "nudo:interface-param-mismatch";
69
+ readonly interfaceUnderivable: "nudo:interface-underivable";
70
+ readonly envHarvestConflict: "nudo:env-harvest-conflict";
71
+ readonly envUnresolved: "nudo:env-unresolved";
72
+ readonly exportsUnresolved: "nudo:exports-unresolved";
73
+ readonly missingExport: "nudo:missing-export";
74
+ readonly moduleCycle: "nudo:module-cycle";
75
+ readonly moduleDepth: "nudo:module-depth";
76
+ readonly moduleMissing: "nudo:module-missing";
77
+ readonly internal: "nudo:internal";
78
+ readonly pathEmptyDir: "nudo:path-empty-dir";
79
+ readonly pathIo: "nudo:path-io";
80
+ readonly pathMissingCallsite: "nudo:path-missing-callsite";
81
+ readonly pathNotFound: "nudo:path-not-found";
82
+ readonly pathNotTarget: "nudo:path-not-target";
83
+ };
84
+ /** 全部诊断码字面量联合(DIAG 值的类型面)。 */
85
+ type DiagCode = (typeof DIAG)[keyof typeof DIAG];
86
+
7
87
  /**
8
88
  * 源码文本工具:注释/字符串/正则字面量剥离。
9
89
  * 原文正则特性探测(require/import/exports 等)必须先剥再测——
@@ -790,4 +870,4 @@ declare function runWithEvalMissingSlot<T>(enabled: boolean, body: () => T): T;
790
870
  */
791
871
  declare function noteObjSlotMissing(recv: Abs | undefined, name: string, loc?: [number, number]): boolean;
792
872
 
793
- export { type AbsBudgetStats, type AbsInlay, type ArgDerivation, type ClassDef, type CollectAbsInlaysOpts, type CollectorScopeParticipant, type DerivationNode, type DiagChannel, type EvalMemberDiag, FORK_TRUNCATION_LABEL, type FnFp, HOST_EFFECT_LABEL_PREFIX, type InjectedDomainEvidenceOpts, type InjectedDomainRecord, MAX_CALL_DEPTH, MAX_EVAL_TOTAL_FORKS, MAX_TOTAL_CALLS, type MethodDef, OBJECT_PROTO_NAMES, PROMISE_MICRO_ERROR_LABEL, PROMISE_MICRO_OVERFLOW_LABEL, type ScopedDiagChannel, type ScopedSlot, type StringLiteralSpan, type TemplateMeta, type TemplatePartDesc, type TemplatePartView, type TemplatePredicateDecision, abortDerivationSession, absTemplateViews, allFixedTextOfViews, anyMemberResult, awaitAbs, beginDerivationSession, bumpEvalForkBudget, callBudgetKey, canSkipLiteralCallScan, checkInjectedDomainEvidence, classChainNames, classFromMethods, clearLiveImportRefreshers, coerceAsyncReturn, collectAbsInlays, concatString, createDiagChannel, createScopedDiagChannel, createScopedSlot, createTemplateAbs, decideEndsWith, decideIncludes, decideStartsWith, defineClass, definitelyUncallableMember, denoteGuard, derivationChain, endDerivationSession, enterCall, escapeTemplateTypeFixed, exitCall, fixedLengthOfViews, fnFingerprints, formatObjectKey, formatTemplateNameViews, generalizeSourceKeyPart, getAbsCallBudgetStats, getAbsOrigin, getClass, getClassChain, getDerivation, getEvalForkBudgetLimit, getEvalForkCount, getFnNameAndBodies, hasDerivationSession, hashSource, instanceOf, instantiateClass, isEvalMissingSlotEnabled, isJsBindingIdent, isJsIdent, isNullishAbs, isTemplateLike, knownPrefixOfViews, knownSuffixOfViews, listTopFunctions, lookupMethod, lookupMethodWithOwner, lookupSuperMethod, maskCommentsAndStrings, mergeAdjacentFixedViews, noteAbsTruncation, noteAnyMemberMayThrow, noteDerivationAdd, noteDerivationJoin, noteEvalForkTruncation, noteHostEffectBlocked, noteMemberDispatchMiss, noteNullishMemberThrows, noteObjSlotMissing, notePrimMemberMissing, noteUnknownMemberMissing, popCallLoc, projectBrand, projectDerivationDsl, pushCallLoc, recordMemberDiag, registerCollectorScopeParticipant, resetAbsCallBudget, resetEvalForkBudget, resetFnFpCache, resetHashSourceCache, runWithCollectorScope, runWithEvalMissingSlot, safeMemberAccess, sanitizeCommentText, scanStringLiterals, setAbsTruncationCollector, setDerivation, setDerivationCollector, setEvalForkBudgetLimit, setEvalMissingSlotEnabled, setMemberDiagCollector, sourceHasCjsExports, sourceHasModuleDependency, sourceHasRequireCall, stableAnalyzeKeySource, stableCallId, stripCommentsAndStrings, stripStringsKeepComments, superNameOf, tagAbsOrigin, tagDerivationRoot, templateMatchesValue, templatePartsOf, termKey, toJsBindingIdent, truncatedAbs, viewTemplateParts, withFnBudgetOverride, wrapPromise };
873
+ export { type AbsBudgetStats, type AbsInlay, type ArgDerivation, type ClassDef, type CollectAbsInlaysOpts, type CollectorScopeParticipant, DIAG, type DerivationNode, type DiagChannel, type DiagCode, type EvalMemberDiag, FORK_TRUNCATION_LABEL, type FnFp, HOST_EFFECT_LABEL_PREFIX, type InjectedDomainEvidenceOpts, type InjectedDomainRecord, MAX_CALL_DEPTH, MAX_EVAL_TOTAL_FORKS, MAX_TOTAL_CALLS, type MethodDef, OBJECT_PROTO_NAMES, PROMISE_MICRO_ERROR_LABEL, PROMISE_MICRO_OVERFLOW_LABEL, type ScopedDiagChannel, type ScopedSlot, type StringLiteralSpan, type TemplateMeta, type TemplatePartDesc, type TemplatePartView, type TemplatePredicateDecision, abortDerivationSession, absTemplateViews, allFixedTextOfViews, anyMemberResult, awaitAbs, beginDerivationSession, bumpEvalForkBudget, callBudgetKey, canSkipLiteralCallScan, checkInjectedDomainEvidence, classChainNames, classFromMethods, clearLiveImportRefreshers, coerceAsyncReturn, collectAbsInlays, concatString, createDiagChannel, createScopedDiagChannel, createScopedSlot, createTemplateAbs, decideEndsWith, decideIncludes, decideStartsWith, defineClass, definitelyUncallableMember, denoteGuard, derivationChain, endDerivationSession, enterCall, escapeTemplateTypeFixed, exitCall, fixedLengthOfViews, fnFingerprints, formatObjectKey, formatTemplateNameViews, generalizeSourceKeyPart, getAbsCallBudgetStats, getAbsOrigin, getClass, getClassChain, getDerivation, getEvalForkBudgetLimit, getEvalForkCount, getFnNameAndBodies, hasDerivationSession, hashSource, instanceOf, instantiateClass, isEvalMissingSlotEnabled, isJsBindingIdent, isJsIdent, isNullishAbs, isTemplateLike, knownPrefixOfViews, knownSuffixOfViews, listTopFunctions, lookupMethod, lookupMethodWithOwner, lookupSuperMethod, maskCommentsAndStrings, mergeAdjacentFixedViews, noteAbsTruncation, noteAnyMemberMayThrow, noteDerivationAdd, noteDerivationJoin, noteEvalForkTruncation, noteHostEffectBlocked, noteMemberDispatchMiss, noteNullishMemberThrows, noteObjSlotMissing, notePrimMemberMissing, noteUnknownMemberMissing, popCallLoc, projectBrand, projectDerivationDsl, pushCallLoc, recordMemberDiag, registerCollectorScopeParticipant, resetAbsCallBudget, resetEvalForkBudget, resetFnFpCache, resetHashSourceCache, runWithCollectorScope, runWithEvalMissingSlot, safeMemberAccess, sanitizeCommentText, scanStringLiterals, setAbsTruncationCollector, setDerivation, setDerivationCollector, setEvalForkBudgetLimit, setEvalMissingSlotEnabled, setMemberDiagCollector, sourceHasCjsExports, sourceHasModuleDependency, sourceHasRequireCall, stableAnalyzeKeySource, stableCallId, stripCommentsAndStrings, stripStringsKeepComments, superNameOf, tagAbsOrigin, tagDerivationRoot, templateMatchesValue, templatePartsOf, termKey, toJsBindingIdent, truncatedAbs, viewTemplateParts, withFnBudgetOverride, wrapPromise };
package/dist/internal.js CHANGED
@@ -22,11 +22,12 @@ import {
22
22
  stableAnalyzeKeySource,
23
23
  stablePathKey,
24
24
  stablePathKeyGraph
25
- } from "./chunk-4GZPH6YL.js";
25
+ } from "./chunk-47UPDZHE.js";
26
26
  import {
27
27
  $tryDigestSoft,
28
28
  $tryMarkSoft,
29
29
  $tryReleaseSoft,
30
+ DIAG,
30
31
  ERROR_FAMILY,
31
32
  FORK_TRUNCATION_LABEL,
32
33
  HOST_EFFECT_LABEL_PREFIX,
@@ -171,7 +172,7 @@ import {
171
172
  withEvalBudgetOverride,
172
173
  withFnBudgetOverride,
173
174
  wrapPromise
174
- } from "./chunk-JMOQEJTD.js";
175
+ } from "./chunk-NUTYUT3I.js";
175
176
 
176
177
  // src/algebra/inlay.ts
177
178
  function listFunctions(source) {
@@ -612,6 +613,7 @@ export {
612
613
  $tryDigestSoft,
613
614
  $tryMarkSoft,
614
615
  $tryReleaseSoft,
616
+ DIAG,
615
617
  ERROR_FAMILY,
616
618
  FORK_TRUNCATION_LABEL,
617
619
  HOST_EFFECT_LABEL_PREFIX,
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@nudojs/core",
3
- "version": "1.14.1",
3
+ "version": "1.15.0",
4
4
  "engines": {
5
- "node": ">=20"
5
+ "node": ">=22"
6
6
  },
7
7
  "description": "Nudo type system: type-as-computation (Abs = shape × term × pred × conf)",
8
8
  "type": "module",