@prooflane/inspector-beta 0.1.0-beta.7 → 0.1.0-beta.8
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/cli.mjs +1 -1
- package/dist/server.mjs +233 -87
- package/dist/ui/assets/index-CPtCo7m6.js +69 -0
- package/dist/ui/index.html +1 -1
- package/package.json +1 -1
- package/dist/ui/assets/index-T0eXH06n.js +0 -69
package/dist/server.mjs
CHANGED
|
@@ -1099,10 +1099,10 @@ function decodeJwt(jwt) {
|
|
|
1099
1099
|
}
|
|
1100
1100
|
|
|
1101
1101
|
// ../server/dist/app.js
|
|
1102
|
-
import { createHash as
|
|
1103
|
-
import { existsSync as
|
|
1102
|
+
import { createHash as createHash16, randomUUID as randomUUID8 } from "node:crypto";
|
|
1103
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "node:fs";
|
|
1104
1104
|
import { fileURLToPath } from "node:url";
|
|
1105
|
-
import { dirname as dirname4, join as
|
|
1105
|
+
import { dirname as dirname4, join as join5, resolve as resolve6 } from "node:path";
|
|
1106
1106
|
|
|
1107
1107
|
// ../core/dist/transport/mcpTransport.js
|
|
1108
1108
|
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
@@ -1386,9 +1386,9 @@ async function startCallbackServer(path = "/callback", port = callbackPort()) {
|
|
|
1386
1386
|
res.end(PAGE("Authorized \u2713", "You can close this tab and return to Kawach Inspector.")), resolveCode(code);
|
|
1387
1387
|
});
|
|
1388
1388
|
try {
|
|
1389
|
-
await new Promise((
|
|
1389
|
+
await new Promise((resolve7, reject) => {
|
|
1390
1390
|
server.once("error", reject), server.listen(port, "127.0.0.1", () => {
|
|
1391
|
-
server.off("error", reject),
|
|
1391
|
+
server.off("error", reject), resolve7();
|
|
1392
1392
|
});
|
|
1393
1393
|
});
|
|
1394
1394
|
} catch (err) {
|
|
@@ -1902,7 +1902,7 @@ var Store = class {
|
|
|
1902
1902
|
return this.db.prepare(`UPDATE benchmark_entitlements SET state = 'AVAILABLE', reservation_key = NULL, reserved_at = NULL
|
|
1903
1903
|
WHERE id = ? AND workspace_id = ? AND state = 'RESERVED' AND reservation_key = ?`).run(entitlementId, workspaceId, reservationKey), this.getBenchmarkEntitlement(entitlementId);
|
|
1904
1904
|
}
|
|
1905
|
-
saveBenchmarkRun(
|
|
1905
|
+
saveBenchmarkRun(record7) {
|
|
1906
1906
|
this.db.prepare(`INSERT INTO benchmark_runs
|
|
1907
1907
|
(run_id, workspace_id, status, plan_json, summary_json, report_json, report_html, created_at, updated_at)
|
|
1908
1908
|
VALUES (@run_id, @workspace_id, @status, @plan_json, @summary_json, @report_json, @report_html, @created_at, @updated_at)
|
|
@@ -1912,15 +1912,15 @@ var Store = class {
|
|
|
1912
1912
|
report_json = excluded.report_json,
|
|
1913
1913
|
report_html = excluded.report_html,
|
|
1914
1914
|
updated_at = excluded.updated_at`).run({
|
|
1915
|
-
run_id:
|
|
1916
|
-
workspace_id:
|
|
1917
|
-
status:
|
|
1918
|
-
plan_json: JSON.stringify(
|
|
1919
|
-
summary_json:
|
|
1920
|
-
report_json:
|
|
1921
|
-
report_html:
|
|
1922
|
-
created_at:
|
|
1923
|
-
updated_at:
|
|
1915
|
+
run_id: record7.runId,
|
|
1916
|
+
workspace_id: record7.workspaceId,
|
|
1917
|
+
status: record7.status,
|
|
1918
|
+
plan_json: JSON.stringify(record7.plan),
|
|
1919
|
+
summary_json: record7.summary ? JSON.stringify(record7.summary) : null,
|
|
1920
|
+
report_json: record7.report ? JSON.stringify(record7.report) : null,
|
|
1921
|
+
report_html: record7.reportHtml ?? null,
|
|
1922
|
+
created_at: record7.createdAt,
|
|
1923
|
+
updated_at: record7.updatedAt
|
|
1924
1924
|
});
|
|
1925
1925
|
}
|
|
1926
1926
|
getBenchmarkRun(runId) {
|
|
@@ -3152,12 +3152,12 @@ ${http2.content}`
|
|
|
3152
3152
|
addPromptCases(cases, source = "ai") {
|
|
3153
3153
|
let saved = [], skipped = 0;
|
|
3154
3154
|
for (let item of cases) {
|
|
3155
|
-
let [
|
|
3156
|
-
if (!
|
|
3155
|
+
let [record7] = this.addPrompts([{ category: item.category, name: item.name, content: item.content, tool: item.tool }], source);
|
|
3156
|
+
if (!record7) {
|
|
3157
3157
|
skipped += 1;
|
|
3158
3158
|
continue;
|
|
3159
3159
|
}
|
|
3160
|
-
item.assertions && item.assertions.length || item.checkSchema ? (this.store.setPromptChecks(
|
|
3160
|
+
item.assertions && item.assertions.length || item.checkSchema ? (this.store.setPromptChecks(record7.id, { assertions: item.assertions, checkSchema: item.checkSchema }), saved.push({ ...record7, assertions: item.assertions, checkSchema: item.checkSchema })) : saved.push(record7);
|
|
3161
3161
|
}
|
|
3162
3162
|
return { saved, skipped };
|
|
3163
3163
|
}
|
|
@@ -4688,13 +4688,13 @@ function fingerprintLocalSuite(suite) {
|
|
|
4688
4688
|
function executorForPillar(pillar) {
|
|
4689
4689
|
return pillar === "prompt" ? "PROMPT" : pillar === "rag" ? "RAG" : pillar === "contract" ? "CONTRACT" : pillar === "performance" ? "PERFORMANCE" : pillar === "model" ? "MODEL" : "MCP";
|
|
4690
4690
|
}
|
|
4691
|
-
function compileLegacyLocalSuiteManifest(suite,
|
|
4692
|
-
if (!/^sha256:[a-f0-9]{64}$/.test(
|
|
4691
|
+
function compileLegacyLocalSuiteManifest(suite, localFingerprint2 = fingerprintLocalSuite(suite)) {
|
|
4692
|
+
if (!/^sha256:[a-f0-9]{64}$/.test(localFingerprint2))
|
|
4693
4693
|
throw new Error("Local Suite migration fingerprint is invalid.");
|
|
4694
4694
|
let pillarCounts = {};
|
|
4695
4695
|
for (let test of suite.tests)
|
|
4696
4696
|
pillarCounts[test.pillar] = (pillarCounts[test.pillar] ?? 0) + 1;
|
|
4697
|
-
let assetName = `local-suite-${
|
|
4697
|
+
let assetName = `local-suite-${localFingerprint2.slice(7)}`, manifest = {
|
|
4698
4698
|
schemaVersion: "prooflane-suite-manifest-v1",
|
|
4699
4699
|
executionClass: "LOCAL_ONLY",
|
|
4700
4700
|
controls: PILLARS2.filter((pillar) => !!pillarCounts[pillar]).map((pillar) => ({
|
|
@@ -4707,7 +4707,7 @@ function compileLegacyLocalSuiteManifest(suite, localFingerprint = fingerprintLo
|
|
|
4707
4707
|
localRef: { kind: "PROJECT_ASSET", name: assetName },
|
|
4708
4708
|
parameters: {
|
|
4709
4709
|
schemaVersion: LOCAL_SUITE_MIGRATION_VERSION,
|
|
4710
|
-
localFingerprint,
|
|
4710
|
+
localFingerprint: localFingerprint2,
|
|
4711
4711
|
localVersion: suite.version,
|
|
4712
4712
|
testCount: pillarCounts[pillar]
|
|
4713
4713
|
}
|
|
@@ -4738,7 +4738,7 @@ function readLegacyLocalSuiteArtifact(file, cwd = process.cwd()) {
|
|
|
4738
4738
|
} catch (error) {
|
|
4739
4739
|
throw new Error(`Could not read local Suite ${basename(sourcePath)}: ${error instanceof Error ? error.message : String(error)}`);
|
|
4740
4740
|
}
|
|
4741
|
-
let suite = validateLegacyLocalSuite(parsed),
|
|
4741
|
+
let suite = validateLegacyLocalSuite(parsed), localFingerprint2 = fingerprintLocalSuite(suite), manifest = compileLegacyLocalSuiteManifest(suite, localFingerprint2), pillarCounts = {};
|
|
4742
4742
|
for (let test of suite.tests)
|
|
4743
4743
|
pillarCounts[test.pillar] = (pillarCounts[test.pillar] ?? 0) + 1;
|
|
4744
4744
|
let supported = suite.tests.filter(localSuiteTestIsGeneric).length, projectRelative = relative(cwd, sourcePath);
|
|
@@ -4748,7 +4748,7 @@ function readLegacyLocalSuiteArtifact(file, cwd = process.cwd()) {
|
|
|
4748
4748
|
projectRelativePath: projectRelative.startsWith("..") || projectRelative.startsWith("/") ? null : projectRelative,
|
|
4749
4749
|
slug: localSuiteSlug(suite.id),
|
|
4750
4750
|
displayName: localDisplayName(suite.id),
|
|
4751
|
-
localFingerprint,
|
|
4751
|
+
localFingerprint: localFingerprint2,
|
|
4752
4752
|
manifest,
|
|
4753
4753
|
migrationManifestHash: hashGovernedSuiteManifest(manifest),
|
|
4754
4754
|
suite,
|
|
@@ -4789,7 +4789,7 @@ function discoverLegacyLocalSuites(input = {}) {
|
|
|
4789
4789
|
return { suites, issues };
|
|
4790
4790
|
}
|
|
4791
4791
|
function migrationManifestHash(manifest) {
|
|
4792
|
-
let { policyRef: _policyRef, ...content } = manifest;
|
|
4792
|
+
let { policyRef: _policyRef, targetFingerprint: _targetFingerprint, requiredCapabilities: _requiredCapabilities, ...content } = manifest;
|
|
4793
4793
|
return hashGovernedSuiteManifest(content);
|
|
4794
4794
|
}
|
|
4795
4795
|
function planLegacyLocalSuiteMigration(local, cloud) {
|
|
@@ -4989,10 +4989,10 @@ function resultCount(output) {
|
|
|
4989
4989
|
return output.length;
|
|
4990
4990
|
if (!output || typeof output != "object")
|
|
4991
4991
|
return null;
|
|
4992
|
-
let
|
|
4992
|
+
let record7 = output;
|
|
4993
4993
|
for (let key of ["results", "documents", "items", "data", "matches"])
|
|
4994
|
-
if (Array.isArray(
|
|
4995
|
-
return
|
|
4994
|
+
if (Array.isArray(record7[key]))
|
|
4995
|
+
return record7[key].length;
|
|
4996
4996
|
return null;
|
|
4997
4997
|
}
|
|
4998
4998
|
function compactError(cause) {
|
|
@@ -5628,11 +5628,11 @@ async function gradeExecution(candidate, benchmarkCase, result, scorers, passThr
|
|
|
5628
5628
|
return { assertions, dimensions, score, verdict, securityBreach, criticalFailure, functionalSuccess, secureTaskSuccess };
|
|
5629
5629
|
}
|
|
5630
5630
|
async function withTimeout(promise, timeoutMs, signal) {
|
|
5631
|
-
return timeoutMs <= 0 && !signal ? promise : await new Promise((
|
|
5631
|
+
return timeoutMs <= 0 && !signal ? promise : await new Promise((resolve7, reject) => {
|
|
5632
5632
|
let settled = !1, finish = (fn) => {
|
|
5633
5633
|
settled || (settled = !0, clearTimeout(timer), signal && signal.removeEventListener("abort", onAbort), fn());
|
|
5634
5634
|
}, timer = timeoutMs > 0 ? setTimeout(() => finish(() => reject(new Error(`benchmark timeout after ${timeoutMs}ms`))), timeoutMs) : void 0, onAbort = () => finish(() => reject(new Error("benchmark cancelled")));
|
|
5635
|
-
signal && signal.addEventListener("abort", onAbort, { once: !0 }), promise.then((v) => finish(() =>
|
|
5635
|
+
signal && signal.addEventListener("abort", onAbort, { once: !0 }), promise.then((v) => finish(() => resolve7(v)), (e) => finish(() => reject(e)));
|
|
5636
5636
|
});
|
|
5637
5637
|
}
|
|
5638
5638
|
async function pool(items, limit, work) {
|
|
@@ -8663,9 +8663,9 @@ function readHuggingFaceCache(ir) {
|
|
|
8663
8663
|
recordedFiles
|
|
8664
8664
|
};
|
|
8665
8665
|
}
|
|
8666
|
-
function compareRecordedDigests(ir,
|
|
8666
|
+
function compareRecordedDigests(ir, record7) {
|
|
8667
8667
|
let onDisk = new Map(ir.files.map((f) => [f.path, f.sha256])), out = { matched: [], mismatched: [], unverifiable: [] };
|
|
8668
|
-
for (let entry of
|
|
8668
|
+
for (let entry of record7.digests) {
|
|
8669
8669
|
if (entry.algorithm !== "sha256") {
|
|
8670
8670
|
out.unverifiable.push(entry.path);
|
|
8671
8671
|
continue;
|
|
@@ -8683,25 +8683,25 @@ function compareRecordedDigests(ir, record6) {
|
|
|
8683
8683
|
// ../core/dist/modelSecurity/packs/provenance.js
|
|
8684
8684
|
var PACK2 = "model-provenance", IMMUTABLE_REVISION = /^[a-f0-9]{7,64}$/i, FLOATING_NAMES = /^(?:main|master|develop|dev|trunk|latest|head|refs\/heads\/.+|refs\/tags\/.+|v?\d+(?:\.\d+)*(?:-[a-z0-9.]+)?)$/i;
|
|
8685
8685
|
function readProvenance(ir) {
|
|
8686
|
-
let
|
|
8687
|
-
ir.target.sourceType === "huggingface" && (
|
|
8686
|
+
let record7 = { architectures: [], externalDependencies: [] };
|
|
8687
|
+
ir.target.sourceType === "huggingface" && (record7.sourceRepository = ir.target.source), ir.target.sourceType === "url" && (record7.artifactUrl = ir.target.source), (ir.target.sourceType === "url" || ir.target.sourceType === "huggingface") && (record7.downloadedFrom = ir.target.source), record7.revision = ir.target.resolvedRevision ?? ir.target.revision, record7.publisher = ir.target.publisher;
|
|
8688
8688
|
for (let file of ir.files) {
|
|
8689
|
-
(/^readme|model[_-]?card/i.test(file.path) || file.role === "documentation") && (
|
|
8689
|
+
(/^readme|model[_-]?card/i.test(file.path) || file.role === "documentation") && (record7.modelCardPath ??= file.path, file.text && (record7.license ??= file.text.match(/^(?:license|model-license)\s*:\s*["']?([^\n"']+)/im)?.[1]?.trim(), record7.sourceRepository ??= file.text.match(/^(?:base_model|base-model|source_model|repository)\s*:\s*["']?([^\n"']+)/im)?.[1]?.trim(), record7.commit ??= file.text.match(/^(?:revision|commit|sha)\s*:\s*["']?([a-f0-9]{7,64})/im)?.[1], record7.publisher ??= file.text.match(/^(?:author|publisher|organization)\s*:\s*["']?([^\n"']+)/im)?.[1]?.trim())), /^license(?:\.|$)|^copying(?:\.|$)/i.test(file.path) && file.text?.trim() && (record7.license ??= "License file present (identifier not parsed)");
|
|
8690
8690
|
for (let [key, value] of flatten(file.json))
|
|
8691
|
-
typeof value == "string" && (/(?:^|\.)model_type$/.test(key) && (
|
|
8691
|
+
typeof value == "string" && (/(?:^|\.)model_type$/.test(key) && (record7.modelType ??= value), /(?:^|\.)transformers_version$/.test(key) && (record7.libraryVersion ??= value), /(?:^|\.)license$/.test(key) && (record7.license ??= value), /(?:^|\.)_name_or_path$/.test(key) && (record7.sourceRepository ??= value), /(?:^|\.)(?:base_model_name_or_path|base_model)$/.test(key) && (record7.sourceRepository ??= value), /(?:^|\.)(?:_?commit_hash|revision|sha)$/.test(key) && (record7.commit ??= value), /(?:^|\.)(?:author|publisher|organization)$/.test(key) && (record7.publisher ??= value));
|
|
8692
8692
|
let architectures = flatten(file.json).filter(([key]) => /(?:^|\.)architectures\[\d+\]$/.test(key)).map(([, value]) => value);
|
|
8693
8693
|
for (let architecture of architectures)
|
|
8694
|
-
typeof architecture == "string" &&
|
|
8694
|
+
typeof architecture == "string" && record7.architectures.push(architecture);
|
|
8695
8695
|
if (/requirements\.txt$|pyproject\.toml$|setup\.py$|environment\.ya?ml$/i.test(file.path) && file.text)
|
|
8696
8696
|
for (let line of file.text.split(/\r?\n/)) {
|
|
8697
8697
|
let dependency = line.trim();
|
|
8698
8698
|
if (!dependency || dependency.startsWith("#"))
|
|
8699
8699
|
continue;
|
|
8700
8700
|
let name = dependency.match(/^([A-Za-z0-9._-]+)/)?.[1];
|
|
8701
|
-
name &&
|
|
8701
|
+
name && record7.externalDependencies.push(dependency.length > 80 ? name : dependency);
|
|
8702
8702
|
}
|
|
8703
8703
|
}
|
|
8704
|
-
return
|
|
8704
|
+
return record7.architectures = [...new Set(record7.architectures)], record7.externalDependencies = [...new Set(record7.externalDependencies)], record7.commit ??= record7.revision && IMMUTABLE_REVISION.test(record7.revision) ? record7.revision : void 0, record7;
|
|
8705
8705
|
}
|
|
8706
8706
|
function recordCheck(id, title, intent, read, missing) {
|
|
8707
8707
|
return {
|
|
@@ -8731,13 +8731,13 @@ function recordCheck(id, title, intent, read, missing) {
|
|
|
8731
8731
|
};
|
|
8732
8732
|
}
|
|
8733
8733
|
var PROVENANCE_RULES = [
|
|
8734
|
-
recordCheck("provenance.source-repository", "Source repository", "The artifact records the repository it was published from.", (
|
|
8734
|
+
recordCheck("provenance.source-repository", "Source repository", "The artifact records the repository it was published from.", (record7) => record7.sourceRepository, {
|
|
8735
8735
|
severity: "medium",
|
|
8736
8736
|
description: "Nothing in the artifact identifies the repository it came from.",
|
|
8737
8737
|
impact: "The artifact cannot be traced back to reviewed source, and a substitution would go unnoticed.",
|
|
8738
8738
|
remediation: "Record the publishing repository in the model card and configuration, and scan by Hugging Face repository or URL so the source is captured automatically."
|
|
8739
8739
|
}),
|
|
8740
|
-
recordCheck("provenance.artifact-url", "Artifact URL", "The location the artifact was retrieved from is recorded.", (
|
|
8740
|
+
recordCheck("provenance.artifact-url", "Artifact URL", "The location the artifact was retrieved from is recorded.", (record7) => record7.artifactUrl ?? record7.downloadedFrom, {
|
|
8741
8741
|
severity: "low",
|
|
8742
8742
|
description: "No retrieval URL was recorded for this artifact.",
|
|
8743
8743
|
impact: "Re-fetching the exact bytes later depends on undocumented tribal knowledge.",
|
|
@@ -8776,7 +8776,7 @@ var PROVENANCE_RULES = [
|
|
|
8776
8776
|
derivedFrom: "Git object naming and model-hub revision semantics",
|
|
8777
8777
|
verification: "source-metadata",
|
|
8778
8778
|
run(ctx) {
|
|
8779
|
-
let
|
|
8779
|
+
let record7 = readProvenance(ctx.ir), revision = record7.commit ?? record7.revision;
|
|
8780
8780
|
if (revision && IMMUTABLE_REVISION.test(revision)) {
|
|
8781
8781
|
ctx.clean(`Pinned to immutable revision ${revision.slice(0, 12)}\u2026`);
|
|
8782
8782
|
return;
|
|
@@ -8801,7 +8801,7 @@ var PROVENANCE_RULES = [
|
|
|
8801
8801
|
derivedFrom: "Git ref semantics; mutable tags and branches are not content-addressed",
|
|
8802
8802
|
verification: "source-metadata",
|
|
8803
8803
|
run(ctx) {
|
|
8804
|
-
let floating = [],
|
|
8804
|
+
let floating = [], record7 = readProvenance(ctx.ir), targetRevision = ctx.ir.target.revision;
|
|
8805
8805
|
ctx.ir.target.revisionIsFloating === !0 && targetRevision ? floating.push({ where: "scan target", value: targetRevision }) : targetRevision && !IMMUTABLE_REVISION.test(targetRevision) && floating.push({ where: "scan target", value: targetRevision });
|
|
8806
8806
|
for (let file of ctx.ir.files)
|
|
8807
8807
|
for (let [key, value] of flatten(file.json))
|
|
@@ -8820,26 +8820,26 @@ var PROVENANCE_RULES = [
|
|
|
8820
8820
|
});
|
|
8821
8821
|
if (floating.length)
|
|
8822
8822
|
return;
|
|
8823
|
-
if (!(!!targetRevision || !!
|
|
8823
|
+
if (!(!!targetRevision || !!record7.commit || !!record7.revision || ctx.ir.files.some((file) => [...flatten(file.json)].some(([key, value]) => typeof value == "string" && /(?:^|\.)(?:revision|base_model_revision|adapter_revision|ref|branch|tag)$/i.test(key))))) {
|
|
8824
8824
|
ctx.notApplicable("NOT MEASURED \u2014 the artifact declares no repository revision, branch or tag, and none was supplied to the scan. There is nothing to judge as floating or immutable; this is absent provenance, not a verified property.");
|
|
8825
8825
|
return;
|
|
8826
8826
|
}
|
|
8827
8827
|
ctx.clean("Every revision reference in the artifact was an immutable identifier.");
|
|
8828
8828
|
}
|
|
8829
8829
|
},
|
|
8830
|
-
recordCheck("provenance.commit-captured", "Repository commit", "The upstream repository commit is captured with the artifact.", (
|
|
8830
|
+
recordCheck("provenance.commit-captured", "Repository commit", "The upstream repository commit is captured with the artifact.", (record7) => record7.commit, {
|
|
8831
8831
|
severity: "medium",
|
|
8832
8832
|
description: "No repository commit was recorded alongside the artifact.",
|
|
8833
8833
|
impact: "The artifact cannot be reproducibly rebuilt from, or diffed against, reviewed source.",
|
|
8834
8834
|
remediation: "Emit the build commit into the model card and configuration as part of the publishing pipeline."
|
|
8835
8835
|
}),
|
|
8836
|
-
recordCheck("provenance.license-declared", "Model license", "A model license is declared.", (
|
|
8836
|
+
recordCheck("provenance.license-declared", "Model license", "A model license is declared.", (record7) => record7.license, {
|
|
8837
8837
|
severity: "medium",
|
|
8838
8838
|
description: "No model license was discovered in configuration, model card or a license file.",
|
|
8839
8839
|
impact: "Use, redistribution, fine-tuning and commercial deployment rights are undetermined.",
|
|
8840
8840
|
remediation: "Attach an SPDX-identifiable model license and have counsel review its obligations before deployment."
|
|
8841
8841
|
}),
|
|
8842
|
-
recordCheck("provenance.publisher-metadata", "Publisher metadata", "An author or publishing organization is recorded.", (
|
|
8842
|
+
recordCheck("provenance.publisher-metadata", "Publisher metadata", "An author or publishing organization is recorded.", (record7) => record7.publisher, {
|
|
8843
8843
|
severity: "low",
|
|
8844
8844
|
description: "No author or publishing organization was recorded for the artifact.",
|
|
8845
8845
|
impact: "There is no accountable owner recorded for security questions or advisories.",
|
|
@@ -8884,7 +8884,7 @@ var PROVENANCE_RULES = [
|
|
|
8884
8884
|
derivedFrom: "Python packaging manifest formats",
|
|
8885
8885
|
verification: "static-text-inspection",
|
|
8886
8886
|
run(ctx) {
|
|
8887
|
-
let
|
|
8887
|
+
let record7 = readProvenance(ctx.ir), manifests = ctx.ir.files.filter((file) => /requirements\.txt$|pyproject\.toml$|setup\.py$|environment\.ya?ml$/i.test(file.path));
|
|
8888
8888
|
if (!manifests.length) {
|
|
8889
8889
|
ctx.report({
|
|
8890
8890
|
title: "No dependency manifest accompanies the model",
|
|
@@ -8897,7 +8897,7 @@ var PROVENANCE_RULES = [
|
|
|
8897
8897
|
});
|
|
8898
8898
|
return;
|
|
8899
8899
|
}
|
|
8900
|
-
ctx.clean(`${
|
|
8900
|
+
ctx.clean(`${record7.externalDependencies.length} declared dependenc${record7.externalDependencies.length === 1 ? "y" : "ies"} across ${manifests.length} manifest(s).`);
|
|
8901
8901
|
}
|
|
8902
8902
|
},
|
|
8903
8903
|
{
|
|
@@ -8972,7 +8972,7 @@ var PROVENANCE_RULES = [
|
|
|
8972
8972
|
});
|
|
8973
8973
|
}
|
|
8974
8974
|
},
|
|
8975
|
-
recordCheck("provenance.model-card-source", "Model card", "A model card documents origin, intended use and limitations.", (
|
|
8975
|
+
recordCheck("provenance.model-card-source", "Model card", "A model card documents origin, intended use and limitations.", (record7) => record7.modelCardPath, {
|
|
8976
8976
|
severity: "medium",
|
|
8977
8977
|
description: "The artifact has no discoverable README or model card.",
|
|
8978
8978
|
impact: "Reviewers cannot establish intended use, training data, limitations or safety evaluation from the artifact itself.",
|
|
@@ -10909,11 +10909,11 @@ function sanitizeAssertions(raw) {
|
|
|
10909
10909
|
for (let item of raw) {
|
|
10910
10910
|
if (!item || typeof item != "object")
|
|
10911
10911
|
continue;
|
|
10912
|
-
let
|
|
10912
|
+
let record7 = item, op = record7.op;
|
|
10913
10913
|
if (typeof op != "string" || !ASSERT_OPS.has(op))
|
|
10914
10914
|
continue;
|
|
10915
|
-
let path = typeof
|
|
10916
|
-
if (!(needsValue &&
|
|
10915
|
+
let path = typeof record7.path == "string" ? record7.path : "", needsValue = op !== "exists" && op !== "not-exists";
|
|
10916
|
+
if (!(needsValue && record7.value === void 0) && (out.push({ path, op, ...needsValue ? { value: record7.value } : {} }), out.length >= 10))
|
|
10917
10917
|
break;
|
|
10918
10918
|
}
|
|
10919
10919
|
return out;
|
|
@@ -10940,22 +10940,22 @@ function parseGeneratedPromptCases(text6, ctx = {}) {
|
|
|
10940
10940
|
for (let raw of parsed) {
|
|
10941
10941
|
if (!raw || typeof raw != "object")
|
|
10942
10942
|
continue;
|
|
10943
|
-
let
|
|
10943
|
+
let record7 = raw, prompt = typeof record7.prompt == "string" ? record7.prompt.trim() : "";
|
|
10944
10944
|
if (!prompt || !isPromptLike(prompt))
|
|
10945
10945
|
continue;
|
|
10946
|
-
let type = typeof
|
|
10946
|
+
let type = typeof record7.type == "string" && CASE_TYPES.has(record7.type) ? record7.type : "positive", expectedTool = typeof record7.expectedTool == "string" ? record7.expectedTool.trim() : "", forbiddenTools = textList(record7.forbiddenTools).filter((t) => known ? known.has(t) : !0);
|
|
10947
10947
|
if (cases.push({
|
|
10948
10948
|
id: `${prefix}-${cases.length + 1}`,
|
|
10949
|
-
name: (typeof
|
|
10949
|
+
name: (typeof record7.name == "string" && record7.name.trim() ? record7.name.trim() : `${type} case`).slice(0, 120),
|
|
10950
10950
|
source: { kind: "ai-generated", serverId: ctx.serverId, toolName: ctx.toolName },
|
|
10951
10951
|
type,
|
|
10952
10952
|
prompt: prompt.slice(0, 8e3),
|
|
10953
|
-
expectedBehavior: typeof
|
|
10953
|
+
expectedBehavior: typeof record7.expectedBehavior == "string" && record7.expectedBehavior.trim() ? record7.expectedBehavior.trim().slice(0, 500) : void 0,
|
|
10954
10954
|
// Never let the generator invent a tool the connected server doesn't advertise.
|
|
10955
10955
|
expectedTool: expectedTool && (!known || known.has(expectedTool)) ? expectedTool : void 0,
|
|
10956
10956
|
forbiddenTools: forbiddenTools.length ? forbiddenTools : void 0,
|
|
10957
|
-
assertions: sanitizeAssertions(
|
|
10958
|
-
tags: textList(
|
|
10957
|
+
assertions: sanitizeAssertions(record7.assertions),
|
|
10958
|
+
tags: textList(record7.tags, 6)
|
|
10959
10959
|
}), cases.length >= max)
|
|
10960
10960
|
break;
|
|
10961
10961
|
}
|
|
@@ -11167,6 +11167,122 @@ async function relaySammyInferenceBoundary(options) {
|
|
|
11167
11167
|
}
|
|
11168
11168
|
}
|
|
11169
11169
|
|
|
11170
|
+
// ../server/dist/hostedSammySuiteHandoff.js
|
|
11171
|
+
import { createHash as createHash15, randomUUID as randomUUID7 } from "node:crypto";
|
|
11172
|
+
import { existsSync as existsSync2, linkSync, mkdirSync as mkdirSync2, readFileSync as readFileSync3, unlinkSync, writeFileSync } from "node:fs";
|
|
11173
|
+
import { join as join4, resolve as resolve5 } from "node:path";
|
|
11174
|
+
var GENERATION_ID = /^sammy-[a-f0-9]{12}$/, STATIC_FINGERPRINT = /^static-suite-fp-[a-f0-9]{12}$/, PROFILE_TARGET_FINGERPRINT = /^target-fp-[a-f0-9]{12}$/, GOVERNED_TARGET_FINGERPRINT = /^target-fp-[a-f0-9]{32}$/, CAPABILITY_FINGERPRINT = /^cap-fp-[a-f0-9]{32}$/, LINEAGE_KEYS = /* @__PURE__ */ new Set([
|
|
11175
|
+
"generationId",
|
|
11176
|
+
"generationStrategy",
|
|
11177
|
+
"registryVersion",
|
|
11178
|
+
"generatorModelAlias",
|
|
11179
|
+
"reviewerModelAlias",
|
|
11180
|
+
"graphVersion",
|
|
11181
|
+
"promptBundleVersion",
|
|
11182
|
+
"datasetVersionRefs",
|
|
11183
|
+
"generatorModelRef",
|
|
11184
|
+
"reviewerModelRef"
|
|
11185
|
+
]);
|
|
11186
|
+
function record6(value) {
|
|
11187
|
+
return !!value && typeof value == "object" && !Array.isArray(value);
|
|
11188
|
+
}
|
|
11189
|
+
function validateArtifact(value, generationId) {
|
|
11190
|
+
if (!record6(value) || !Object.keys(value).every((key) => ["format", "suite", "lineage", "fingerprint"].includes(key)))
|
|
11191
|
+
throw new Error("Hosted Sammy returned an invalid static Suite artifact envelope.");
|
|
11192
|
+
if (value.format !== "prooflane-static-assurance-suite-v1" || typeof value.fingerprint != "string" || !STATIC_FINGERPRINT.test(value.fingerprint))
|
|
11193
|
+
throw new Error("Hosted Sammy returned an unsupported static Suite artifact.");
|
|
11194
|
+
if (!record6(value.lineage) || !Object.keys(value.lineage).every((key) => LINEAGE_KEYS.has(key)) || value.lineage.generationId !== generationId)
|
|
11195
|
+
throw new Error("Hosted Sammy artifact lineage does not match the approved generation.");
|
|
11196
|
+
let suite = validateLegacyLocalSuite(value.suite);
|
|
11197
|
+
if (suite.status !== "APPROVED" || !suite.approvedAt)
|
|
11198
|
+
throw new Error("Only an approved Sammy Suite can enter governed authoring.");
|
|
11199
|
+
let expectedFingerprint = `static-suite-fp-${createHash15("sha256").update(canonicalizeSuiteJson({ suiteFingerprint: suite.suiteFingerprint, lineage: value.lineage }), "utf8").digest("hex").slice(0, 12)}`;
|
|
11200
|
+
if (value.fingerprint !== expectedFingerprint)
|
|
11201
|
+
throw new Error("Hosted Sammy static Suite artifact fingerprint verification failed.");
|
|
11202
|
+
return { format: value.format, suite, lineage: value.lineage, fingerprint: value.fingerprint };
|
|
11203
|
+
}
|
|
11204
|
+
function validateCapabilities(value) {
|
|
11205
|
+
if (value.length > 1e3)
|
|
11206
|
+
throw new Error("The governed capability surface is too large.");
|
|
11207
|
+
let ids = /* @__PURE__ */ new Set();
|
|
11208
|
+
return value.map((entry) => {
|
|
11209
|
+
if (!entry || typeof entry.id != "string" || entry.id.length < 1 || entry.id.length > 128 || !/^[A-Za-z0-9][A-Za-z0-9_.:/-]{0,127}$/.test(entry.id) || typeof entry.fingerprint != "string" || !CAPABILITY_FINGERPRINT.test(entry.fingerprint) || ids.has(entry.id))
|
|
11210
|
+
throw new Error("The governed capability surface is invalid.");
|
|
11211
|
+
return ids.add(entry.id), { id: entry.id, fingerprint: entry.fingerprint };
|
|
11212
|
+
}).sort((left, right) => left.id.localeCompare(right.id));
|
|
11213
|
+
}
|
|
11214
|
+
function approvedTestContentFingerprint(tests) {
|
|
11215
|
+
let content = tests.map((test) => {
|
|
11216
|
+
let { createdAt: _createdAt, ...rest } = test, intelligence = test.intelligence ? (({ generationId: _generationId, suiteId: _suiteId, suiteVersion: _suiteVersion, reviewStatus: _reviewStatus, reviewedAt: _reviewedAt, reviewedBy: _reviewedBy, ...authored }) => authored)(test.intelligence) : void 0, rag = test.rag ? {
|
|
11217
|
+
...test.rag,
|
|
11218
|
+
intelligence: test.rag.intelligence ? (({ generationId: _generationId, suiteId: _suiteId, suiteVersion: _suiteVersion, nativeTestRef: _nativeTestRef, ...trusted }) => trusted)(test.rag.intelligence) : null
|
|
11219
|
+
} : null;
|
|
11220
|
+
return { ...rest, tags: [...test.tags].sort(), intelligence: intelligence ?? null, rag };
|
|
11221
|
+
}).sort((left, right) => left.id.localeCompare(right.id));
|
|
11222
|
+
return `suite-fp-${createHash15("sha256").update(canonicalizeSuiteJson({ format: "prooflane-assurance-suite-v1", content }), "utf8").digest("hex").slice(0, 12)}`;
|
|
11223
|
+
}
|
|
11224
|
+
function runtimeSuiteId(sourceId, generationId) {
|
|
11225
|
+
let sourceSlug = localSuiteSlug(sourceId), suffix = generationId.slice(6);
|
|
11226
|
+
return `${sourceSlug.slice(0, 48)}-${suffix}`;
|
|
11227
|
+
}
|
|
11228
|
+
function localFingerprint(suite) {
|
|
11229
|
+
return `sha256:${createHash15("sha256").update(canonicalizeSuiteJson(suite), "utf8").digest("hex")}`;
|
|
11230
|
+
}
|
|
11231
|
+
function materializeHostedSammySuite(input) {
|
|
11232
|
+
if (!GENERATION_ID.test(input.generationId))
|
|
11233
|
+
throw new Error("Hosted Sammy generation id is invalid.");
|
|
11234
|
+
if (!input.expectedTarget.trim() || input.expectedTarget.length > 256 || !PROFILE_TARGET_FINGERPRINT.test(input.expectedProfileTargetFingerprint) || !GOVERNED_TARGET_FINGERPRINT.test(input.governedTargetFingerprint))
|
|
11235
|
+
throw new Error("The current hosted capability surface is invalid.");
|
|
11236
|
+
let artifact = validateArtifact(input.artifact, input.generationId);
|
|
11237
|
+
if (artifact.suite.suiteFingerprint !== approvedTestContentFingerprint(artifact.suite.tests))
|
|
11238
|
+
throw new Error("Hosted Sammy approved Suite content fingerprint verification failed.");
|
|
11239
|
+
if (artifact.suite.target !== input.expectedTarget || artifact.suite.targetFingerprint !== input.expectedProfileTargetFingerprint)
|
|
11240
|
+
throw new Error("The connected MCP target changed after Sammy approval. Generate and approve a fresh plan.");
|
|
11241
|
+
let requiredCapabilities = validateCapabilities(input.requiredCapabilities), id = runtimeSuiteId(artifact.suite.id, input.generationId), suite = validateLegacyLocalSuite({
|
|
11242
|
+
...artifact.suite,
|
|
11243
|
+
id,
|
|
11244
|
+
targetFingerprint: input.governedTargetFingerprint
|
|
11245
|
+
}), expectedLocalFingerprint = localFingerprint(suite), slug = localSuiteSlug(suite.id), directory = resolve5(input.cwd ?? process.cwd(), ".prooflane", "suites"), fileName = `${slug}-v${suite.version}.json`, file = join4(directory, fileName), bytes = `${JSON.stringify(suite, null, 2)}
|
|
11246
|
+
`, created = !1;
|
|
11247
|
+
if (mkdirSync2(directory, { recursive: !0, mode: 448 }), existsSync2(file)) {
|
|
11248
|
+
if (readLegacyLocalSuiteArtifact(file, input.cwd ?? process.cwd()).localFingerprint !== expectedLocalFingerprint)
|
|
11249
|
+
throw new Error(`A different local Suite already occupies ${fileName}; Prooflane will not overwrite it.`);
|
|
11250
|
+
} else {
|
|
11251
|
+
let temporary = join4(directory, `.${fileName}.${process.pid}.${randomUUID7()}.tmp`);
|
|
11252
|
+
try {
|
|
11253
|
+
writeFileSync(temporary, bytes, { encoding: "utf8", flag: "wx", mode: 384 });
|
|
11254
|
+
try {
|
|
11255
|
+
linkSync(temporary, file), created = !0;
|
|
11256
|
+
} catch (error) {
|
|
11257
|
+
if (!existsSync2(file))
|
|
11258
|
+
throw error;
|
|
11259
|
+
if (readLegacyLocalSuiteArtifact(file, input.cwd ?? process.cwd()).localFingerprint !== expectedLocalFingerprint)
|
|
11260
|
+
throw new Error(`A different local Suite already occupies ${fileName}; Prooflane will not overwrite it.`);
|
|
11261
|
+
}
|
|
11262
|
+
} finally {
|
|
11263
|
+
existsSync2(temporary) && unlinkSync(temporary);
|
|
11264
|
+
}
|
|
11265
|
+
}
|
|
11266
|
+
let stored = readLegacyLocalSuiteArtifact(file, input.cwd ?? process.cwd());
|
|
11267
|
+
if (stored.localFingerprint !== expectedLocalFingerprint || stored.slug !== slug || stored.suite.status !== "APPROVED")
|
|
11268
|
+
throw new Error("The materialized Sammy Suite failed local integrity verification.");
|
|
11269
|
+
if (readFileSync3(file).byteLength > 8 * 1024 * 1024)
|
|
11270
|
+
throw new Error("The materialized Sammy Suite exceeds the local artifact limit.");
|
|
11271
|
+
return {
|
|
11272
|
+
version: "prooflane-hosted-sammy-materialization-v1",
|
|
11273
|
+
generationId: input.generationId,
|
|
11274
|
+
sourceArtifactFingerprint: artifact.fingerprint,
|
|
11275
|
+
sourceTargetFingerprint: artifact.suite.targetFingerprint,
|
|
11276
|
+
governedTargetFingerprint: input.governedTargetFingerprint,
|
|
11277
|
+
requiredCapabilities,
|
|
11278
|
+
slug,
|
|
11279
|
+
localFingerprint: stored.localFingerprint,
|
|
11280
|
+
localVersion: stored.suite.version,
|
|
11281
|
+
fileName,
|
|
11282
|
+
created
|
|
11283
|
+
};
|
|
11284
|
+
}
|
|
11285
|
+
|
|
11170
11286
|
// ../server/dist/plans.js
|
|
11171
11287
|
var UNLIMITED = 1e6, PLANS = {
|
|
11172
11288
|
free: { tier: "free", label: "Free \xB7 Inspector", servers: 1, tools: 5, attacks: 0, retrievers: 0, prompts: 10, maxVus: 10, deployment: !1, historyDays: 7, ci: !1, ruleFeed: "static", core: !0, hosted: !1, security: !1, rag: !1, gates: !1 },
|
|
@@ -11218,7 +11334,7 @@ function describeToolError(output) {
|
|
|
11218
11334
|
})();
|
|
11219
11335
|
return text6.length > 500 ? `${text6.slice(0, 500)}\u2026` : text6 || "the tool reported an error";
|
|
11220
11336
|
}
|
|
11221
|
-
var sha256 = (value) =>
|
|
11337
|
+
var sha256 = (value) => createHash16("sha256").update(typeof value == "string" ? value : JSON.stringify(value)).digest("hex"), hostedRagCaseQuery = (testCase) => (testCase.userQuery ?? "").trim() || testCase.query, hostedRagCaseName = (testCase) => (testCase.name ?? "").trim() || hostedRagCaseQuery(testCase) || testCase.id, hostedRagCaseInput = (testCase) => testCase.input ?? { query: hostedRagCaseQuery(testCase) }, clampRagScore = (value) => Math.max(0, Math.min(100, Math.round(Number.isFinite(value) ? value : 0))), averageRagScore = (values) => values.length ? Math.round(values.reduce((sum, value) => sum + value, 0) / values.length) : 100;
|
|
11222
11338
|
function extractHostedRagPayload(output) {
|
|
11223
11339
|
let value = output;
|
|
11224
11340
|
if (Array.isArray(value) && value.length && value.every((block) => block && typeof block == "object" && "type" in block)) {
|
|
@@ -11492,10 +11608,10 @@ function resultCount3(value) {
|
|
|
11492
11608
|
if (Array.isArray(value))
|
|
11493
11609
|
return value.length;
|
|
11494
11610
|
if (value && typeof value == "object") {
|
|
11495
|
-
let
|
|
11611
|
+
let record7 = value;
|
|
11496
11612
|
for (let key of ["results", "items", "documents", "matches", "content"])
|
|
11497
|
-
if (Array.isArray(
|
|
11498
|
-
return
|
|
11613
|
+
if (Array.isArray(record7[key]))
|
|
11614
|
+
return record7[key].length;
|
|
11499
11615
|
return 1;
|
|
11500
11616
|
}
|
|
11501
11617
|
return value == null || value === "" ? 0 : 1;
|
|
@@ -11651,10 +11767,10 @@ function buildApp() {
|
|
|
11651
11767
|
targetTokenCeiling: Math.trunc(configuredNumber("PROOFLANE_BENCHMARK_PAID_TARGET_TOKENS", DEFAULT_BENCHMARK_PRICING_POLICY.products.PAID_SINGLE_RUN.targetTokenCeiling, 1e3, 2e7))
|
|
11652
11768
|
}
|
|
11653
11769
|
}
|
|
11654
|
-
}, localLifecycleKey =
|
|
11770
|
+
}, localLifecycleKey = randomUUID8(), activeMcpAuthMode = "unknown", activeMcpConnectionId = null, oauthFlows = /* @__PURE__ */ new Map(), assuranceGateManifest = process.env.PROOFLANE_ASSURANCE_GATES_FILE ?? resolve6(".prooflane/assurance-gates.json"), assurancePolicyRegistry = process.env.PROOFLANE_ASSURANCE_POLICIES_FILE ?? join5(dirname4(assuranceGateManifest), "assurance-policies.json"), readAssurancePolicies = async () => {
|
|
11655
11771
|
let intel = await loadLegacyIntelligence(), stored = [];
|
|
11656
|
-
if (
|
|
11657
|
-
let document = JSON.parse(
|
|
11772
|
+
if (existsSync3(assurancePolicyRegistry)) {
|
|
11773
|
+
let document = JSON.parse(readFileSync4(assurancePolicyRegistry, "utf8"));
|
|
11658
11774
|
if (document.version !== "prooflane-assurance-policy-registry-v1" || !Array.isArray(document.policies))
|
|
11659
11775
|
throw new Error("Assurance Policy registry must use prooflane-assurance-policy-registry-v1.");
|
|
11660
11776
|
stored = document.policies;
|
|
@@ -11662,7 +11778,7 @@ function buildApp() {
|
|
|
11662
11778
|
let policies = stored.map((policy) => intel.validateAssurancePolicyVersion(policy));
|
|
11663
11779
|
return policies.some((policy) => policy.id === intel.DEFAULT_ASSURANCE_POLICY.id) || policies.unshift(structuredClone(intel.DEFAULT_ASSURANCE_POLICY)), policies.sort((a, b) => b.createdAt.localeCompare(a.createdAt) || b.version - a.version || a.id.localeCompare(b.id));
|
|
11664
11780
|
}, writeAssurancePolicies = (policies) => {
|
|
11665
|
-
|
|
11781
|
+
mkdirSync3(dirname4(assurancePolicyRegistry), { recursive: !0 }), writeFileSync2(assurancePolicyRegistry, JSON.stringify({ version: "prooflane-assurance-policy-registry-v1", policies }, null, 2) + `
|
|
11666
11782
|
`, "utf8");
|
|
11667
11783
|
}, hostedSammyInference = async (request, task, context) => {
|
|
11668
11784
|
let authorization = request[HOSTED_SAMMY_AUTHORIZATION], relayRequest = buildHostedSammyRelayRequest({
|
|
@@ -12065,6 +12181,36 @@ ${item.artifact.localFingerprint}`));
|
|
|
12065
12181
|
let status = error instanceof ControlPlaneRequestError ? error.status : 400;
|
|
12066
12182
|
return reply.code(status).send({ error: (error instanceof Error ? error.message : "Local Suite migration failed.").slice(0, 300) });
|
|
12067
12183
|
}
|
|
12184
|
+
}), app.post("/api/intelligence/generations/:id/materialize-suite", async (req, reply) => {
|
|
12185
|
+
if (intelligenceMode !== "hosted")
|
|
12186
|
+
return reply.code(409).send({ error: "Hosted Sammy Suite materialization is available only in hosted Intelligence mode." });
|
|
12187
|
+
if (!req.body || typeof req.body != "object" || Array.isArray(req.body) || Object.keys(req.body).length !== 0)
|
|
12188
|
+
return reply.code(400).send({ error: "Hosted Sammy Suite materialization accepts an empty body only." });
|
|
12189
|
+
if (!/^sammy-[a-f0-9]{12}$/.test(req.params.id))
|
|
12190
|
+
return reply.code(400).send({ error: "Hosted Sammy generation id is invalid." });
|
|
12191
|
+
let capabilities = svc.getCapabilities();
|
|
12192
|
+
if (!capabilities)
|
|
12193
|
+
return reply.code(409).send({ error: "Connect the same MCP target before preparing the governed Suite." });
|
|
12194
|
+
try {
|
|
12195
|
+
let surface = await requestControlPlaneJson(req, "/v1/intelligence/surface", "POST", { capabilities }), governedTargetFingerprint = fingerprintServerCapabilities(capabilities), governedCapabilities = fingerprintServerCapabilitySurface(capabilities);
|
|
12196
|
+
if (surface.connected !== !0 || typeof surface.target != "string" || typeof surface.fingerprint != "string" || surface.governedTargetFingerprint !== governedTargetFingerprint || JSON.stringify(surface.governedCapabilities) !== JSON.stringify(governedCapabilities))
|
|
12197
|
+
throw new Error("Hosted capability analysis did not preserve the current governed target identity.");
|
|
12198
|
+
let compiled = await requestControlPlaneJson(req, `/v1/projects/${encodeURIComponent(PROOFLANE_PROJECT)}/intelligence/generations/${encodeURIComponent(req.params.id)}/compile-suite`, "POST", {});
|
|
12199
|
+
if (!compiled.artifact)
|
|
12200
|
+
throw new Error("Hosted Sammy did not return an approved static Suite artifact.");
|
|
12201
|
+
return { materialized: materializeHostedSammySuite({
|
|
12202
|
+
artifact: compiled.artifact,
|
|
12203
|
+
generationId: req.params.id,
|
|
12204
|
+
expectedTarget: surface.target,
|
|
12205
|
+
expectedProfileTargetFingerprint: surface.fingerprint,
|
|
12206
|
+
governedTargetFingerprint,
|
|
12207
|
+
requiredCapabilities: governedCapabilities,
|
|
12208
|
+
cwd: process.cwd()
|
|
12209
|
+
}) };
|
|
12210
|
+
} catch (error) {
|
|
12211
|
+
let status = error instanceof ControlPlaneRequestError ? error.status : 409;
|
|
12212
|
+
return reply.code(status).send({ error: (error instanceof Error ? error.message : "The hosted Sammy Suite could not be prepared.").slice(0, 300) });
|
|
12213
|
+
}
|
|
12068
12214
|
});
|
|
12069
12215
|
let gateRegistryPath = `/v1/projects/${encodeURIComponent(PROOFLANE_PROJECT)}/gates`;
|
|
12070
12216
|
app.get("/api/governance/gates", async (req, reply) => proxyControlPlane(req, reply, gateRegistryPath, void 0, "GET")), app.post("/api/governance/gates", async (req, reply) => proxyControlPlane(req, reply, gateRegistryPath, req.body ?? {})), app.get("/api/governance/gates/:slug", async (req, reply) => proxyControlPlane(req, reply, `${gateRegistryPath}/${encodeURIComponent(req.params.slug)}`, void 0, "GET")), app.post("/api/governance/gates/:slug/versions", async (req, reply) => proxyControlPlane(req, reply, `${gateRegistryPath}/${encodeURIComponent(req.params.slug)}/versions`, req.body ?? {})), app.get("/api/governance/gates/:slug/versions/:version", async (req, reply) => proxyControlPlane(req, reply, `${gateRegistryPath}/${encodeURIComponent(req.params.slug)}/versions/${encodeURIComponent(req.params.version)}`, void 0, "GET")), app.put("/api/governance/gates/:slug/versions/:version", async (req, reply) => proxyControlPlane(req, reply, `${gateRegistryPath}/${encodeURIComponent(req.params.slug)}/versions/${encodeURIComponent(req.params.version)}`, req.body ?? {}, "PUT"));
|
|
@@ -12129,8 +12275,8 @@ ${item.artifact.localFingerprint}`));
|
|
|
12129
12275
|
throw new Error("Gate required pillars are not represented by the signed Suite.");
|
|
12130
12276
|
if (!svc.isConnected())
|
|
12131
12277
|
throw new Error("Connect the local MCP target before running this Gate.");
|
|
12132
|
-
let runnerId = `local_ui_${
|
|
12133
|
-
${PROOFLANE_PROJECT}`, "utf8").digest("hex").slice(0, 24)}`, idempotencyKey = `localui:${
|
|
12278
|
+
let runnerId = `local_ui_${createHash16("sha256").update(`${kawachHome()}
|
|
12279
|
+
${PROOFLANE_PROJECT}`, "utf8").digest("hex").slice(0, 24)}`, idempotencyKey = `localui:${randomUUID8().replaceAll("-", "")}`, gatePin = { gateId: gate.id, slug: gate.slug, gateVersionId: gateVersion.id, version: gateVersion.version, manifestHash: gateVersion.manifestHash }, suitePin = { suiteId: suite.id, slug: suite.slug, suiteVersionId: suiteVersion.id, version: suiteVersion.version, manifestHash: suiteVersion.manifestHash }, policyPin = { policyId: policy.id, policyVersionId: policyVersion.id, version: policyVersion.version, manifestHash: policyVersion.manifestHash }, runner = { runnerId, type: "LOCAL_UI", runnerVersion: "0.1.0", cliVersion: "ui-0.1.0" }, governedRunMatches = (candidate, targetFingerprint) => {
|
|
12134
12280
|
if (!object(candidate) || !object(candidate.gate) || !object(candidate.suite) || !object(candidate.policy) || !object(candidate.runner))
|
|
12135
12281
|
return !1;
|
|
12136
12282
|
let value = candidate;
|
|
@@ -12672,13 +12818,13 @@ ${existing.length ? existing.join(`
|
|
|
12672
12818
|
}
|
|
12673
12819
|
}), app.get("/api/benchmark/history", async (req) => {
|
|
12674
12820
|
let limit = Math.max(1, Math.min(100, Number(req.query.limit) || 25));
|
|
12675
|
-
return { runs: store.listBenchmarkRuns(benchmarkWorkspaceId(), limit).map((
|
|
12821
|
+
return { runs: store.listBenchmarkRuns(benchmarkWorkspaceId(), limit).map((record7) => ({ runId: record7.runId, status: record7.status, planId: record7.plan.planId, planVersion: record7.plan.version, objective: record7.plan.objective, mode: record7.plan.mode, targetType: record7.plan.targetType, summary: record7.summary, createdAt: record7.createdAt, updatedAt: record7.updatedAt })) };
|
|
12676
12822
|
}), app.get("/api/benchmark/runs/:id", async (req, reply) => {
|
|
12677
|
-
let
|
|
12678
|
-
return !
|
|
12823
|
+
let record7 = store.getBenchmarkRun(req.params.id);
|
|
12824
|
+
return !record7 || record7.workspaceId !== benchmarkWorkspaceId() ? reply.code(404).send({ error: "Benchmark Run not found." }) : { run: record7 };
|
|
12679
12825
|
}), app.get("/api/benchmark/runs/:id/report.html", async (req, reply) => {
|
|
12680
|
-
let
|
|
12681
|
-
return !
|
|
12826
|
+
let record7 = store.getBenchmarkRun(req.params.id);
|
|
12827
|
+
return !record7 || record7.workspaceId !== benchmarkWorkspaceId() || !record7.reportHtml ? reply.code(404).send({ error: "Benchmark HTML report not found." }) : (reply.header("Content-Disposition", `attachment; filename="benchmark-report-${record7.runId}.html"`), reply.type("text/html; charset=utf-8"), record7.reportHtml);
|
|
12682
12828
|
}), app.post("/api/intelligence/execute", async (req, reply) => {
|
|
12683
12829
|
if (!req.body?.lease)
|
|
12684
12830
|
return reply.code(400).send({ ok: !1, error: "A hosted Intelligence lease is required." });
|
|
@@ -12947,8 +13093,8 @@ ${answer}`
|
|
|
12947
13093
|
severity: scanSeverity ?? (evidence.outcome === "fail" ? "high" : void 0)
|
|
12948
13094
|
} : void 0) ?? evidence, privacy: { rawDataSent: !1, next: "Submit this envelope with the original lease to the hosted Control Plane." } };
|
|
12949
13095
|
});
|
|
12950
|
-
let tagsFile = () =>
|
|
12951
|
-
|
|
13096
|
+
let tagsFile = () => join5(process.cwd(), DEFAULT_TAGS_FILE), readTagsConfig = (file) => parseTagsConfig(existsSync3(file) ? readFileSync4(file, "utf8") : ""), writeTagsConfig = (file, config) => {
|
|
13097
|
+
mkdirSync3(dirname4(file), { recursive: !0 }), writeFileSync2(file, serializeTagsConfig(config));
|
|
12952
13098
|
};
|
|
12953
13099
|
app.get("/api/tags", async () => ({ ok: !0, path: DEFAULT_TAGS_FILE, config: readTagsConfig(tagsFile()) })), app.post("/api/tags", async (req, reply) => {
|
|
12954
13100
|
let plan = await resolvePlan(req);
|
|
@@ -12966,21 +13112,21 @@ ${answer}`
|
|
|
12966
13112
|
let file = tagsFile(), next = removeTest(readTagsConfig(file), req.params.id);
|
|
12967
13113
|
return writeTagsConfig(file, next), { ok: !0, path: DEFAULT_TAGS_FILE, config: next };
|
|
12968
13114
|
});
|
|
12969
|
-
let gatesPath = () =>
|
|
13115
|
+
let gatesPath = () => join5(process.cwd(), ".prooflane/gates.json"), validLegacyRegressionGroup = (value) => {
|
|
12970
13116
|
if (!value || typeof value != "object" || Array.isArray(value))
|
|
12971
13117
|
return !1;
|
|
12972
13118
|
let gate = value;
|
|
12973
13119
|
return typeof gate.id == "string" && /^[a-z0-9][a-z0-9_-]{1,63}$/.test(gate.id) && typeof gate.name == "string" && gate.name.trim().length >= 2 && gate.name.length <= 80 && Array.isArray(gate.tags) && gate.tags.length > 0 && gate.tags.length <= 50 && gate.tags.every((tag2) => typeof tag2 == "string" && /^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,63}$/.test(tag2)) && typeof gate.minScore == "number" && Number.isFinite(gate.minScore) && gate.minScore >= 0 && gate.minScore <= 100 && typeof gate.repeat == "number" && Number.isInteger(gate.repeat) && gate.repeat >= 1 && gate.repeat <= 10 && typeof gate.deterministicOnly == "boolean" && typeof gate.createdAt == "string" && Number.isFinite(Date.parse(gate.createdAt)) && typeof gate.updatedAt == "string" && Number.isFinite(Date.parse(gate.updatedAt));
|
|
12974
13120
|
}, readLegacyRegressionGroups = () => {
|
|
12975
13121
|
try {
|
|
12976
|
-
let parsed = JSON.parse(
|
|
13122
|
+
let parsed = JSON.parse(readFileSync4(gatesPath(), "utf8"));
|
|
12977
13123
|
return parsed.version === "prooflane-gates-v1" && Array.isArray(parsed.gates) ? parsed.gates.filter(validLegacyRegressionGroup) : [];
|
|
12978
13124
|
} catch {
|
|
12979
13125
|
return [];
|
|
12980
13126
|
}
|
|
12981
13127
|
}, writeLegacyRegressionGroups = (gates) => {
|
|
12982
13128
|
let file = gatesPath();
|
|
12983
|
-
|
|
13129
|
+
mkdirSync3(dirname4(file), { recursive: !0 }), writeFileSync2(file, JSON.stringify({ version: "prooflane-gates-v1", gates }, null, 2) + `
|
|
12984
13130
|
`, "utf8");
|
|
12985
13131
|
};
|
|
12986
13132
|
app.get("/api/gates", async () => ({ ok: !0, path: ".prooflane/gates.json", gates: readLegacyRegressionGroups() })), app.put("/api/gates/:id", async (req, reply) => {
|
|
@@ -13180,7 +13326,7 @@ ${answer}`
|
|
|
13180
13326
|
let capabilities = await candidate.adoptConnection(flow.transport, name, origin), registered = mcpManager.registerConnectedRuntime({ workspaceId: PROOFLANE_PROJECT, displayName: name ?? "MCP Server", config: origin, createdBy: actor, entitlement, authMode: "oauth" }, candidate, capabilities);
|
|
13181
13327
|
return svc = candidate, activeMcpConnectionId = registered.connection.id, activeMcpAuthMode = "oauth", { status: "connected", capabilities, connection: registered.connection };
|
|
13182
13328
|
}
|
|
13183
|
-
let flowId =
|
|
13329
|
+
let flowId = randomUUID8();
|
|
13184
13330
|
return oauthFlows.set(flowId, { status: "pending" }), flow.finish().then((transport) => candidate.adoptConnection(transport, name, origin)).then((capabilities) => {
|
|
13185
13331
|
let registered = mcpManager.registerConnectedRuntime({ workspaceId: PROOFLANE_PROJECT, displayName: name ?? "MCP Server", config: origin, createdBy: actor, entitlement, authMode: "oauth" }, candidate, capabilities);
|
|
13186
13332
|
svc = candidate, activeMcpConnectionId = registered.connection.id, activeMcpAuthMode = "oauth", oauthFlows.set(flowId, { status: "connected", capabilities });
|
|
@@ -13462,7 +13608,7 @@ ${answer}`
|
|
|
13462
13608
|
if (req.body.recordHistory === !1)
|
|
13463
13609
|
return finish({ ok: !0, report, hostedScan });
|
|
13464
13610
|
let previous = (() => {
|
|
13465
|
-
let last = svc.listRuns(500).find((
|
|
13611
|
+
let last = svc.listRuns(500).find((record7) => record7.pillar === "rag" && record7.evidence);
|
|
13466
13612
|
if (!last?.evidence)
|
|
13467
13613
|
return null;
|
|
13468
13614
|
try {
|
|
@@ -13489,10 +13635,10 @@ ${answer}`
|
|
|
13489
13635
|
}), diff = previous ? hostedRagScoreDiff(previous, snapshot) : void 0;
|
|
13490
13636
|
return finish({ ok: !0, report, diff, run, hostedScan });
|
|
13491
13637
|
}), app.get("/api/rag/hosted-diff/:id", async (req, reply) => {
|
|
13492
|
-
let runs = svc.listRuns(1e3).filter((
|
|
13638
|
+
let runs = svc.listRuns(1e3).filter((record7) => record7.pillar === "rag"), index = runs.findIndex((record7) => record7.id === req.params.id);
|
|
13493
13639
|
if (index === -1)
|
|
13494
13640
|
return reply.code(404).send({ ok: !1, error: "Run not found." });
|
|
13495
|
-
let current = runs[index], previous = runs.slice(index + 1).find((
|
|
13641
|
+
let current = runs[index], previous = runs.slice(index + 1).find((record7) => record7.evidence);
|
|
13496
13642
|
if (!current.evidence || !previous?.evidence)
|
|
13497
13643
|
return { ok: !0, diff: null };
|
|
13498
13644
|
try {
|
|
@@ -13701,7 +13847,7 @@ Assertions must be objectively checkable against the tool's JSON response. Never
|
|
|
13701
13847
|
});
|
|
13702
13848
|
function pushStudioEvent(session, turnId, type, payload) {
|
|
13703
13849
|
let event = {
|
|
13704
|
-
id: `ev-${
|
|
13850
|
+
id: `ev-${randomUUID8().slice(0, 8)}`,
|
|
13705
13851
|
sessionId: session.id,
|
|
13706
13852
|
turnId,
|
|
13707
13853
|
sequence: ++session.sequence,
|
|
@@ -13724,7 +13870,7 @@ Assertions must be objectively checkable against the tool's JSON response. Never
|
|
|
13724
13870
|
};
|
|
13725
13871
|
app.post("/api/prompt-studio/sessions", async (req) => {
|
|
13726
13872
|
let body = req.body ?? {}, now = (/* @__PURE__ */ new Date()).toISOString(), session = {
|
|
13727
|
-
id: `ps-${
|
|
13873
|
+
id: `ps-${randomUUID8().slice(0, 8)}`,
|
|
13728
13874
|
name: (body.name ?? "").trim().slice(0, 120) || `Session ${(/* @__PURE__ */ new Date()).toLocaleString()}`,
|
|
13729
13875
|
createdAt: now,
|
|
13730
13876
|
updatedAt: now,
|
|
@@ -14006,8 +14152,8 @@ Assertions must be objectively checkable against the tool's JSON response. Never
|
|
|
14006
14152
|
let oldest = Date.now() - plan.historyDays * 24 * 60 * 60 * 1e3;
|
|
14007
14153
|
return runs.filter((run) => Date.parse(run.createdAt) >= oldest);
|
|
14008
14154
|
});
|
|
14009
|
-
let uiDist = process.env.KAWACH_UI_DIST ??
|
|
14010
|
-
return
|
|
14155
|
+
let uiDist = process.env.KAWACH_UI_DIST ?? join5(__dirname, "../../ui/dist");
|
|
14156
|
+
return existsSync3(uiDist) && (app.register(fastifyStatic, { root: uiDist }), app.setNotFoundHandler((req, reply) => {
|
|
14011
14157
|
if (req.url.startsWith("/api")) {
|
|
14012
14158
|
reply.code(404).send({ error: "Not found" });
|
|
14013
14159
|
return;
|