@rulvar/executor 1.112.0 → 1.113.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.d.ts +10 -1
- package/dist/index.js +11 -7
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -273,8 +273,17 @@ interface CorruptLedgerLine {
|
|
|
273
273
|
}
|
|
274
274
|
/** A torn fragment the writer quarantined while repairing a tail (RV502). */
|
|
275
275
|
interface TornLedgerArtifact {
|
|
276
|
-
/**
|
|
276
|
+
/**
|
|
277
|
+
* The torn fragment as a LOSSY string: invalid UTF-8 bytes decode to
|
|
278
|
+
* U+FFFD, so two different byte tails can read identically here.
|
|
279
|
+
* Kept for compatibility with rows written before RV707; use
|
|
280
|
+
* `bytesBase64` for the exact bytes.
|
|
281
|
+
*/
|
|
277
282
|
bytes: string;
|
|
283
|
+
/** The exact torn bytes, base64 (RV707); absent on rows written before it. */
|
|
284
|
+
bytesBase64?: string;
|
|
285
|
+
/** sha256 (hex) of the exact torn bytes (RV707); absent on legacy rows. */
|
|
286
|
+
sha256?: string;
|
|
278
287
|
/** Wall-clock ms when the writer quarantined the fragment. */
|
|
279
288
|
recoveredAt: number;
|
|
280
289
|
}
|
package/dist/index.js
CHANGED
|
@@ -612,6 +612,9 @@ function containerExecutor(options) {
|
|
|
612
612
|
* durability wraps the seam over its own fsync or database write.
|
|
613
613
|
*/
|
|
614
614
|
const wallClock = Date.now.bind(globalThis);
|
|
615
|
+
/** Strict decode (RV607/RV707): invalid UTF-8 is damage, never a
|
|
616
|
+
* replacement character that forges a key or a parseable fragment. */
|
|
617
|
+
const decodeStrict = (bytes) => new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
615
618
|
/** How stale a repair lock's mtime must be before a writer may presume
|
|
616
619
|
* its holder crashed and steal it. Repairs take milliseconds; ten
|
|
617
620
|
* seconds is a crash verdict, not a performance budget. */
|
|
@@ -671,10 +674,10 @@ async function repairUnderLock(path, now) {
|
|
|
671
674
|
}
|
|
672
675
|
if (raw.length === 0 || raw[raw.length - 1] === 10) return;
|
|
673
676
|
const boundary = raw.lastIndexOf(10) + 1;
|
|
674
|
-
const fragment = raw.subarray(boundary)
|
|
677
|
+
const fragment = raw.subarray(boundary);
|
|
675
678
|
let parseable = true;
|
|
676
679
|
try {
|
|
677
|
-
JSON.parse(fragment);
|
|
680
|
+
JSON.parse(decodeStrict(fragment));
|
|
678
681
|
} catch {
|
|
679
682
|
parseable = false;
|
|
680
683
|
}
|
|
@@ -686,7 +689,9 @@ async function repairUnderLock(path, now) {
|
|
|
686
689
|
await truncate(path, boundary);
|
|
687
690
|
await appendFile(path, `${JSON.stringify({
|
|
688
691
|
phase: "torn",
|
|
689
|
-
bytes: fragment,
|
|
692
|
+
bytes: fragment.toString("utf8"),
|
|
693
|
+
bytesBase64: fragment.toString("base64"),
|
|
694
|
+
sha256: createHash("sha256").update(fragment).digest("hex"),
|
|
690
695
|
recoveredAt: now()
|
|
691
696
|
})}\n`, "utf8");
|
|
692
697
|
return;
|
|
@@ -775,9 +780,6 @@ var LedgerCorruptionError = class extends Error {
|
|
|
775
780
|
this.lines = lines;
|
|
776
781
|
}
|
|
777
782
|
};
|
|
778
|
-
/** Strict per-line decode (RV607): invalid UTF-8 is damage, never a
|
|
779
|
-
* replacement character that forges a key. */
|
|
780
|
-
const decodeStrict = (bytes) => new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
781
783
|
const isRecordObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
782
784
|
const hasIntentShape = (value) => typeof value.idempotencyKey === "string" && typeof value.runId === "string" && typeof value.spanId === "string" && typeof value.tool === "string" && typeof value.argsHash === "string" && typeof value.executor === "string" && typeof value.workdir === "string" && typeof value.startedAt === "number" && (value.attemptId === void 0 || typeof value.attemptId === "string");
|
|
783
785
|
const OUTCOME_CLASSES = /* @__PURE__ */ new Set([
|
|
@@ -798,7 +800,7 @@ function asLedgerLine(parsed) {
|
|
|
798
800
|
if (!isRecordObject(parsed)) return void 0;
|
|
799
801
|
if (parsed.phase === "intent") return hasIntentShape(parsed) ? parsed : void 0;
|
|
800
802
|
if (parsed.phase === "outcome") return hasIntentShape(parsed) && typeof parsed.durationMs === "number" && OUTCOME_CLASSES.has(parsed.outcome) && (typeof parsed.exitCode === "number" || parsed.exitCode === null) && (typeof parsed.signal === "string" || parsed.signal === null) ? parsed : void 0;
|
|
801
|
-
if (parsed.phase === "torn") return typeof parsed.bytes === "string" && typeof parsed.recoveredAt === "number" ? parsed : void 0;
|
|
803
|
+
if (parsed.phase === "torn") return typeof parsed.bytes === "string" && typeof parsed.recoveredAt === "number" && (parsed.bytesBase64 === void 0 || typeof parsed.bytesBase64 === "string") && (parsed.sha256 === void 0 || typeof parsed.sha256 === "string") ? parsed : void 0;
|
|
802
804
|
}
|
|
803
805
|
/**
|
|
804
806
|
* Scans a JSONL ledger file into intents, outcomes, and the orphaned
|
|
@@ -867,6 +869,8 @@ async function loadEffectLedger(path, options) {
|
|
|
867
869
|
outcomes.push(rest);
|
|
868
870
|
} else tornArtifacts.push({
|
|
869
871
|
bytes: entry.bytes,
|
|
872
|
+
...entry.bytesBase64 === void 0 ? {} : { bytesBase64: entry.bytesBase64 },
|
|
873
|
+
...entry.sha256 === void 0 ? {} : { sha256: entry.sha256 },
|
|
870
874
|
recoveredAt: entry.recoveredAt
|
|
871
875
|
});
|
|
872
876
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rulvar/executor",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.113.0",
|
|
4
4
|
"description": "Rulvar isolated tool executors: reference ToolExecutorProvider adapters that run tool work out of process (subprocess and container) so hostile or model-generated scripts cannot reach host capabilities.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -22,13 +22,13 @@
|
|
|
22
22
|
"access": "public"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@rulvar/core": "1.
|
|
25
|
+
"@rulvar/core": "1.113.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@types/node": "^22.20.1",
|
|
29
29
|
"tsdown": "^0.22.14",
|
|
30
30
|
"typescript": "~6.0.3",
|
|
31
|
-
"@rulvar/testing": "1.
|
|
31
|
+
"@rulvar/testing": "1.113.0"
|
|
32
32
|
},
|
|
33
33
|
"repository": {
|
|
34
34
|
"type": "git",
|