@rotifer/playground 0.30.3 → 0.32.1
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/CHANGELOG.md +40 -0
- package/README.md +1 -1
- package/README.zh.md +1 -1
- package/dist/arena/invalidation-criteria.js +8 -8
- package/dist/cloud/client.d.ts.map +1 -1
- package/dist/cloud/client.js +9 -0
- package/dist/cloud/client.js.map +1 -1
- package/dist/cloud/types.d.ts +7 -0
- package/dist/cloud/types.d.ts.map +1 -1
- package/dist/cloud/types.js.map +1 -1
- package/dist/commands/agent-create.js +1 -1
- package/dist/commands/agent-create.js.map +1 -1
- package/dist/commands/arena-submit.d.ts.map +1 -1
- package/dist/commands/arena-submit.js +58 -21
- package/dist/commands/arena-submit.js.map +1 -1
- package/dist/commands/arena-watch.js +1 -1
- package/dist/commands/arena-watch.js.map +1 -1
- package/dist/commands/compile.d.ts.map +1 -1
- package/dist/commands/compile.js +15 -8
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/test.d.ts.map +1 -1
- package/dist/commands/test.js +5 -9
- package/dist/commands/test.js.map +1 -1
- package/dist/commands/vg.d.ts.map +1 -1
- package/dist/commands/vg.js +7 -0
- package/dist/commands/vg.js.map +1 -1
- package/dist/publish/pre-publish-check.d.ts.map +1 -1
- package/dist/publish/pre-publish-check.js +12 -0
- package/dist/publish/pre-publish-check.js.map +1 -1
- package/dist/runtime/network-gateway.d.ts +24 -4
- package/dist/runtime/network-gateway.d.ts.map +1 -1
- package/dist/runtime/network-gateway.js +86 -12
- package/dist/runtime/network-gateway.js.map +1 -1
- package/dist/scanner/index.d.ts +1 -1
- package/dist/scanner/index.d.ts.map +1 -1
- package/dist/scanner/index.js +2 -1
- package/dist/scanner/index.js.map +1 -1
- package/dist/scanner/scanner.d.ts +2 -0
- package/dist/scanner/scanner.d.ts.map +1 -1
- package/dist/scanner/scanner.js +35 -5
- package/dist/scanner/scanner.js.map +1 -1
- package/dist/scanner/types.d.ts +3 -0
- package/dist/scanner/types.d.ts.map +1 -1
- package/dist/testsuite/gate.d.ts +6 -3
- package/dist/testsuite/gate.d.ts.map +1 -1
- package/dist/testsuite/gate.js +20 -7
- package/dist/testsuite/gate.js.map +1 -1
- package/dist/testsuite/run.d.ts +6 -11
- package/dist/testsuite/run.d.ts.map +1 -1
- package/dist/testsuite/run.js +29 -4
- package/dist/testsuite/run.js.map +1 -1
- package/dist/utils/fidelity-discount.d.ts +24 -0
- package/dist/utils/fidelity-discount.d.ts.map +1 -1
- package/dist/utils/fidelity-discount.js +35 -0
- package/dist/utils/fidelity-discount.js.map +1 -1
- package/dist/utils/fitness-formula.d.ts +20 -4
- package/dist/utils/fitness-formula.d.ts.map +1 -1
- package/dist/utils/fitness-formula.js +24 -6
- package/dist/utils/fitness-formula.js.map +1 -1
- package/dist/utils/javy-compiler.d.ts +25 -0
- package/dist/utils/javy-compiler.d.ts.map +1 -1
- package/dist/utils/javy-compiler.js +84 -1
- package/dist/utils/javy-compiler.js.map +1 -1
- package/package.json +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"network-gateway.d.ts","sourceRoot":"","sources":["../../src/runtime/network-gateway.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"network-gateway.d.ts","sourceRoot":"","sources":["../../src/runtime/network-gateway.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,2DAA2D;AAC3D,eAAO,MAAM,iBAAiB,IAAI,CAAC;AAEnC,MAAM,WAAW,aAAa;IAC5B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,qBAAa,mBAAoB,SAAQ,KAAK;aAE1B,IAAI,EAChB,gBAAgB,GAChB,iBAAiB,GACjB,cAAc,GACd,SAAS,GACT,oBAAoB,GACpB,eAAe;gBANH,IAAI,EAChB,gBAAgB,GAChB,iBAAiB,GACjB,cAAc,GACd,SAAS,GACT,oBAAoB,GACpB,eAAe,EACnB,OAAO,EAAE,MAAM;CAKlB;AAkBD,6DAA6D;AAC7D,MAAM,WAAW,kBAAkB;IACjC;;yEAEqE;IACrE,6BAA6B,CAAC,EAAE,OAAO,CAAC;CACzC;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,qBAAqB,CAAU;IACvC,OAAO,CAAC,iBAAiB,CAAgB;IACzC,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,UAAU,CAAK;gBAEX,MAAM,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,EAAE,WAAW,GAAE,kBAAuB;IAKjF,IAAI,KAAK;;;;MAMR;IAEK,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,eAAe,CAAC;IA0FjF;;;;oDAIgD;IAChD,OAAO,CAAC,WAAW;IA6CnB,OAAO,CAAC,gBAAgB;YAiBV,cAAc;CAmC7B;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,GAC7B;IACD,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;IACvF,OAAO,EAAE,cAAc,CAAC;CACzB,CAMA"}
|
|
@@ -5,10 +5,17 @@
|
|
|
5
5
|
* Enforces domain whitelist, per-request timeout, response size cap,
|
|
6
6
|
* and per-minute rate limiting. Genes call `gatewayFetch()` instead
|
|
7
7
|
* of raw `fetch()`.
|
|
8
|
+
*
|
|
9
|
+
* SSRF hardening, the same as the WASM path (rotifer-core hybrid.rs
|
|
10
|
+
* `check_url` / `perform_fetch`, Hybrid Binding API §2.1): https only, no IP
|
|
11
|
+
* literals, and redirects followed by hand, at most MAX_REDIRECT_HOPS, each
|
|
12
|
+
* hop checked against the whitelist before it is requested.
|
|
8
13
|
*/
|
|
9
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.NetworkGateway = exports.NetworkGatewayError = void 0;
|
|
15
|
+
exports.NetworkGateway = exports.NetworkGatewayError = exports.MAX_REDIRECT_HOPS = void 0;
|
|
11
16
|
exports.createGatewayFetch = createGatewayFetch;
|
|
17
|
+
/** Same as rotifer-core `constants::MAX_REDIRECT_HOPS`. */
|
|
18
|
+
exports.MAX_REDIRECT_HOPS = 5;
|
|
12
19
|
class NetworkGatewayError extends Error {
|
|
13
20
|
code;
|
|
14
21
|
constructor(code, message) {
|
|
@@ -24,13 +31,23 @@ const DEFAULT_CONFIG = {
|
|
|
24
31
|
maxResponseBytes: 1_048_576, // 1 MiB
|
|
25
32
|
maxRequestsPerMin: 10,
|
|
26
33
|
};
|
|
34
|
+
/** Headers that describe a request body (fetch's "request-body-header names"),
|
|
35
|
+
* dropped when a redirect turns the request into a body-less GET. */
|
|
36
|
+
const BODY_HEADERS = new Set(["content-encoding", "content-language", "content-location", "content-type", "content-length"]);
|
|
37
|
+
function withoutBodyHeaders(headers) {
|
|
38
|
+
if (!headers)
|
|
39
|
+
return headers;
|
|
40
|
+
return Object.fromEntries(Object.entries(headers).filter(([k]) => !BODY_HEADERS.has(k.toLowerCase())));
|
|
41
|
+
}
|
|
27
42
|
class NetworkGateway {
|
|
28
43
|
config;
|
|
44
|
+
allowInsecureLoopback;
|
|
29
45
|
requestTimestamps = [];
|
|
30
46
|
totalRequests = 0;
|
|
31
47
|
totalBytes = 0;
|
|
32
|
-
constructor(config) {
|
|
48
|
+
constructor(config, testOptions = {}) {
|
|
33
49
|
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
50
|
+
this.allowInsecureLoopback = testOptions.allowInsecureLoopbackForTests === true;
|
|
34
51
|
}
|
|
35
52
|
get stats() {
|
|
36
53
|
return {
|
|
@@ -40,17 +57,57 @@ class NetworkGateway {
|
|
|
40
57
|
};
|
|
41
58
|
}
|
|
42
59
|
async fetch(url, options) {
|
|
43
|
-
this.
|
|
60
|
+
this.validateUrl(url);
|
|
44
61
|
this.enforceRateLimit();
|
|
45
62
|
const controller = new AbortController();
|
|
46
63
|
const timeout = setTimeout(() => controller.abort(), this.config.maxTimeoutMs);
|
|
47
64
|
try {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
65
|
+
// Redirects are followed here, not by fetch: fetch would follow a
|
|
66
|
+
// whitelisted host's 302 to anywhere. Every hop is checked before it
|
|
67
|
+
// is requested; the timeout covers the whole chain.
|
|
68
|
+
//
|
|
69
|
+
// What a hop carries follows fetch's own redirect rules, made stricter:
|
|
70
|
+
// - 301/302/303 turn a request that is not GET/HEAD into a GET with no
|
|
71
|
+
// body (and no body headers); 307/308 keep the method and body.
|
|
72
|
+
// - Moving to another origin (scheme, host or port) drops every header
|
|
73
|
+
// the gene set, not only Authorization: a key travels just as well in
|
|
74
|
+
// X-Api-Key or apikey, and the next host is someone else even when
|
|
75
|
+
// it matches the same *.domain wildcard.
|
|
76
|
+
let current = url;
|
|
77
|
+
let method = options?.method || "POST";
|
|
78
|
+
let requestHeaders = options?.headers;
|
|
79
|
+
let body = options?.body;
|
|
80
|
+
let response;
|
|
81
|
+
for (let hop = 0; hop <= exports.MAX_REDIRECT_HOPS; hop++) {
|
|
82
|
+
if (hop > 0)
|
|
83
|
+
this.validateUrl(current);
|
|
84
|
+
response = await fetch(current, {
|
|
85
|
+
method,
|
|
86
|
+
headers: requestHeaders,
|
|
87
|
+
body,
|
|
88
|
+
signal: controller.signal,
|
|
89
|
+
redirect: "manual",
|
|
90
|
+
});
|
|
91
|
+
const location = response.headers.get("location");
|
|
92
|
+
if (response.status < 300 || response.status >= 400 || !location)
|
|
93
|
+
break;
|
|
94
|
+
if (hop === exports.MAX_REDIRECT_HOPS) {
|
|
95
|
+
await response.body?.cancel();
|
|
96
|
+
throw new NetworkGatewayError("NETWORK_ERROR", `Request to ${url} failed: more than ${exports.MAX_REDIRECT_HOPS} redirects`);
|
|
97
|
+
}
|
|
98
|
+
await response.body?.cancel();
|
|
99
|
+
const next = new URL(location, current);
|
|
100
|
+
if ([301, 302, 303].includes(response.status) && method !== "GET" && method !== "HEAD") {
|
|
101
|
+
method = "GET";
|
|
102
|
+
body = undefined;
|
|
103
|
+
requestHeaders = withoutBodyHeaders(requestHeaders);
|
|
104
|
+
}
|
|
105
|
+
if (next.origin !== new URL(current).origin)
|
|
106
|
+
requestHeaders = undefined;
|
|
107
|
+
current = next.toString();
|
|
108
|
+
}
|
|
109
|
+
if (!response)
|
|
110
|
+
throw new Error("no response");
|
|
54
111
|
const { text, isTruncated } = await this.readBodyCapped(response);
|
|
55
112
|
this.totalRequests++;
|
|
56
113
|
this.totalBytes += text.length;
|
|
@@ -66,6 +123,8 @@ class NetworkGateway {
|
|
|
66
123
|
};
|
|
67
124
|
}
|
|
68
125
|
catch (err) {
|
|
126
|
+
if (err instanceof NetworkGatewayError)
|
|
127
|
+
throw err;
|
|
69
128
|
if (err.name === "AbortError") {
|
|
70
129
|
throw new NetworkGatewayError("TIMEOUT", `Request to ${url} timed out after ${this.config.maxTimeoutMs}ms`);
|
|
71
130
|
}
|
|
@@ -75,14 +134,20 @@ class NetworkGateway {
|
|
|
75
134
|
clearTimeout(timeout);
|
|
76
135
|
}
|
|
77
136
|
}
|
|
78
|
-
|
|
79
|
-
|
|
137
|
+
/** Whitelist first, then scheme and host shape. Runs for the first request
|
|
138
|
+
* and for every redirect hop. rotifer-core's `check_url` checks shape first;
|
|
139
|
+
* here a URL off the whitelist keeps the DOMAIN_BLOCKED callers have always
|
|
140
|
+
* had, and INVALID_REQUEST is what a whitelisted host gets over http or as
|
|
141
|
+
* an IP literal. Either way nothing is sent. */
|
|
142
|
+
validateUrl(url) {
|
|
143
|
+
let parsed;
|
|
80
144
|
try {
|
|
81
|
-
|
|
145
|
+
parsed = new URL(url);
|
|
82
146
|
}
|
|
83
147
|
catch {
|
|
84
148
|
throw new NetworkGatewayError("DOMAIN_BLOCKED", `Invalid URL: ${url}`);
|
|
85
149
|
}
|
|
150
|
+
const hostname = parsed.hostname;
|
|
86
151
|
const isAllowed = this.config.allowedDomains.some((d) => {
|
|
87
152
|
if (d.startsWith("*.")) {
|
|
88
153
|
return hostname.endsWith(d.slice(1)) || hostname === d.slice(2);
|
|
@@ -92,6 +157,15 @@ class NetworkGateway {
|
|
|
92
157
|
if (!isAllowed) {
|
|
93
158
|
throw new NetworkGatewayError("DOMAIN_BLOCKED", `Domain "${hostname}" is not in the allowed list: [${this.config.allowedDomains.join(", ")}]`);
|
|
94
159
|
}
|
|
160
|
+
const isIpLiteral = /^\d{1,3}(\.\d{1,3}){3}$/.test(hostname) || hostname.startsWith("[");
|
|
161
|
+
const isLoopback = hostname === "localhost" || hostname === "[::1]" || /^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(hostname);
|
|
162
|
+
const isLoopbackAdmitted = this.allowInsecureLoopback && isLoopback;
|
|
163
|
+
if (parsed.protocol !== "https:" && !(parsed.protocol === "http:" && isLoopbackAdmitted)) {
|
|
164
|
+
throw new NetworkGatewayError("INVALID_REQUEST", `Only https is allowed: ${parsed.protocol}//${hostname}`);
|
|
165
|
+
}
|
|
166
|
+
if (isIpLiteral && !isLoopbackAdmitted) {
|
|
167
|
+
throw new NetworkGatewayError("INVALID_REQUEST", `IP addresses are not allowed, use a host name: ${hostname}`);
|
|
168
|
+
}
|
|
95
169
|
}
|
|
96
170
|
enforceRateLimit() {
|
|
97
171
|
const now = Date.now();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"network-gateway.js","sourceRoot":"","sources":["../../src/runtime/network-gateway.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"network-gateway.js","sourceRoot":"","sources":["../../src/runtime/network-gateway.ts"],"names":[],"mappings":"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"}
|
package/dist/scanner/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { scan, scanFile, computeGrade } from "./scanner.js";
|
|
1
|
+
export { scan, scanFile, computeGrade, unscannedLanguages } from "./scanner.js";
|
|
2
2
|
export type { ScanOptions } from "./scanner.js";
|
|
3
3
|
export { SCAN_RULES, SCANNER_VERSION, rulesFingerprint } from "./rules.js";
|
|
4
4
|
export type { ScanResult, Finding, Grade, Severity, ScanRule } from "./types.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scanner/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scanner/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAChF,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC3E,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/scanner/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.rulesFingerprint = exports.SCANNER_VERSION = exports.SCAN_RULES = exports.computeGrade = exports.scanFile = exports.scan = void 0;
|
|
3
|
+
exports.rulesFingerprint = exports.SCANNER_VERSION = exports.SCAN_RULES = exports.unscannedLanguages = exports.computeGrade = exports.scanFile = exports.scan = void 0;
|
|
4
4
|
var scanner_js_1 = require("./scanner.js");
|
|
5
5
|
Object.defineProperty(exports, "scan", { enumerable: true, get: function () { return scanner_js_1.scan; } });
|
|
6
6
|
Object.defineProperty(exports, "scanFile", { enumerable: true, get: function () { return scanner_js_1.scanFile; } });
|
|
7
7
|
Object.defineProperty(exports, "computeGrade", { enumerable: true, get: function () { return scanner_js_1.computeGrade; } });
|
|
8
|
+
Object.defineProperty(exports, "unscannedLanguages", { enumerable: true, get: function () { return scanner_js_1.unscannedLanguages; } });
|
|
8
9
|
var rules_js_1 = require("./rules.js");
|
|
9
10
|
Object.defineProperty(exports, "SCAN_RULES", { enumerable: true, get: function () { return rules_js_1.SCAN_RULES; } });
|
|
10
11
|
Object.defineProperty(exports, "SCANNER_VERSION", { enumerable: true, get: function () { return rules_js_1.SCANNER_VERSION; } });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/scanner/index.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/scanner/index.ts"],"names":[],"mappings":";;;AAAA,2CAAgF;AAAvE,kGAAA,IAAI,OAAA;AAAE,sGAAA,QAAQ,OAAA;AAAE,0GAAA,YAAY,OAAA;AAAE,gHAAA,kBAAkB,OAAA;AAEzD,uCAA2E;AAAlE,sGAAA,UAAU,OAAA;AAAE,2GAAA,eAAe,OAAA;AAAE,4GAAA,gBAAgB,OAAA"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { Finding, Grade, ScanResult } from "./types.js";
|
|
2
|
+
/** ".rs" files → "Rust"; unknown extensions are named by extension. */
|
|
3
|
+
export declare function unscannedLanguages(files: readonly string[]): string;
|
|
2
4
|
export declare function scanFile(filePath: string, rootDir: string): Finding[];
|
|
3
5
|
export declare function computeGrade(findings: Finding[]): Grade;
|
|
4
6
|
export interface ScanOptions {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../src/scanner/scanner.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../src/scanner/scanner.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAuE7D,uEAAuE;AACvE,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAOnE;AAED,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,EAAE,CA6BrE;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,KAAK,CAQvD;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,UAAU,CAwCrF"}
|
package/dist/scanner/scanner.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.unscannedLanguages = unscannedLanguages;
|
|
3
4
|
exports.scanFile = scanFile;
|
|
4
5
|
exports.computeGrade = computeGrade;
|
|
5
6
|
exports.scan = scan;
|
|
@@ -8,22 +9,28 @@ const node_path_1 = require("node:path");
|
|
|
8
9
|
const rules_js_1 = require("./rules.js");
|
|
9
10
|
const literals_js_1 = require("./literals.js");
|
|
10
11
|
const CODE_EXTENSIONS = new Set([".ts", ".js", ".mts", ".mjs", ".cjs", ".tsx", ".jsx", ".sh", ".py"]);
|
|
12
|
+
// Source files V(g) has no rules for. They are not read, but they are named in
|
|
13
|
+
// the result: a gene written only in Rust otherwise looks exactly like a gene
|
|
14
|
+
// with no code at all.
|
|
15
|
+
const UNSUPPORTED_CODE_EXTENSIONS = new Set([
|
|
16
|
+
".rs", ".go", ".c", ".h", ".cc", ".cpp", ".hpp", ".zig", ".java", ".kt", ".swift", ".rb", ".cs",
|
|
17
|
+
]);
|
|
11
18
|
// Files whose literals maskJsLiterals understands. .tsx/.jsx are left out (JSX
|
|
12
19
|
// text such as `Don't` is not a string literal), as are .sh and .py, whose
|
|
13
20
|
// quoting rules differ; those keep raw-line matching for every rule.
|
|
14
21
|
const JS_EXTENSIONS = new Set([".ts", ".js", ".mts", ".mjs", ".cjs"]);
|
|
15
|
-
function collectCodeFiles(dir) {
|
|
22
|
+
function collectCodeFiles(dir, extensions = CODE_EXTENSIONS, skip = []) {
|
|
16
23
|
const files = [];
|
|
17
24
|
const walk = (d) => {
|
|
18
25
|
for (const entry of (0, node_fs_1.readdirSync)(d)) {
|
|
19
|
-
if (entry === "node_modules" || entry === ".git" || entry === "dist")
|
|
26
|
+
if (entry === "node_modules" || entry === ".git" || entry === "dist" || skip.includes(entry))
|
|
20
27
|
continue;
|
|
21
28
|
const full = (0, node_path_1.join)(d, entry);
|
|
22
29
|
const st = (0, node_fs_1.statSync)(full);
|
|
23
30
|
if (st.isDirectory()) {
|
|
24
31
|
walk(full);
|
|
25
32
|
}
|
|
26
|
-
else if (
|
|
33
|
+
else if (extensions.has((0, node_path_1.extname)(entry))) {
|
|
27
34
|
files.push(full);
|
|
28
35
|
}
|
|
29
36
|
}
|
|
@@ -35,10 +42,10 @@ function hasSrcDirectory(dir) {
|
|
|
35
42
|
return (0, node_fs_1.existsSync)((0, node_path_1.join)(dir, "src"));
|
|
36
43
|
}
|
|
37
44
|
/** Code files directly in `dir`, not in its subdirectories. */
|
|
38
|
-
function collectTopLevelCodeFiles(dir) {
|
|
45
|
+
function collectTopLevelCodeFiles(dir, extensions = CODE_EXTENSIONS) {
|
|
39
46
|
return (0, node_fs_1.readdirSync)(dir)
|
|
40
47
|
.map((entry) => (0, node_path_1.join)(dir, entry))
|
|
41
|
-
.filter((full) => (0, node_fs_1.statSync)(full).isFile() &&
|
|
48
|
+
.filter((full) => (0, node_fs_1.statSync)(full).isFile() && extensions.has((0, node_path_1.extname)(full)));
|
|
42
49
|
}
|
|
43
50
|
/**
|
|
44
51
|
* Which files a scan reads:
|
|
@@ -56,6 +63,25 @@ function selectFiles(dir, shouldScanAll) {
|
|
|
56
63
|
return collectCodeFiles((0, node_path_1.join)(dir, "src"));
|
|
57
64
|
return collectTopLevelCodeFiles(dir);
|
|
58
65
|
}
|
|
66
|
+
/** The files selectFiles would have read had V(g) rules for their language.
|
|
67
|
+
* `target/` is skipped: it is Rust's build output, not the gene's source. */
|
|
68
|
+
function selectUnscanned(dir, shouldScanAll) {
|
|
69
|
+
const files = shouldScanAll
|
|
70
|
+
? collectCodeFiles(dir, UNSUPPORTED_CODE_EXTENSIONS, ["target"])
|
|
71
|
+
: hasSrcDirectory(dir)
|
|
72
|
+
? collectCodeFiles((0, node_path_1.join)(dir, "src"), UNSUPPORTED_CODE_EXTENSIONS, ["target"])
|
|
73
|
+
: collectTopLevelCodeFiles(dir, UNSUPPORTED_CODE_EXTENSIONS);
|
|
74
|
+
return files.map((f) => (0, node_path_1.relative)(dir, f)).sort();
|
|
75
|
+
}
|
|
76
|
+
/** ".rs" files → "Rust"; unknown extensions are named by extension. */
|
|
77
|
+
function unscannedLanguages(files) {
|
|
78
|
+
const names = {
|
|
79
|
+
".rs": "Rust", ".go": "Go", ".c": "C", ".h": "C", ".cc": "C++", ".cpp": "C++", ".hpp": "C++",
|
|
80
|
+
".zig": "Zig", ".java": "Java", ".kt": "Kotlin", ".swift": "Swift", ".rb": "Ruby", ".cs": "C#",
|
|
81
|
+
};
|
|
82
|
+
const langs = [...new Set(files.map((f) => names[(0, node_path_1.extname)(f)] ?? (0, node_path_1.extname)(f)))];
|
|
83
|
+
return langs.join(", ");
|
|
84
|
+
}
|
|
59
85
|
function scanFile(filePath, rootDir) {
|
|
60
86
|
const content = (0, node_fs_1.readFileSync)(filePath, "utf-8");
|
|
61
87
|
const lines = content.split("\n");
|
|
@@ -98,6 +124,8 @@ function computeGrade(findings) {
|
|
|
98
124
|
function scan(dir, skillId, options) {
|
|
99
125
|
const shouldScanAll = options?.scanAll ?? false;
|
|
100
126
|
const files = selectFiles(dir, shouldScanAll);
|
|
127
|
+
const unscanned = selectUnscanned(dir, shouldScanAll);
|
|
128
|
+
const unscannedField = unscanned.length > 0 ? { unscanned } : {};
|
|
101
129
|
// No code read, no grade. computeGrade([]) is "A", and `--all` over a
|
|
102
130
|
// directory without code used to report exactly that: a clean result for
|
|
103
131
|
// code that was never looked at.
|
|
@@ -108,6 +136,7 @@ function scan(dir, skillId, options) {
|
|
|
108
136
|
grade: "?",
|
|
109
137
|
findings: [],
|
|
110
138
|
stats: { files_scanned: 0, lines_of_code: 0 },
|
|
139
|
+
...unscannedField,
|
|
111
140
|
};
|
|
112
141
|
}
|
|
113
142
|
const allFindings = [];
|
|
@@ -126,6 +155,7 @@ function scan(dir, skillId, options) {
|
|
|
126
155
|
files_scanned: files.length,
|
|
127
156
|
lines_of_code: totalLines,
|
|
128
157
|
},
|
|
158
|
+
...unscannedField,
|
|
129
159
|
};
|
|
130
160
|
}
|
|
131
161
|
//# sourceMappingURL=scanner.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scanner.js","sourceRoot":"","sources":["../../src/scanner/scanner.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"scanner.js","sourceRoot":"","sources":["../../src/scanner/scanner.ts"],"names":[],"mappings":"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"}
|
package/dist/scanner/types.d.ts
CHANGED
|
@@ -30,5 +30,8 @@ export interface ScanResult {
|
|
|
30
30
|
files_scanned: number;
|
|
31
31
|
lines_of_code: number;
|
|
32
32
|
};
|
|
33
|
+
/** Source files in a language V(g) has no rules for (e.g. Rust), relative to
|
|
34
|
+
* the scanned directory. They were not read: present only when there are any. */
|
|
35
|
+
unscanned?: string[];
|
|
33
36
|
}
|
|
34
37
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/scanner/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,CAAC;AACtD,MAAM,MAAM,KAAK,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAEhD,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,KAAK,EAAE;QACL,aAAa,EAAE,MAAM,CAAC;QACtB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/scanner/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,CAAC;AACtD,MAAM,MAAM,KAAK,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAEhD,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,KAAK,EAAE;QACL,aAAa,EAAE,MAAM,CAAC;QACtB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;IACF;qFACiF;IACjF,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB"}
|
package/dist/testsuite/gate.d.ts
CHANGED
|
@@ -32,9 +32,12 @@ export interface GateInput {
|
|
|
32
32
|
run: GeneRunner | null;
|
|
33
33
|
}
|
|
34
34
|
export declare function evaluatePublishGate(input: GateInput): GateVerdict;
|
|
35
|
-
/** Adapter
|
|
36
|
-
*
|
|
37
|
-
*
|
|
35
|
+
/** Adapter from the sandbox's result to a RunOutcome, shared by `rotifer test`
|
|
36
|
+
* and `rotifer publish`. An ADR-334 refusal is a refusal, as on the Node path
|
|
37
|
+
* (readErrorEnvelope): ADR-334 counts explicit INVALID_INPUT as handling, not a
|
|
38
|
+
* crash. Every other failure — a trap, a host error code, an L0 block — is
|
|
39
|
+
* reported as crashed: the caller cannot tell it from a defect. See
|
|
40
|
+
* runNegative. */
|
|
38
41
|
export declare function outcomeFromSandbox(r: {
|
|
39
42
|
success: boolean;
|
|
40
43
|
output?: unknown;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../../src/testsuite/gate.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEvD;;;;;;;;;GASG;AAEH,MAAM,MAAM,WAAW,GACnB;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,GACzD;IAAE,MAAM,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAoBjD,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE;QAAE,WAAW,CAAC,EAAE,OAAO,CAAC;QAAC,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC7D;oDACgD;IAChD,GAAG,EAAE,UAAU,GAAG,IAAI,CAAC;CACxB;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,SAAS,GAAG,WAAW,
|
|
1
|
+
{"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../../src/testsuite/gate.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEvD;;;;;;;;;GASG;AAEH,MAAM,MAAM,WAAW,GACnB;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,GACzD;IAAE,MAAM,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAoBjD,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE;QAAE,WAAW,CAAC,EAAE,OAAO,CAAC;QAAC,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC7D;oDACgD;IAChD,GAAG,EAAE,UAAU,GAAG,IAAI,CAAC;CACxB;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,SAAS,GAAG,WAAW,CAyEjE;AAMD;;;;;kBAKkB;AAClB,wBAAgB,kBAAkB,CAAC,CAAC,EAAE;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,UAAU,CAMb;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAUhE;AAED,wBAAsB,cAAc,CAClC,aAAa,EAAE,MAAM,EACrB,EAAE,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GACpC,OAAO,CAAC;IAAE,MAAM,EAAE,UAAU,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CA2CvD"}
|
package/dist/testsuite/gate.js
CHANGED
|
@@ -57,11 +57,15 @@ function evaluatePublishGate(input) {
|
|
|
57
57
|
inputSchema: input.phenotype.inputSchema ?? null,
|
|
58
58
|
outputSchema: input.phenotype.outputSchema ?? null,
|
|
59
59
|
run: input.run,
|
|
60
|
+
fidelity: input.fidelity,
|
|
60
61
|
});
|
|
61
62
|
if (report.gatePassed) {
|
|
63
|
+
// A retried property iteration is part of the verdict: say so.
|
|
64
|
+
const retried = report.results.find((r) => r.testId === "t1-property-schema-legality" && r.details?.includes("retried"));
|
|
62
65
|
return {
|
|
63
66
|
status: "passed",
|
|
64
|
-
details: `T1 satisfied — ${report.results.filter((r) => r.passed).length}/${report.results.length} checks
|
|
67
|
+
details: `T1 satisfied — ${report.results.filter((r) => r.passed).length}/${report.results.length} checks` +
|
|
68
|
+
(retried ? ` (${retried.details})` : ""),
|
|
65
69
|
};
|
|
66
70
|
}
|
|
67
71
|
const req = report.requirements;
|
|
@@ -86,13 +90,22 @@ function evaluatePublishGate(input) {
|
|
|
86
90
|
],
|
|
87
91
|
};
|
|
88
92
|
}
|
|
89
|
-
/**
|
|
90
|
-
*
|
|
91
|
-
|
|
93
|
+
/** The prefix the napi binding gives a GeneResult::Error{ INVALID_INPUT }
|
|
94
|
+
* (`"{code}: {message}"`), which only the ADR-334 envelope produces. */
|
|
95
|
+
const SANDBOX_REFUSAL_PREFIX = "INVALID_INPUT: ";
|
|
96
|
+
/** Adapter from the sandbox's result to a RunOutcome, shared by `rotifer test`
|
|
97
|
+
* and `rotifer publish`. An ADR-334 refusal is a refusal, as on the Node path
|
|
98
|
+
* (readErrorEnvelope): ADR-334 counts explicit INVALID_INPUT as handling, not a
|
|
99
|
+
* crash. Every other failure — a trap, a host error code, an L0 block — is
|
|
100
|
+
* reported as crashed: the caller cannot tell it from a defect. See
|
|
101
|
+
* runNegative. */
|
|
92
102
|
function outcomeFromSandbox(r) {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
103
|
+
if (r.success)
|
|
104
|
+
return { success: true, output: r.output, durationMs: r.durationMs };
|
|
105
|
+
if (r.errorMessage?.startsWith(SANDBOX_REFUSAL_PREFIX)) {
|
|
106
|
+
return { success: false, errorMessage: r.errorMessage, durationMs: r.durationMs };
|
|
107
|
+
}
|
|
108
|
+
return { success: false, crashed: true, errorMessage: r.errorMessage ?? undefined };
|
|
96
109
|
}
|
|
97
110
|
/**
|
|
98
111
|
* Build a GeneRunner for a Wrapped gene, which has no IR and executes in its
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gate.js","sourceRoot":"","sources":["../../src/testsuite/gate.ts"],"names":[],"mappings":";;AAgDA,
|
|
1
|
+
{"version":3,"file":"gate.js","sourceRoot":"","sources":["../../src/testsuite/gate.ts"],"names":[],"mappings":"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"}
|
package/dist/testsuite/run.d.ts
CHANGED
|
@@ -76,17 +76,9 @@ export declare function runPositive(c: ClassifiedCase, run: GeneRunner, outputVa
|
|
|
76
76
|
* source-linker through.
|
|
77
77
|
*/
|
|
78
78
|
export declare function runNegative(c: ClassifiedCase, run: GeneRunner, ajv: Ajv): TestResult;
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
*
|
|
83
|
-
* The seed is what makes a failure actionable — the same seed replays the same
|
|
84
|
-
* inputs, so a property failure can be reproduced rather than merely observed.
|
|
85
|
-
* When the suite gives no seed one is derived from nothing but a constant, so
|
|
86
|
-
* two runs of an unseeded suite still agree; randomness across runs would make
|
|
87
|
-
* the gate flaky and the flake would be blamed on the Gene.
|
|
88
|
-
*/
|
|
89
|
-
export declare function runProperty(suite: TestSuite, inputSchema: Record<string, unknown> | null, run: GeneRunner, outputValidator: ValidateFunction | null): TestResult;
|
|
79
|
+
export declare function runProperty(suite: TestSuite, inputSchema: Record<string, unknown> | null, run: GeneRunner, outputValidator: ValidateFunction | null, options?: {
|
|
80
|
+
retryNetworkFailures?: boolean;
|
|
81
|
+
}): TestResult;
|
|
90
82
|
export interface T1Report {
|
|
91
83
|
results: TestResult[];
|
|
92
84
|
classified: ClassifiedCase[];
|
|
@@ -103,6 +95,9 @@ export declare function runT1(suite: TestSuite, opts: {
|
|
|
103
95
|
inputSchema: Record<string, unknown> | null;
|
|
104
96
|
outputSchema: Record<string, unknown> | null;
|
|
105
97
|
run: GeneRunner;
|
|
98
|
+
/** The Gene's declared fidelity. A Hybrid Gene's property iterations may
|
|
99
|
+
* be retried once after a network failure (see runProperty). */
|
|
100
|
+
fidelity?: string;
|
|
106
101
|
}): T1Report;
|
|
107
102
|
/** Stable id for a report, for callers that persist results. */
|
|
108
103
|
export declare function newTestRunId(): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/testsuite/run.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,KAAK,CAAC;AAE5C,OAAO,KAAK,EACV,cAAc,EACd,QAAQ,EACR,UAAU,EACV,SAAS,EACV,MAAM,YAAY,CAAC;AAGpB,2EAA2E;AAC3E,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAE1C;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,yDAAyD;IACzD,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,+EAA+E;IAC/E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;oDAEgD;IAChD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,UAAU,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,UAAU,CAAC;AAE5E;;;;;;;;;;;;GAYG;AACH,wBAAgB,QAAQ,CACtB,SAAS,EAAE,QAAQ,EAAE,EACrB,cAAc,EAAE,gBAAgB,GAAG,IAAI,GACtC,cAAc,EAAE,CA2BlB;AA4CD;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CACzB,CAAC,EAAE,cAAc,EACjB,GAAG,EAAE,UAAU,EACf,eAAe,EAAE,gBAAgB,GAAG,IAAI,EACxC,GAAG,EAAE,GAAG,GACP,UAAU,CA2CZ;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,WAAW,CACzB,CAAC,EAAE,cAAc,EACjB,GAAG,EAAE,UAAU,EACf,GAAG,EAAE,GAAG,GACP,UAAU,CAmDZ;
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/testsuite/run.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,KAAK,CAAC;AAE5C,OAAO,KAAK,EACV,cAAc,EACd,QAAQ,EACR,UAAU,EACV,SAAS,EACV,MAAM,YAAY,CAAC;AAGpB,2EAA2E;AAC3E,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAE1C;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,yDAAyD;IACzD,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,+EAA+E;IAC/E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;oDAEgD;IAChD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,UAAU,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,UAAU,CAAC;AAE5E;;;;;;;;;;;;GAYG;AACH,wBAAgB,QAAQ,CACtB,SAAS,EAAE,QAAQ,EAAE,EACrB,cAAc,EAAE,gBAAgB,GAAG,IAAI,GACtC,cAAc,EAAE,CA2BlB;AA4CD;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CACzB,CAAC,EAAE,cAAc,EACjB,GAAG,EAAE,UAAU,EACf,eAAe,EAAE,gBAAgB,GAAG,IAAI,EACxC,GAAG,EAAE,GAAG,GACP,UAAU,CA2CZ;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,WAAW,CACzB,CAAC,EAAE,cAAc,EACjB,GAAG,EAAE,UAAU,EACf,GAAG,EAAE,GAAG,GACP,UAAU,CAmDZ;AAmBD,wBAAgB,WAAW,CACzB,KAAK,EAAE,SAAS,EAChB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,EAC3C,GAAG,EAAE,UAAU,EACf,eAAe,EAAE,gBAAgB,GAAG,IAAI,EACxC,OAAO,GAAE;IAAE,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAAO,GAC/C,UAAU,CAwDZ;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,8DAA8D;IAC9D,YAAY,EAAE;QACZ,QAAQ,EAAE,OAAO,CAAC;QAClB,QAAQ,EAAE,OAAO,CAAC;QAClB,QAAQ,EAAE,OAAO,CAAC;KACnB,CAAC;IACF,gFAAgF;IAChF,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,KAAK,CACnB,KAAK,EAAE,SAAS,EAChB,IAAI,EAAE;IACJ,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC5C,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC7C,GAAG,EAAE,UAAU,CAAC;IAChB;oEACgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GACA,QAAQ,CA6DV;AAED,gEAAgE;AAChE,wBAAgB,YAAY,IAAI,MAAM,CAErC"}
|
package/dist/testsuite/run.js
CHANGED
|
@@ -218,7 +218,13 @@ function runNegative(c, run, ajv) {
|
|
|
218
218
|
* two runs of an unseeded suite still agree; randomness across runs would make
|
|
219
219
|
* the gate flaky and the flake would be blamed on the Gene.
|
|
220
220
|
*/
|
|
221
|
-
|
|
221
|
+
/**
|
|
222
|
+
* Host codes that mean the network failed, not the Gene: -4 timeout, -5
|
|
223
|
+
* network, -7 the run's request limit (Hybrid Binding API §5). Matched on the
|
|
224
|
+
* code the sandbox reports, so -50 or a Gene's own -201 never count.
|
|
225
|
+
*/
|
|
226
|
+
const NETWORK_FAILURE = /gene returned error code: (-4|-5|-7)(?![0-9])/;
|
|
227
|
+
function runProperty(suite, inputSchema, run, outputValidator, options = {}) {
|
|
222
228
|
const started = Date.now();
|
|
223
229
|
const id = "t1-property-schema-legality";
|
|
224
230
|
const iterations = suite.config?.fuzzIterations ?? exports.DEFAULT_FUZZ_ITERATIONS;
|
|
@@ -229,9 +235,25 @@ function runProperty(suite, inputSchema, run, outputValidator) {
|
|
|
229
235
|
if (!outputValidator) {
|
|
230
236
|
return fail(id, started, "Gene declares no outputSchema, so schema legality cannot be asserted");
|
|
231
237
|
}
|
|
238
|
+
const retries = [];
|
|
232
239
|
for (let i = 0; i < iterations; i++) {
|
|
233
240
|
const input = (0, generate_js_1.generateTestInput)(inputSchema, seed + i);
|
|
234
|
-
|
|
241
|
+
let outcome = run(input);
|
|
242
|
+
// A Hybrid Gene's request can fail on the network alone, and a run with
|
|
243
|
+
// no output says nothing about schema legality. Such an iteration gets
|
|
244
|
+
// one more run with the same input; everything else is final.
|
|
245
|
+
const network = !outcome.success && options.retryNetworkFailures
|
|
246
|
+
? NETWORK_FAILURE.exec(outcome.errorMessage ?? "")
|
|
247
|
+
: null;
|
|
248
|
+
if (network) {
|
|
249
|
+
const first = outcome.errorMessage;
|
|
250
|
+
outcome = run(input);
|
|
251
|
+
if (!outcome.success) {
|
|
252
|
+
return fail(id, started, `iteration ${i + 1}/${iterations} did not produce output after one retry: ` +
|
|
253
|
+
`first ${first}; then ${outcome.errorMessage ?? "no message"}`, `reproduce with seed ${seed}, input ${JSON.stringify(input).slice(0, 200)}`);
|
|
254
|
+
}
|
|
255
|
+
retries.push(`iteration ${i + 1} was retried once after ${network[1]} (${first})`);
|
|
256
|
+
}
|
|
235
257
|
if (!outcome.success) {
|
|
236
258
|
return fail(id, started, `iteration ${i + 1}/${iterations} did not produce output: ${outcome.errorMessage ?? "no message"}`, `reproduce with seed ${seed}, input ${JSON.stringify(input).slice(0, 200)}`);
|
|
237
259
|
}
|
|
@@ -239,7 +261,8 @@ function runProperty(suite, inputSchema, run, outputValidator) {
|
|
|
239
261
|
return fail(id, started, `iteration ${i + 1}/${iterations} produced output violating outputSchema`, `reproduce with seed ${seed}, input ${JSON.stringify(input).slice(0, 200)}`);
|
|
240
262
|
}
|
|
241
263
|
}
|
|
242
|
-
|
|
264
|
+
const retried = retries.length > 0 ? `; ${retries.join("; ")}` : "";
|
|
265
|
+
return pass(id, started, `${iterations} generated inputs all produced schema-legal output (seed ${seed})${retried}`);
|
|
243
266
|
}
|
|
244
267
|
function runT1(suite, opts) {
|
|
245
268
|
const ajv = new ajv_1.default({ allErrors: true, strict: false });
|
|
@@ -266,7 +289,9 @@ function runT1(suite, opts) {
|
|
|
266
289
|
? runPositive(c, opts.run, outputValidator, ajv)
|
|
267
290
|
: runNegative(c, opts.run, ajv));
|
|
268
291
|
}
|
|
269
|
-
const property = runProperty(suite, opts.inputSchema, opts.run, outputValidator
|
|
292
|
+
const property = runProperty(suite, opts.inputSchema, opts.run, outputValidator, {
|
|
293
|
+
retryNetworkFailures: opts.fidelity === "Hybrid",
|
|
294
|
+
});
|
|
270
295
|
results.push(property);
|
|
271
296
|
const hasPassingPositive = classified.some((c, i) => c.kind === "positive" && results[i].passed);
|
|
272
297
|
const hasPassingNegative = classified.some((c, i) => c.kind === "negative" && results[i].passed);
|