@skill-harness/adapters 0.16.0 → 0.18.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 +0 -28
- package/dist/index.js +0 -28
- package/dist/pi.js +21 -133
- package/package.json +2 -3
- package/dist/archive-access.d.ts +0 -58
- package/dist/archive-access.js +0 -61
- package/dist/archive-checkpoint.d.ts +0 -47
- package/dist/archive-checkpoint.js +0 -116
- package/dist/archive-facts.d.ts +0 -19
- package/dist/archive-facts.js +0 -20
- package/dist/archive-observer.d.ts +0 -21
- package/dist/archive-observer.js +0 -79
- package/dist/archive-policy.d.ts +0 -107
- package/dist/archive-policy.js +0 -135
- package/dist/archive-read-capability.d.ts +0 -49
- package/dist/archive-read-capability.js +0 -45
- package/dist/archive-retention-policy.d.ts +0 -52
- package/dist/archive-retention-policy.js +0 -49
- package/dist/archived-work.d.ts +0 -45
- package/dist/archived-work.js +0 -78
- package/dist/blind-intervention.d.ts +0 -35
- package/dist/blind-intervention.js +0 -218
- package/dist/codex-diagnostic-model.d.ts +0 -14
- package/dist/codex-diagnostic-model.js +0 -39
- package/dist/codex-host-observer.d.ts +0 -111
- package/dist/codex-host-observer.js +0 -309
- package/dist/codex-https.d.ts +0 -7
- package/dist/codex-https.js +0 -221
- package/dist/codex-model-profile.d.ts +0 -38
- package/dist/codex-model-profile.js +0 -54
- package/dist/codex-producer-ipc.d.ts +0 -55
- package/dist/codex-producer-ipc.js +0 -67
- package/dist/codex-sdk-transport.d.ts +0 -50
- package/dist/codex-sdk-transport.js +0 -294
- package/dist/codex-subscription.d.ts +0 -114
- package/dist/codex-subscription.js +0 -268
- package/dist/evidence-archive.d.ts +0 -65
- package/dist/evidence-archive.js +0 -225
- package/dist/execution-projection-schema.d.ts +0 -10
- package/dist/execution-projection-schema.js +0 -30
- package/dist/execution-retention-archive.d.ts +0 -69
- package/dist/execution-retention-archive.js +0 -154
- package/dist/generated/retention-v2-contract.d.ts +0 -72
- package/dist/generated/retention-v2-contract.js +0 -105
- package/dist/generated/retention-v2-json.d.ts +0 -24
- package/dist/generated/retention-v2-json.js +0 -268
- package/dist/generated/retention-v2-native-json.d.ts +0 -2
- package/dist/generated/retention-v2-native-json.js +0 -33
- package/dist/generated/retention-v2-native.d.ts +0 -58
- package/dist/generated/retention-v2-native.js +0 -155
- package/dist/generated/retention-v2-pin.d.ts +0 -2
- package/dist/generated/retention-v2-pin.js +0 -4
- package/dist/generated/retention-v2-types.d.ts +0 -49
- package/dist/generated/retention-v2-types.js +0 -2
- package/dist/generated/retention-v2-work-types.d.ts +0 -260
- package/dist/generated/retention-v2-work-types.js +0 -13
- package/dist/generated/work-v4/execution-id.d.ts +0 -5
- package/dist/generated/work-v4/execution-id.js +0 -14
- package/dist/generated/work-v4/json.d.ts +0 -24
- package/dist/generated/work-v4/json.js +0 -268
- package/dist/generated/work-v4/occurrences.d.ts +0 -226
- package/dist/generated/work-v4/occurrences.js +0 -116
- package/dist/generated/work-v4/pin.d.ts +0 -1
- package/dist/generated/work-v4/pin.js +0 -3
- package/dist/generated/work-v4/projection.d.ts +0 -294
- package/dist/generated/work-v4/projection.js +0 -238
- package/dist/generated/work-v4/reader.d.ts +0 -24
- package/dist/generated/work-v4/reader.js +0 -109
- package/dist/generated/work-v4/snapshot.d.ts +0 -28
- package/dist/generated/work-v4/snapshot.js +0 -268
- package/dist/generated/work-v4/types.d.ts +0 -260
- package/dist/generated/work-v4/types.js +0 -13
- package/dist/generated/work-v4/validation.d.ts +0 -13
- package/dist/generated/work-v4/validation.js +0 -227
- package/dist/installed-review-session.d.ts +0 -28
- package/dist/installed-review-session.js +0 -166
- package/dist/intervention-run.d.ts +0 -403
- package/dist/intervention-run.js +0 -169
- package/dist/learning-case.d.ts +0 -12
- package/dist/learning-case.js +0 -15
- package/dist/learning-journal.d.ts +0 -18
- package/dist/learning-journal.js +0 -256
- package/dist/learning-lifecycle.d.ts +0 -28
- package/dist/learning-lifecycle.js +0 -66
- package/dist/learning-trust-setup.d.ts +0 -64
- package/dist/learning-trust-setup.js +0 -55
- package/dist/learning-workspace.d.ts +0 -930
- package/dist/learning-workspace.js +0 -663
- package/dist/principal-payload-port.d.ts +0 -25
- package/dist/principal-payload-port.js +0 -40
- package/dist/producer-product.d.ts +0 -70
- package/dist/producer-product.js +0 -186
- package/dist/producer-review.d.ts +0 -53
- package/dist/producer-review.js +0 -207
- package/dist/prompt-capture-extension.d.ts +0 -10
- package/dist/prompt-capture-extension.js +0 -26
- package/dist/prompt-provenance.d.ts +0 -22
- package/dist/prompt-provenance.js +0 -146
- package/dist/reviewed-archive-export.d.ts +0 -42
- package/dist/reviewed-archive-export.js +0 -78
- package/dist/trust-lifecycle.d.ts +0 -152
- package/dist/trust-lifecycle.js +0 -209
- package/dist/weekly-investigation.d.ts +0 -237
- package/dist/weekly-investigation.js +0 -330
- package/dist/work-candidates.d.ts +0 -29
- package/dist/work-candidates.js +0 -78
- package/dist/work-case-archive.d.ts +0 -25
- package/dist/work-case-archive.js +0 -63
- package/dist/work-case-review.d.ts +0 -45
- package/dist/work-case-review.js +0 -220
- package/dist/work-signal-cases.d.ts +0 -15
- package/dist/work-signal-cases.js +0 -54
- package/dist/work-signal-observation.d.ts +0 -23
- package/dist/work-signal-observation.js +0 -89
package/dist/index.d.ts
CHANGED
|
@@ -1,34 +1,6 @@
|
|
|
1
|
-
export * from './producer-product.js';
|
|
2
1
|
import type { HarnessAdapter } from "@skill-harness/core";
|
|
3
2
|
import { piAdapter } from "./pi.js";
|
|
4
3
|
export declare function getAdapter(name: string): HarnessAdapter;
|
|
5
4
|
export { piAdapter };
|
|
6
|
-
export * from "./prompt-provenance.js";
|
|
7
5
|
export * from "./trajectory.js";
|
|
8
6
|
export * from "./pi-daddy-ledger-v3.js";
|
|
9
|
-
export * from "./evidence-archive.js";
|
|
10
|
-
export * from "./archive-checkpoint.js";
|
|
11
|
-
export * from "./archive-policy.js";
|
|
12
|
-
export * from "./execution-retention-archive.js";
|
|
13
|
-
export * from "./work-candidates.js";
|
|
14
|
-
export * from "./work-case-archive.js";
|
|
15
|
-
export * from "./work-signal-observation.js";
|
|
16
|
-
export * from "./work-signal-cases.js";
|
|
17
|
-
export * from "./work-case-review.js";
|
|
18
|
-
export * from "./archive-read-capability.js";
|
|
19
|
-
export * from "./archived-work.js";
|
|
20
|
-
export * from "./blind-intervention.js";
|
|
21
|
-
export * from "./learning-lifecycle.js";
|
|
22
|
-
export * from "./learning-workspace.js";
|
|
23
|
-
export * from "./learning-trust-setup.js";
|
|
24
|
-
export { learningHash, learningFile } from "./learning-journal.js";
|
|
25
|
-
export * from "./learning-case.js";
|
|
26
|
-
export * from "./archive-observer.js";
|
|
27
|
-
export * from "./weekly-investigation.js";
|
|
28
|
-
export * from "./intervention-run.js";
|
|
29
|
-
export * from "./principal-payload-port.js";
|
|
30
|
-
export * from "./reviewed-archive-export.js";
|
|
31
|
-
export * from "./archive-access.js";
|
|
32
|
-
export * from "./archive-facts.js";
|
|
33
|
-
export * from "./trust-lifecycle.js";
|
|
34
|
-
export * from "./producer-review.js";
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export * from './producer-product.js';
|
|
2
1
|
import { piAdapter } from "./pi.js";
|
|
3
2
|
/**
|
|
4
3
|
* Registered harnesses. pi is the only one (per project scope). The interface
|
|
@@ -15,33 +14,6 @@ export function getAdapter(name) {
|
|
|
15
14
|
return a;
|
|
16
15
|
}
|
|
17
16
|
export { piAdapter };
|
|
18
|
-
export * from "./prompt-provenance.js";
|
|
19
17
|
export * from "./trajectory.js";
|
|
20
18
|
export * from "./pi-daddy-ledger-v3.js";
|
|
21
|
-
export * from "./evidence-archive.js";
|
|
22
|
-
export * from "./archive-checkpoint.js";
|
|
23
|
-
export * from "./archive-policy.js";
|
|
24
|
-
export * from "./execution-retention-archive.js";
|
|
25
|
-
export * from "./work-candidates.js";
|
|
26
|
-
export * from "./work-case-archive.js";
|
|
27
|
-
export * from "./work-signal-observation.js";
|
|
28
|
-
export * from "./work-signal-cases.js";
|
|
29
|
-
export * from "./work-case-review.js";
|
|
30
|
-
export * from "./archive-read-capability.js";
|
|
31
|
-
export * from "./archived-work.js";
|
|
32
|
-
export * from "./blind-intervention.js";
|
|
33
|
-
export * from "./learning-lifecycle.js";
|
|
34
|
-
export * from "./learning-workspace.js";
|
|
35
|
-
export * from "./learning-trust-setup.js";
|
|
36
|
-
export { learningHash, learningFile } from "./learning-journal.js";
|
|
37
|
-
export * from "./learning-case.js";
|
|
38
|
-
export * from "./archive-observer.js";
|
|
39
|
-
export * from "./weekly-investigation.js";
|
|
40
|
-
export * from "./intervention-run.js";
|
|
41
|
-
export * from "./principal-payload-port.js";
|
|
42
|
-
export * from "./reviewed-archive-export.js";
|
|
43
|
-
export * from "./archive-access.js";
|
|
44
|
-
export * from "./archive-facts.js";
|
|
45
|
-
export * from "./trust-lifecycle.js";
|
|
46
|
-
export * from "./producer-review.js";
|
|
47
19
|
//# sourceMappingURL=index.js.map
|
package/dist/pi.js
CHANGED
|
@@ -1,72 +1,9 @@
|
|
|
1
|
-
import { existsSync, mkdtempSync, readFileSync,
|
|
1
|
+
import { existsSync, mkdtempSync, readFileSync, statSync } from "node:fs";
|
|
2
2
|
import { tmpdir, homedir } from "node:os";
|
|
3
|
-
import { randomBytes } from "node:crypto";
|
|
4
3
|
import { join, resolve } from "node:path";
|
|
5
|
-
import { fileURLToPath } from "node:url";
|
|
6
4
|
import { runPiJson } from "./pi-json.js";
|
|
7
|
-
import {
|
|
8
|
-
import { bindPromptObservation, observeProviderPayload, promptCaptureIsTrusted, verifyPromptSummary } from "./prompt-provenance.js";
|
|
9
|
-
import { exec, onPath, envNum, traceSha256, withProviderFailure, splitPromptDoc } from "@skill-harness/core";
|
|
5
|
+
import { exec, onPath, envNum, traceSha256, withProviderFailure } from "@skill-harness/core";
|
|
10
6
|
const PI_TIMEOUT_MS = envNum("PI_TIMEOUT_MS", 300_000);
|
|
11
|
-
const PROMPT_CAPTURE_EXTENSION = fileURLToPath(new URL("./prompt-capture-extension.js", import.meta.url));
|
|
12
|
-
function contractFor(req) {
|
|
13
|
-
if (req.systemPromptFile) {
|
|
14
|
-
const raw = readFileSync(req.systemPromptFile, "utf8");
|
|
15
|
-
return { text: raw, raw, mechanism: "system-prompt-file" };
|
|
16
|
-
}
|
|
17
|
-
const raw = readFileSync(join(requireSkillDir(req.skillDir, req.mode), "SKILL.md"), "utf8");
|
|
18
|
-
const body = splitPromptDoc(raw).body;
|
|
19
|
-
if (req.mode === "red")
|
|
20
|
-
return { text: body, raw, mechanism: "none" };
|
|
21
|
-
return { text: body, raw, mechanism: req.mode === "green" ? "pi-skill" : "append-system-prompt" };
|
|
22
|
-
}
|
|
23
|
-
const RUNTIME_INJECTION_ENV = ["NODE_OPTIONS", "NODE_PATH", "LD_PRELOAD", "DYLD_INSERT_LIBRARIES"];
|
|
24
|
-
function hasRuntimeInjection(req) {
|
|
25
|
-
return Boolean(req.armEnv && Object.keys(req.armEnv).length) || RUNTIME_INJECTION_ENV.some(key => Boolean(process.env[key]));
|
|
26
|
-
}
|
|
27
|
-
function captureSetup(req, env, contract, counter) {
|
|
28
|
-
if (!req.onPromptObservation)
|
|
29
|
-
return { env, finish: () => { } };
|
|
30
|
-
// Arbitrary scenario/arm extensions and runtime-injection env execute in Pi's
|
|
31
|
-
// process with full Node authority. Refuse a forgeable positive observation.
|
|
32
|
-
if (!promptCaptureIsTrusted(req.extensions?.length ?? 0, hasRuntimeInjection(req)))
|
|
33
|
-
return { env, finish: () => {
|
|
34
|
-
const empty = observeProviderPayload({}, contract.text, contract.mechanism, counter.value++);
|
|
35
|
-
req.onPromptObservation?.({ ...empty, status: "ERROR", error: "prompt delivery provenance is unauthenticated when subject extensions or runtime-injection env share Pi's process" });
|
|
36
|
-
} };
|
|
37
|
-
const dir = mkdtempSync(join(tmpdir(), "skill-harness-prompt-"));
|
|
38
|
-
const path = join(dir, "observations.jsonl"), contractPath = join(dir, "contract.json");
|
|
39
|
-
const authenticationKey = randomBytes(32).toString("hex");
|
|
40
|
-
writeFileSync(path, "", { mode: 0o600 });
|
|
41
|
-
writeFileSync(contractPath, JSON.stringify({ text: contract.text, mechanism: contract.mechanism, authentication_key: authenticationKey }), { mode: 0o600 });
|
|
42
|
-
const finish = () => {
|
|
43
|
-
try {
|
|
44
|
-
const lines = readFileSync(path, "utf8").split("\n").filter(Boolean);
|
|
45
|
-
const parsed = lines.map(line => { try {
|
|
46
|
-
return JSON.parse(line);
|
|
47
|
-
}
|
|
48
|
-
catch {
|
|
49
|
-
return null;
|
|
50
|
-
} });
|
|
51
|
-
const records = parsed.slice(0, -1), summary = parsed.at(-1);
|
|
52
|
-
if (!verifyPromptSummary(summary, records.length, authenticationKey)) {
|
|
53
|
-
const empty = observeProviderPayload({}, contract.text, contract.mechanism, counter.value++);
|
|
54
|
-
req.onPromptObservation?.({ ...empty, status: "ERROR", error: "Pi prompt observation log is missing, truncated, replayed, or unauthenticated" });
|
|
55
|
-
}
|
|
56
|
-
else
|
|
57
|
-
records.forEach((record, observerRequestIndex) => {
|
|
58
|
-
req.onPromptObservation?.(bindPromptObservation(record, contract.text, contract.mechanism, counter.value++, authenticationKey, observerRequestIndex));
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
finally {
|
|
62
|
-
rmSync(dir, { recursive: true, force: true });
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
return { env: { ...(env ?? process.env), SKILL_HARNESS_PROMPT_CAPTURE_FILE: path, SKILL_HARNESS_PROMPT_CONTRACT_FILE: contractPath }, finish };
|
|
66
|
-
}
|
|
67
|
-
function observerFlags(req) {
|
|
68
|
-
return req.onPromptObservation && promptCaptureIsTrusted(req.extensions?.length ?? 0, hasRuntimeInjection(req)) ? ["--extension", PROMPT_CAPTURE_EXTENSION] : [];
|
|
69
|
-
}
|
|
70
7
|
/**
|
|
71
8
|
* stderr fragments that mean the provider refused the request, so the run measured
|
|
72
9
|
* nothing about the model. Substring matching on a message pi passes through from
|
|
@@ -160,7 +97,6 @@ function header(turnNo, total, text) {
|
|
|
160
97
|
}
|
|
161
98
|
export const piAdapter = {
|
|
162
99
|
name: "pi",
|
|
163
|
-
observesPrompts: true,
|
|
164
100
|
available() {
|
|
165
101
|
return Promise.resolve(onPath("pi"));
|
|
166
102
|
},
|
|
@@ -196,18 +132,14 @@ export const piAdapter = {
|
|
|
196
132
|
"--no-context-files",
|
|
197
133
|
"--no-extensions",
|
|
198
134
|
...extensionFlags(req.extensions),
|
|
199
|
-
...observerFlags(req),
|
|
200
135
|
"--provider",
|
|
201
136
|
req.model.provider,
|
|
202
137
|
"--model",
|
|
203
138
|
req.model.model,
|
|
204
139
|
];
|
|
205
|
-
// Bind bytes once: argv and provenance must describe the same contract even if a file changes mid-run.
|
|
206
|
-
const contract = contractFor(req);
|
|
207
140
|
const flags = req.systemPromptFile
|
|
208
|
-
? ["--no-skills", "--append-system-prompt",
|
|
209
|
-
: skillFlags(req.mode, req.skillDir
|
|
210
|
-
const requestCounter = { value: 0 };
|
|
141
|
+
? ["--no-skills", "--append-system-prompt", readFileSync(req.systemPromptFile, "utf8")]
|
|
142
|
+
: skillFlags(req.mode, req.skillDir);
|
|
211
143
|
const total = req.turns.length;
|
|
212
144
|
const parts = [];
|
|
213
145
|
// The arm's env, merged over the harness's own — undefined (not `process.env`)
|
|
@@ -222,14 +154,7 @@ export const piAdapter = {
|
|
|
222
154
|
let providerFailure = null;
|
|
223
155
|
if (total === 1) {
|
|
224
156
|
const args = [...flags, ...common, "--no-session", "-p", req.turns[0]];
|
|
225
|
-
const
|
|
226
|
-
let r;
|
|
227
|
-
try {
|
|
228
|
-
r = await exec("pi", args, { cwd: req.cwd, timeoutMs: PI_TIMEOUT_MS, env: capture.env });
|
|
229
|
-
}
|
|
230
|
-
finally {
|
|
231
|
-
capture.finish();
|
|
232
|
-
}
|
|
157
|
+
const r = await exec("pi", args, { cwd: req.cwd, timeoutMs: PI_TIMEOUT_MS, env });
|
|
233
158
|
parts.push(header(1, 1, req.turns[0]));
|
|
234
159
|
parts.push(`<<< ASSISTANT:\n${r.stdout.trim()}\n`);
|
|
235
160
|
if (r.code !== 0) {
|
|
@@ -243,14 +168,7 @@ export const piAdapter = {
|
|
|
243
168
|
for (let i = 0; i < total; i++) {
|
|
244
169
|
const turnFlags = i === 0 ? ["--session-dir", session] : ["--session-dir", session, "-c"];
|
|
245
170
|
const args = [...flags, ...common, ...turnFlags, "-p", req.turns[i]];
|
|
246
|
-
const
|
|
247
|
-
let r;
|
|
248
|
-
try {
|
|
249
|
-
r = await exec("pi", args, { cwd: req.cwd, timeoutMs: PI_TIMEOUT_MS, env: capture.env });
|
|
250
|
-
}
|
|
251
|
-
finally {
|
|
252
|
-
capture.finish();
|
|
253
|
-
}
|
|
171
|
+
const r = await exec("pi", args, { cwd: req.cwd, timeoutMs: PI_TIMEOUT_MS, env });
|
|
254
172
|
parts.push(header(i + 1, total, req.turns[i]));
|
|
255
173
|
parts.push(`<<< ASSISTANT:\n${r.stdout.trim()}\n`);
|
|
256
174
|
if (r.code !== 0) {
|
|
@@ -282,17 +200,14 @@ export const piAdapter = {
|
|
|
282
200
|
"--no-context-files",
|
|
283
201
|
"--no-extensions",
|
|
284
202
|
...extensionFlags(req.extensions),
|
|
285
|
-
...observerFlags(req),
|
|
286
203
|
"--provider",
|
|
287
204
|
req.model.provider,
|
|
288
205
|
"--model",
|
|
289
206
|
req.model.model,
|
|
290
207
|
];
|
|
291
|
-
const contract = contractFor(req);
|
|
292
208
|
const flags = req.systemPromptFile
|
|
293
|
-
? ["--no-skills", "--append-system-prompt",
|
|
294
|
-
: skillFlags(req.mode, req.skillDir
|
|
295
|
-
const requestCounter = { value: 0 };
|
|
209
|
+
? ["--no-skills", "--append-system-prompt", readFileSync(req.systemPromptFile, "utf8")]
|
|
210
|
+
: skillFlags(req.mode, req.skillDir);
|
|
296
211
|
const piVersion = await this.version();
|
|
297
212
|
const total = req.turns.length;
|
|
298
213
|
const traces = [];
|
|
@@ -309,26 +224,19 @@ export const piAdapter = {
|
|
|
309
224
|
? ["--session-dir", session]
|
|
310
225
|
: ["--session-dir", session, "-c"];
|
|
311
226
|
const args = [...flags, ...common, "--mode", "json", ...turnFlags, "-p", req.turns[i]];
|
|
312
|
-
const
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
homeDir: homedir(),
|
|
326
|
-
env: capture.env,
|
|
327
|
-
});
|
|
328
|
-
}
|
|
329
|
-
finally {
|
|
330
|
-
capture.finish();
|
|
331
|
-
}
|
|
227
|
+
const r = await runPiJson({
|
|
228
|
+
args,
|
|
229
|
+
cwd: req.cwd,
|
|
230
|
+
timeoutMs: PI_TIMEOUT_MS,
|
|
231
|
+
piVersion,
|
|
232
|
+
subject: req.model,
|
|
233
|
+
scenarioId: req.scenarioId ?? "(unknown)",
|
|
234
|
+
mode: req.mode,
|
|
235
|
+
rep: req.rep ?? 0,
|
|
236
|
+
turn: i,
|
|
237
|
+
homeDir: homedir(),
|
|
238
|
+
env,
|
|
239
|
+
});
|
|
332
240
|
// A stream with no terminal events at all is not evidence of a clean run.
|
|
333
241
|
// Fail loudly here rather than let an empty trace satisfy a `forbid_calls`
|
|
334
242
|
// gate — "the model called nothing" and "we recorded nothing" must not
|
|
@@ -356,29 +264,9 @@ export const piAdapter = {
|
|
|
356
264
|
if (r.code !== 0)
|
|
357
265
|
parts.push(`[pi exited ${r.code} on turn ${i + 1}]\n${r.stderr.trim()}\n`);
|
|
358
266
|
}
|
|
359
|
-
const native = req.eventSources?.length
|
|
360
|
-
? collectTrajectorySources(req.cwd, req.eventSources)
|
|
361
|
-
: { events: [], errors: [] };
|
|
362
|
-
const piEvents = normalizePiTraces(traces);
|
|
363
|
-
const combined = [...piEvents, ...native.events];
|
|
364
|
-
const chronologyErrors = [];
|
|
365
|
-
if (piEvents.length && native.events.length) {
|
|
366
|
-
if (combined.some((event) => !event.at || !Number.isFinite(Date.parse(event.at)))) {
|
|
367
|
-
chronologyErrors.push("pi/native events cannot be globally ordered because at least one event has no valid `at` timestamp");
|
|
368
|
-
}
|
|
369
|
-
else {
|
|
370
|
-
const piTimes = new Set(piEvents.map((event) => Date.parse(event.at)));
|
|
371
|
-
if (native.events.some((event) => piTimes.has(Date.parse(event.at)))) {
|
|
372
|
-
chronologyErrors.push("pi/native events contain equal timestamps, so strict cross-source order is ambiguous");
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
const eventErrors = [...native.errors, ...chronologyErrors];
|
|
377
267
|
return {
|
|
378
268
|
transcript: withProviderFailure(parts.join("\n"), providerFailure),
|
|
379
269
|
traces,
|
|
380
|
-
events: resequence(combined),
|
|
381
|
-
...(eventErrors.length ? { eventErrors } : {}),
|
|
382
270
|
...(providerFailure ? { providerFailure } : {}),
|
|
383
271
|
};
|
|
384
272
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skill-harness/adapters",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "skill-harness harness adapters — pi runner + claude-code judge routing (internal API)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -40,7 +40,6 @@
|
|
|
40
40
|
"prepack": "node ../../scripts/release-pack.mjs --guard"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@skill-harness/core": "0.
|
|
44
|
-
"typebox": "1.3.4"
|
|
43
|
+
"@skill-harness/core": "0.18.0"
|
|
45
44
|
}
|
|
46
45
|
}
|
package/dist/archive-access.d.ts
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
export interface ArchiveAccessPolicy {
|
|
2
|
-
archiveRoot: string;
|
|
3
|
-
id: string;
|
|
4
|
-
expiresAt: number;
|
|
5
|
-
maxCalls: number;
|
|
6
|
-
maxBytes: number;
|
|
7
|
-
purposes: string[];
|
|
8
|
-
}
|
|
9
|
-
export interface ArchiveConsent {
|
|
10
|
-
manifestId: string;
|
|
11
|
-
purpose: string;
|
|
12
|
-
expiresAt: number;
|
|
13
|
-
}
|
|
14
|
-
export interface GovernedArchiveRoute {
|
|
15
|
-
directory: string;
|
|
16
|
-
purpose: string;
|
|
17
|
-
}
|
|
18
|
-
export declare function createArchiveAccess(path: string, raw: ArchiveAccessPolicy, permissions: string[]): {
|
|
19
|
-
inspect: () => {
|
|
20
|
-
policy: ArchiveAccessPolicy;
|
|
21
|
-
lastObservedNow: number;
|
|
22
|
-
consents: {
|
|
23
|
-
id: unknown;
|
|
24
|
-
grant: ArchiveConsent;
|
|
25
|
-
state: string;
|
|
26
|
-
}[];
|
|
27
|
-
calls: number;
|
|
28
|
-
bytes: number;
|
|
29
|
-
pending: number;
|
|
30
|
-
};
|
|
31
|
-
previewConsent: (g: ArchiveConsent) => string;
|
|
32
|
-
previewRevocation: (id: string) => string;
|
|
33
|
-
consent(raw: ArchiveConsent, permissions: string[], now: number): string;
|
|
34
|
-
revoke(id: string, permissions: string[], now: number): void;
|
|
35
|
-
read(manifestId: string, purpose: string, maxBytes: number, now?: number): import("./evidence-archive.js").ArchiveRead;
|
|
36
|
-
};
|
|
37
|
-
/** Shared cooperative access owner. No history deletion, authentication, OS
|
|
38
|
-
* deadline guarantee, or reinterpretation of legacy raw archive APIs. */
|
|
39
|
-
export declare function openArchiveAccess(path: string): {
|
|
40
|
-
inspect: () => {
|
|
41
|
-
policy: ArchiveAccessPolicy;
|
|
42
|
-
lastObservedNow: number;
|
|
43
|
-
consents: {
|
|
44
|
-
id: unknown;
|
|
45
|
-
grant: ArchiveConsent;
|
|
46
|
-
state: string;
|
|
47
|
-
}[];
|
|
48
|
-
calls: number;
|
|
49
|
-
bytes: number;
|
|
50
|
-
pending: number;
|
|
51
|
-
};
|
|
52
|
-
previewConsent: (g: ArchiveConsent) => string;
|
|
53
|
-
previewRevocation: (id: string) => string;
|
|
54
|
-
consent(raw: ArchiveConsent, permissions: string[], now: number): string;
|
|
55
|
-
revoke(id: string, permissions: string[], now: number): void;
|
|
56
|
-
read(manifestId: string, purpose: string, maxBytes: number, now?: number): import("./evidence-archive.js").ArchiveRead;
|
|
57
|
-
};
|
|
58
|
-
export declare function readGovernedArchive(root: string, manifestId: string, maxBytes: number, route: GovernedArchiveRoute, now?: number): import("./evidence-archive.js").ArchiveRead;
|
package/dist/archive-access.js
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { learningCopy, learningHash, learningJournal, registerLearningStore, verifyLearningStore } from './learning-journal.js';
|
|
2
|
-
import { readArchiveSource } from './evidence-archive.js';
|
|
3
|
-
export function createArchiveAccess(path, raw, permissions) {
|
|
4
|
-
const policy = learningCopy(raw), binding = learningHash(policy);
|
|
5
|
-
if (!permissions.includes(binding))
|
|
6
|
-
throw Error('exact archive policy permission required');
|
|
7
|
-
validate(policy);
|
|
8
|
-
registerLearningStore(policy.archiveRoot, 'access', learningHash(policy.id), path, binding);
|
|
9
|
-
learningJournal(path, { type: 'archive-access-v1', policy, binding });
|
|
10
|
-
return openArchiveAccess(path);
|
|
11
|
-
}
|
|
12
|
-
function validate(p) { if (typeof p.id !== 'string' || !p.id.length || p.id.length > 128 || !Number.isSafeInteger(p.expiresAt) || p.expiresAt < 0 || !Number.isSafeInteger(p.maxCalls) || p.maxCalls < 1 || p.maxCalls > 1024 || !Number.isSafeInteger(p.maxBytes) || p.maxBytes < 1 || p.maxBytes > 64 * 1024 * 1024 || !Array.isArray(p.purposes) || !p.purposes.length || p.purposes.length > 16 || new Set(p.purposes).size !== p.purposes.length || p.purposes.some(s => typeof s !== 'string' || !s.length || s.length > 128))
|
|
13
|
-
throw Error('bounded archive access policy required'); }
|
|
14
|
-
/** Shared cooperative access owner. No history deletion, authentication, OS
|
|
15
|
-
* deadline guarantee, or reinterpretation of legacy raw archive APIs. */
|
|
16
|
-
export function openArchiveAccess(path) {
|
|
17
|
-
const journal = learningJournal(path), first = journal.read()[0].value, policy = learningCopy(first.policy);
|
|
18
|
-
validate(policy);
|
|
19
|
-
if (first.type !== 'archive-access-v1' || learningHash(policy) !== first.binding)
|
|
20
|
-
throw Error('archive policy changed');
|
|
21
|
-
const history = () => { verifyLearningStore(policy.archiveRoot, 'access', learningHash(policy.id), path, String(first.binding)); return journal.read(); };
|
|
22
|
-
const clock = (now) => { const rows = history(); if (!Number.isSafeInteger(now) || now < Math.max(0, ...rows.map(e => Number(e.value.now ?? 0))))
|
|
23
|
-
throw Error('archive access clock rewind'); journal.append(rows.at(-1).id, { type: 'clock', now }); if (now >= policy.expiresAt)
|
|
24
|
-
throw Error('archive access expired'); };
|
|
25
|
-
const consent = (raw) => { const g = learningCopy(raw); if (!/^[a-f0-9]{64}$/.test(g.manifestId) || !policy.purposes.includes(g.purpose) || !Number.isSafeInteger(g.expiresAt) || g.expiresAt < 0 || g.expiresAt > policy.expiresAt)
|
|
26
|
-
throw Error('consent outside policy'); return g; };
|
|
27
|
-
const digest = (g) => learningHash({ policy: String(first.binding), consent: consent(g) });
|
|
28
|
-
const revokeDigest = (id) => learningHash({ policy: String(first.binding), revoke: id });
|
|
29
|
-
const inspect = () => { const rows = history(), claims = rows.filter(e => e.value.type === 'read-claim'), lastObservedNow = Math.max(0, ...rows.map(e => Number(e.value.now ?? 0))); return { policy: learningCopy(policy), lastObservedNow, consents: rows.filter(e => e.value.type === 'consented').map(e => { const grant = e.value.grant; return { id: e.value.consentId, grant: learningCopy(grant), state: rows.some(r => r.value.type === 'revoked' && r.value.consentId === e.value.consentId) ? 'revoked' : lastObservedNow >= Math.min(policy.expiresAt, grant.expiresAt) ? 'expired' : 'not-revoked-at-last-observed-clock' }; }), calls: claims.length, bytes: claims.reduce((n, e) => { const settled = rows.find(s => s.value.type === 'read-settled' && s.value.claim === e.id); return n + Number(settled ? settled.value.bytes : e.value.reserved); }, 0), pending: claims.filter(e => !rows.some(s => s.value.type === 'read-settled' && s.value.claim === e.id)).length }; };
|
|
30
|
-
return { inspect, previewConsent: digest, previewRevocation: revokeDigest,
|
|
31
|
-
consent(raw, permissions, now) { clock(now); const g = consent(raw), id = digest(g), rows = history(); if (!permissions.includes(id) || now >= g.expiresAt)
|
|
32
|
-
throw Error('exact current consent permission required'); if (rows.some(e => e.value.type === 'revoked' && e.value.consentId === id))
|
|
33
|
-
throw Error('consent revoked'); if (!rows.some(e => e.value.type === 'consented' && e.value.consentId === id))
|
|
34
|
-
journal.append(rows.at(-1).id, { type: 'consented', consentId: id, grant: g, now }); return id; },
|
|
35
|
-
revoke(id, permissions, now) { clock(now); const rows = history(); if (!permissions.includes(revokeDigest(id)) || !rows.some(e => e.value.type === 'consented' && e.value.consentId === id))
|
|
36
|
-
throw Error('exact revocation permission required'); if (!rows.some(e => e.value.type === 'revoked' && e.value.consentId === id))
|
|
37
|
-
journal.append(rows.at(-1).id, { type: 'revoked', consentId: id, now }); },
|
|
38
|
-
read(manifestId, purpose, maxBytes, now = Date.now()) {
|
|
39
|
-
clock(now);
|
|
40
|
-
const rows = history(), valid = rows.filter(e => e.value.type === 'consented').filter(e => { const g = e.value.grant; return g.manifestId === manifestId && g.purpose === purpose && now < g.expiresAt && !rows.some(r => r.value.type === 'revoked' && r.value.consentId === e.value.consentId); });
|
|
41
|
-
if (valid.length !== 1)
|
|
42
|
-
throw Error('unique active manifest/purpose consent required');
|
|
43
|
-
if (!Number.isSafeInteger(maxBytes) || maxBytes < 0 || maxBytes > 8 * 1024 * 1024)
|
|
44
|
-
throw Error('archive read bound');
|
|
45
|
-
const used = inspect();
|
|
46
|
-
if (used.calls >= policy.maxCalls || maxBytes > policy.maxBytes - used.bytes)
|
|
47
|
-
throw Error('shared archive budget exhausted');
|
|
48
|
-
const claim = journal.append(rows.at(-1).id, { type: 'read-claim', manifestId, purpose, consentId: valid[0].value.consentId, reserved: maxBytes, now });
|
|
49
|
-
const result = readArchiveSource(policy.archiveRoot, manifestId, maxBytes);
|
|
50
|
-
journal.append(claim.id, { type: 'read-settled', claim: claim.id, bytes: result.status === 'available' ? result.bytes.length : 0, status: result.status, now });
|
|
51
|
-
return result;
|
|
52
|
-
},
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
export function readGovernedArchive(root, manifestId, maxBytes, route, now = Date.now()) {
|
|
56
|
-
const access = openArchiveAccess(route.directory);
|
|
57
|
-
if (access.inspect().policy.archiveRoot !== root)
|
|
58
|
-
throw Error('governed archive root mismatch');
|
|
59
|
-
return access.read(manifestId, route.purpose, maxBytes, now);
|
|
60
|
-
}
|
|
61
|
-
//# sourceMappingURL=archive-access.js.map
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { type ArchiveRead, type ArchiveSourceInput, type ArchiveRetention } from "./evidence-archive.js";
|
|
2
|
-
export type SnapshotChange = "initial" | "append" | "replaced" | "unknown";
|
|
3
|
-
export interface ArchiveCheckpoint {
|
|
4
|
-
version: "archive-checkpoint-v1";
|
|
5
|
-
sourceId: string;
|
|
6
|
-
sourceManifestId: string;
|
|
7
|
-
sourceSha256: string;
|
|
8
|
-
sourceBytes: number;
|
|
9
|
-
previousCheckpointId: string | null;
|
|
10
|
-
lineage: string;
|
|
11
|
-
declaredParser: {
|
|
12
|
-
id: string;
|
|
13
|
-
version: string;
|
|
14
|
-
};
|
|
15
|
-
reader: "jsonl-syntax-v1";
|
|
16
|
-
retention: ArchiveRetention;
|
|
17
|
-
change: SnapshotChange;
|
|
18
|
-
syntax: "complete" | "partial" | "error" | "unavailable";
|
|
19
|
-
completeBytes: number;
|
|
20
|
-
pendingBytes: number;
|
|
21
|
-
invalidLines: number;
|
|
22
|
-
issues: string[];
|
|
23
|
-
activeBranch: null;
|
|
24
|
-
acceptance: "not-assessed";
|
|
25
|
-
}
|
|
26
|
-
export interface ArchivedRecord {
|
|
27
|
-
id: string;
|
|
28
|
-
line: number;
|
|
29
|
-
start: number;
|
|
30
|
-
end: number;
|
|
31
|
-
value: unknown;
|
|
32
|
-
}
|
|
33
|
-
export interface CheckpointRead {
|
|
34
|
-
checkpoint: ArchiveCheckpoint;
|
|
35
|
-
source: ArchiveRead;
|
|
36
|
-
records: ArchivedRecord[];
|
|
37
|
-
}
|
|
38
|
-
/** Restart from the immutable checkpoint ID. This never advances a worker or invokes a gate. */
|
|
39
|
-
export declare function readArchiveCheckpoint(root: string, checkpointId: string): CheckpointRead;
|
|
40
|
-
/** Caller supplies an explicit snapshot, policy and prior receipt. No inferred active branch or acceptance. */
|
|
41
|
-
export declare function ingestArchiveSnapshot(root: string, input: ArchiveSourceInput & {
|
|
42
|
-
previousCheckpointId?: string;
|
|
43
|
-
}): CheckpointRead & {
|
|
44
|
-
checkpointId: string;
|
|
45
|
-
change: SnapshotChange | "repeat";
|
|
46
|
-
newRecords: ArchivedRecord[];
|
|
47
|
-
};
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import { createHash } from "node:crypto";
|
|
2
|
-
import { parseArchivedJsonl, readArchiveSource, retainArchiveSource, } from "./evidence-archive.js";
|
|
3
|
-
const hash = (value) => createHash("sha256").update(value).digest("hex");
|
|
4
|
-
const SHA = /^[a-f0-9]{64}$/;
|
|
5
|
-
const LIMIT = 8 * 1024 * 1024;
|
|
6
|
-
const parserEqual = (a, b) => a.id === b.id && a.version === b.version;
|
|
7
|
-
function reject() { throw new Error("invalid archive checkpoint"); }
|
|
8
|
-
function parseCheckpoint(bytes) {
|
|
9
|
-
const text = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
10
|
-
const v = JSON.parse(text);
|
|
11
|
-
if (JSON.stringify(v) !== text)
|
|
12
|
-
reject();
|
|
13
|
-
const names = ["version", "sourceId", "sourceManifestId", "sourceSha256", "sourceBytes", "previousCheckpointId", "lineage", "declaredParser", "reader", "retention", "change", "syntax", "completeBytes", "pendingBytes", "invalidLines", "issues", "activeBranch", "acceptance"];
|
|
14
|
-
if (!v || Object.keys(v).length !== names.length || Object.keys(v).some(k => !names.includes(k))
|
|
15
|
-
|| v.version !== "archive-checkpoint-v1" || v.reader !== "jsonl-syntax-v1"
|
|
16
|
-
|| typeof v.sourceId !== "string" || !/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/.test(v.sourceId)
|
|
17
|
-
|| ![v.sourceManifestId, v.sourceSha256, v.lineage].every(h => typeof h === "string" && SHA.test(h))
|
|
18
|
-
|| !(v.previousCheckpointId === null || (typeof v.previousCheckpointId === "string" && SHA.test(v.previousCheckpointId)))
|
|
19
|
-
|| ![v.sourceBytes, v.completeBytes, v.pendingBytes, v.invalidLines].every(n => Number.isSafeInteger(n) && n >= 0 && n <= LIMIT)
|
|
20
|
-
|| v.completeBytes + v.pendingBytes !== v.sourceBytes
|
|
21
|
-
|| !v.declaredParser || Object.keys(v.declaredParser).sort().join() !== "id,version"
|
|
22
|
-
|| ![v.declaredParser.id, v.declaredParser.version].every(s => typeof s === "string" && /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/.test(s))
|
|
23
|
-
|| !["exact", "redacted", "reference-only"].includes(v.retention)
|
|
24
|
-
|| !["initial", "append", "replaced", "unknown"].includes(v.change)
|
|
25
|
-
|| !["complete", "partial", "error", "unavailable"].includes(v.syntax)
|
|
26
|
-
|| (v.retention === "reference-only" && (v.syntax !== "unavailable" || v.completeBytes !== 0 || v.invalidLines !== 0))
|
|
27
|
-
|| !Array.isArray(v.issues) || v.issues.length > 16 || v.issues.some(i => typeof i !== "string" || i.length > 128)
|
|
28
|
-
|| v.activeBranch !== null || v.acceptance !== "not-assessed")
|
|
29
|
-
reject();
|
|
30
|
-
return v;
|
|
31
|
-
}
|
|
32
|
-
function records(checkpoint, source) {
|
|
33
|
-
if (source.status !== "available")
|
|
34
|
-
return [];
|
|
35
|
-
const parsed = parseArchivedJsonl(source.bytes);
|
|
36
|
-
return parsed.records.map(record => ({
|
|
37
|
-
...record, id: hash(JSON.stringify([checkpoint.sourceId, checkpoint.lineage, record.start, hash(source.bytes.subarray(record.start, record.end))])),
|
|
38
|
-
}));
|
|
39
|
-
}
|
|
40
|
-
/** Restart from the immutable checkpoint ID. This never advances a worker or invokes a gate. */
|
|
41
|
-
export function readArchiveCheckpoint(root, checkpointId) {
|
|
42
|
-
const stored = readArchiveSource(root, checkpointId);
|
|
43
|
-
if (stored.status !== "available" || stored.reference.retention !== "exact")
|
|
44
|
-
reject();
|
|
45
|
-
const checkpoint = parseCheckpoint(stored.bytes);
|
|
46
|
-
const source = readArchiveSource(root, checkpoint.sourceManifestId);
|
|
47
|
-
if (source.status === "available") {
|
|
48
|
-
const ref = source.reference;
|
|
49
|
-
if (ref.sourceId !== checkpoint.sourceId || ref.sha256 !== checkpoint.sourceSha256 || ref.bytes !== checkpoint.sourceBytes
|
|
50
|
-
|| ref.retention !== checkpoint.retention || !parserEqual(ref.parser, checkpoint.declaredParser))
|
|
51
|
-
reject();
|
|
52
|
-
const actual = parseArchivedJsonl(source.bytes);
|
|
53
|
-
if (actual.status !== checkpoint.syntax || actual.completeBytes !== checkpoint.completeBytes
|
|
54
|
-
|| actual.pendingBytes !== checkpoint.pendingBytes || actual.errors.length !== checkpoint.invalidLines)
|
|
55
|
-
reject();
|
|
56
|
-
}
|
|
57
|
-
return { checkpoint, source, records: records(checkpoint, source) };
|
|
58
|
-
}
|
|
59
|
-
/** Caller supplies an explicit snapshot, policy and prior receipt. No inferred active branch or acceptance. */
|
|
60
|
-
export function ingestArchiveSnapshot(root, input) {
|
|
61
|
-
// Inspect the prior bytes BEFORE storing this snapshot, so reacquisition cannot disguise a prior gap.
|
|
62
|
-
const previous = input.previousCheckpointId ? readArchiveCheckpoint(root, input.previousCheckpointId) : undefined;
|
|
63
|
-
if (previous && previous.checkpoint.sourceId !== input.sourceId)
|
|
64
|
-
throw new Error("checkpoint source mismatch");
|
|
65
|
-
const captured = retainArchiveSource(root, input);
|
|
66
|
-
const source = readArchiveSource(root, captured.manifestId);
|
|
67
|
-
const issues = [];
|
|
68
|
-
let change = previous ? "unknown" : "initial";
|
|
69
|
-
let lineage = captured.manifestId;
|
|
70
|
-
if (previous) {
|
|
71
|
-
if (!parserEqual(previous.checkpoint.declaredParser, captured.reference.parser) || previous.checkpoint.retention !== input.retention) {
|
|
72
|
-
issues.push("parser-or-representation-changed");
|
|
73
|
-
}
|
|
74
|
-
else if (previous.source.status !== "available") {
|
|
75
|
-
issues.push("previous-content-unavailable");
|
|
76
|
-
}
|
|
77
|
-
else if (input.retention !== "exact") {
|
|
78
|
-
issues.push("non-exact-continuity-unknown");
|
|
79
|
-
}
|
|
80
|
-
else if (source.status === "available") {
|
|
81
|
-
if (captured.manifestId === previous.checkpoint.sourceManifestId) {
|
|
82
|
-
return { ...previous, checkpointId: input.previousCheckpointId, change: "repeat", newRecords: [] };
|
|
83
|
-
}
|
|
84
|
-
if (source.bytes.length >= previous.source.bytes.length && source.bytes.subarray(0, previous.source.bytes.length).equals(previous.source.bytes)) {
|
|
85
|
-
change = "append";
|
|
86
|
-
lineage = previous.checkpoint.lineage;
|
|
87
|
-
}
|
|
88
|
-
else {
|
|
89
|
-
change = "replaced";
|
|
90
|
-
issues.push("source-replaced");
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
if (input.retention === "redacted")
|
|
95
|
-
issues.push("redacted-representation");
|
|
96
|
-
if (source.status !== "available")
|
|
97
|
-
issues.push("content-not-retained");
|
|
98
|
-
const syntax = source.status === "available" ? parseArchivedJsonl(source.bytes) : undefined;
|
|
99
|
-
const checkpoint = {
|
|
100
|
-
version: "archive-checkpoint-v1", sourceId: input.sourceId,
|
|
101
|
-
sourceManifestId: captured.manifestId, sourceSha256: captured.reference.sha256, sourceBytes: captured.reference.bytes,
|
|
102
|
-
previousCheckpointId: input.previousCheckpointId ?? null, lineage,
|
|
103
|
-
declaredParser: captured.reference.parser, reader: "jsonl-syntax-v1", retention: input.retention, change,
|
|
104
|
-
syntax: syntax?.status ?? "unavailable", completeBytes: syntax?.completeBytes ?? 0,
|
|
105
|
-
pendingBytes: syntax?.pendingBytes ?? captured.reference.bytes, invalidLines: syntax?.errors.length ?? 0,
|
|
106
|
-
issues, activeBranch: null, acceptance: "not-assessed",
|
|
107
|
-
};
|
|
108
|
-
const result = retainArchiveSource(root, {
|
|
109
|
-
sourceId: `checkpoint-${hash(input.sourceId)}`, parser: { id: "archive-checkpoint", version: "1" },
|
|
110
|
-
retention: "exact", bytes: Buffer.from(JSON.stringify(checkpoint)),
|
|
111
|
-
});
|
|
112
|
-
const all = records(checkpoint, source);
|
|
113
|
-
return { checkpointId: result.manifestId, checkpoint, source, records: all, change,
|
|
114
|
-
newRecords: change === "append" ? all.filter(record => record.start >= previous.checkpoint.completeBytes) : all };
|
|
115
|
-
}
|
|
116
|
-
//# sourceMappingURL=archive-checkpoint.js.map
|
package/dist/archive-facts.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { WorkSignalFacts } from '@skill-harness/core';
|
|
2
|
-
import { type GovernedArchiveRoute } from './archive-access.js';
|
|
3
|
-
/** Operational fixed-order fact adapter, not arbitrary model/host fact inference.
|
|
4
|
-
* The caller supplies independent scope/source pins; all actual bytes use consent. */
|
|
5
|
-
export declare function readFixedOrderFacts(root: string, manifestId: string, route: GovernedArchiveRoute, raw: {
|
|
6
|
-
producerCommit: string;
|
|
7
|
-
scopeDigest: string;
|
|
8
|
-
population: string;
|
|
9
|
-
obligations: string[];
|
|
10
|
-
}, now?: number): {
|
|
11
|
-
facts: WorkSignalFacts;
|
|
12
|
-
source: {
|
|
13
|
-
manifestId: string;
|
|
14
|
-
sha256: string;
|
|
15
|
-
producerCommit: string;
|
|
16
|
-
};
|
|
17
|
-
unknownNodes: any;
|
|
18
|
-
acceptance: "not-assessed";
|
|
19
|
-
};
|
package/dist/archive-facts.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { createHash } from 'node:crypto';
|
|
2
|
-
import { readGovernedArchive } from './archive-access.js';
|
|
3
|
-
import { learningCopy } from './learning-journal.js';
|
|
4
|
-
/** Operational fixed-order fact adapter, not arbitrary model/host fact inference.
|
|
5
|
-
* The caller supplies independent scope/source pins; all actual bytes use consent. */
|
|
6
|
-
export function readFixedOrderFacts(root, manifestId, route, raw, now = Date.now()) {
|
|
7
|
-
const expected = learningCopy(raw);
|
|
8
|
-
if (!/^[a-f0-9]{40}$/.test(expected.producerCommit) || !/^[a-f0-9]{64}$/.test(expected.scopeDigest) || typeof expected.population !== 'string' || !expected.population.length || expected.population.length > 512 || /[\u0000-\u001f\u007f]/.test(expected.population) || !Array.isArray(expected.obligations) || expected.obligations.length > 128 || expected.obligations.some(h => !/^[a-f0-9]{64}$/.test(h)))
|
|
9
|
-
throw Error('explicit fact source/scope pins required');
|
|
10
|
-
const read = readGovernedArchive(root, manifestId, 1024 * 1024, route, now);
|
|
11
|
-
if (read.status !== 'available' || read.reference.retention !== 'exact' || read.reference.parser.id !== 'factory-order-readback' || read.reference.parser.version !== '1')
|
|
12
|
-
throw Error('exact governed order readback required');
|
|
13
|
-
const value = JSON.parse(new TextDecoder('utf-8', { fatal: true }).decode(read.bytes));
|
|
14
|
-
if (value.kind !== 'actual-fixed-profile-order' || value.producerCommit !== expected.producerCommit || !Array.isArray(value.nodes) || !value.nodes.length || value.nodes.length > 128 || value.nodes.some((n) => !n || !expected.obligations.includes(n.obligation?.digest) || typeof n.state !== 'string'))
|
|
15
|
-
throw Error('order facts source/scope mismatch');
|
|
16
|
-
const digest = createHash('sha256').update(read.bytes).digest('hex');
|
|
17
|
-
const facts = { scopeDigest: expected.scopeDigest, version: 'fixed-order-facts-v1', population: expected.population, expectedWaits: [], checkpoints: [], violations: value.nodes.filter((n) => n.state === 'exhausted').map((n) => ({ obligationDigest: n.obligation.digest, status: 'FAIL', evidence: digest })), priorAccepted: [] };
|
|
18
|
-
return { facts, source: { manifestId, sha256: digest, producerCommit: expected.producerCommit }, unknownNodes: value.nodes.filter((n) => !['satisfied', 'exhausted'].includes(n.state)).length, acceptance: 'not-assessed' };
|
|
19
|
-
}
|
|
20
|
-
//# sourceMappingURL=archive-facts.js.map
|