witnora 0.13.12 → 0.14.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/vendor/onegent-runtime/production-evaluator-kit.d.ts +85 -0
- package/dist/vendor/onegent-runtime/production-evaluator-kit.d.ts.map +1 -0
- package/dist/vendor/onegent-runtime/production-evaluator-kit.js +131 -0
- package/dist/vendor/onegent-runtime/signed-change-manifest.d.ts +40 -0
- package/dist/vendor/onegent-runtime/signed-change-manifest.d.ts.map +1 -0
- package/dist/vendor/onegent-runtime/signed-change-manifest.js +22 -0
- package/package.json +9 -1
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
export declare const PRODUCTION_EVALUATOR_OBSERVATION_VERSION: "witnora.production_evaluator_observation.v0.1";
|
|
2
|
+
export type ProductionEvaluatorTemplate = "CRM_RECORD_STATE" | "TICKET_STATUS" | "EMAIL_DELIVERY" | "DATABASE_READ_ONLY" | "WEBHOOK_DELIVERY" | "QUEUE_JOB_COMPLETION" | "PAYMENT_REFUND_RESULT" | "BROWSER_WORKFLOW_OUTCOME";
|
|
3
|
+
type SafeScalar = string | number | boolean | null;
|
|
4
|
+
type SafeFields = Record<string, SafeScalar>;
|
|
5
|
+
export interface ProductionEvaluatorRequest {
|
|
6
|
+
resourceId: string;
|
|
7
|
+
criterionId: string;
|
|
8
|
+
expected: SafeFields;
|
|
9
|
+
parameters?: SafeScalar[];
|
|
10
|
+
}
|
|
11
|
+
export interface ProductionEvaluatorObservation {
|
|
12
|
+
schemaVersion: typeof PRODUCTION_EVALUATOR_OBSERVATION_VERSION;
|
|
13
|
+
template: ProductionEvaluatorTemplate;
|
|
14
|
+
provider: string;
|
|
15
|
+
environment: "sandbox" | "staging" | "production";
|
|
16
|
+
criterion: {
|
|
17
|
+
id: string;
|
|
18
|
+
expectedDigestSha256: string;
|
|
19
|
+
};
|
|
20
|
+
scope: {
|
|
21
|
+
resourceIdSha256: string;
|
|
22
|
+
credentialHandleSha256: string;
|
|
23
|
+
};
|
|
24
|
+
result: "SATISFIED" | "NOT_SATISFIED" | "NOT_OBSERVED";
|
|
25
|
+
observation: {
|
|
26
|
+
fields: SafeFields;
|
|
27
|
+
digestSha256: string;
|
|
28
|
+
observedAt: string;
|
|
29
|
+
};
|
|
30
|
+
evaluatorIdentity?: {
|
|
31
|
+
id: string;
|
|
32
|
+
version: string;
|
|
33
|
+
digestSha256: string;
|
|
34
|
+
};
|
|
35
|
+
limitations: string[];
|
|
36
|
+
}
|
|
37
|
+
export interface ProductionOutcomeEvaluator {
|
|
38
|
+
readonly template: ProductionEvaluatorTemplate;
|
|
39
|
+
evaluate(request: ProductionEvaluatorRequest): Promise<ProductionEvaluatorObservation>;
|
|
40
|
+
}
|
|
41
|
+
interface CommonOptions {
|
|
42
|
+
provider: string;
|
|
43
|
+
environment: "sandbox" | "staging" | "production";
|
|
44
|
+
credentialHandle: string;
|
|
45
|
+
resolveCredential(handle: string): Promise<string>;
|
|
46
|
+
select(value: Record<string, unknown>): Record<string, unknown>;
|
|
47
|
+
timeoutMs?: number;
|
|
48
|
+
now?: () => Date;
|
|
49
|
+
}
|
|
50
|
+
export interface HttpProductionEvaluatorOptions extends CommonOptions {
|
|
51
|
+
allowedOrigin: string;
|
|
52
|
+
resourcePath(resourceId: string): string;
|
|
53
|
+
fetch?: typeof fetch;
|
|
54
|
+
}
|
|
55
|
+
export interface DatabaseReadOnlyEvaluatorOptions extends CommonOptions {
|
|
56
|
+
statementId: string;
|
|
57
|
+
executePrepared(input: {
|
|
58
|
+
statementId: string;
|
|
59
|
+
parameters: SafeScalar[];
|
|
60
|
+
credential: string;
|
|
61
|
+
signal: AbortSignal;
|
|
62
|
+
}): Promise<Record<string, unknown>>;
|
|
63
|
+
}
|
|
64
|
+
export interface BrowserWorkflowOutcomeEvaluatorOptions extends CommonOptions {
|
|
65
|
+
observerIdentity: {
|
|
66
|
+
id: string;
|
|
67
|
+
version: string;
|
|
68
|
+
digestSha256: string;
|
|
69
|
+
};
|
|
70
|
+
observe(input: {
|
|
71
|
+
resourceId: string;
|
|
72
|
+
credential: string;
|
|
73
|
+
signal: AbortSignal;
|
|
74
|
+
}): Promise<Record<string, unknown>>;
|
|
75
|
+
}
|
|
76
|
+
export declare const createCrmRecordStateEvaluator: (options: HttpProductionEvaluatorOptions) => ProductionOutcomeEvaluator;
|
|
77
|
+
export declare const createTicketStatusEvaluator: (options: HttpProductionEvaluatorOptions) => ProductionOutcomeEvaluator;
|
|
78
|
+
export declare const createEmailDeliveryEvaluator: (options: HttpProductionEvaluatorOptions) => ProductionOutcomeEvaluator;
|
|
79
|
+
export declare const createWebhookDeliveryEvaluator: (options: HttpProductionEvaluatorOptions) => ProductionOutcomeEvaluator;
|
|
80
|
+
export declare const createQueueJobCompletionEvaluator: (options: HttpProductionEvaluatorOptions) => ProductionOutcomeEvaluator;
|
|
81
|
+
export declare const createPaymentRefundResultEvaluator: (options: HttpProductionEvaluatorOptions) => ProductionOutcomeEvaluator;
|
|
82
|
+
export declare function createDatabaseReadOnlyEvaluator(options: DatabaseReadOnlyEvaluatorOptions): ProductionOutcomeEvaluator;
|
|
83
|
+
export declare function createBrowserWorkflowOutcomeEvaluator(options: BrowserWorkflowOutcomeEvaluatorOptions): ProductionOutcomeEvaluator;
|
|
84
|
+
export {};
|
|
85
|
+
//# sourceMappingURL=production-evaluator-kit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"production-evaluator-kit.d.ts","sourceRoot":"","sources":["../../../../onegent-runtime/src/production-evaluator-kit.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,wCAAwC,EAAG,+CAAwD,CAAC;AACjH,MAAM,MAAM,2BAA2B,GAAG,kBAAkB,GAAG,eAAe,GAAG,gBAAgB,GAAG,oBAAoB,GAAG,kBAAkB,GAAG,sBAAsB,GAAG,uBAAuB,GAAG,0BAA0B,CAAC;AAC9N,KAAK,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AACnD,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAE7C,MAAM,WAAW,0BAA0B;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,UAAU,CAAC;IACrB,UAAU,CAAC,EAAE,UAAU,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,8BAA8B;IAC7C,aAAa,EAAE,OAAO,wCAAwC,CAAC;IAC/D,QAAQ,EAAE,2BAA2B,CAAC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,SAAS,GAAG,SAAS,GAAG,YAAY,CAAC;IAClD,SAAS,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,oBAAoB,EAAE,MAAM,CAAA;KAAE,CAAC;IACxD,KAAK,EAAE;QAAE,gBAAgB,EAAE,MAAM,CAAC;QAAC,sBAAsB,EAAE,MAAM,CAAA;KAAE,CAAC;IACpE,MAAM,EAAE,WAAW,GAAG,eAAe,GAAG,cAAc,CAAC;IACvD,WAAW,EAAE;QAAE,MAAM,EAAE,UAAU,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9E,iBAAiB,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1E,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,QAAQ,EAAE,2BAA2B,CAAC;IAC/C,QAAQ,CAAC,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC,8BAA8B,CAAC,CAAC;CACxF;AAED,UAAU,aAAa;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,SAAS,GAAG,SAAS,GAAG,YAAY,CAAC;IAClD,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACnD,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,MAAM,WAAW,8BAA+B,SAAQ,aAAa;IACnE,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC;IACzC,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB;AAED,MAAM,WAAW,gCAAiC,SAAQ,aAAa;IACrE,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,KAAK,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,UAAU,EAAE,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,WAAW,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACtJ;AAED,MAAM,WAAW,sCAAuC,SAAQ,aAAa;IAC3E,gBAAgB,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC;IACxE,OAAO,CAAC,KAAK,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,WAAW,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACnH;AAED,eAAO,MAAM,6BAA6B,GAAI,SAAS,8BAA8B,+BAAqD,CAAC;AAC3I,eAAO,MAAM,2BAA2B,GAAI,SAAS,8BAA8B,+BAAkD,CAAC;AACtI,eAAO,MAAM,4BAA4B,GAAI,SAAS,8BAA8B,+BAAmD,CAAC;AACxI,eAAO,MAAM,8BAA8B,GAAI,SAAS,8BAA8B,+BAAqD,CAAC;AAC5I,eAAO,MAAM,iCAAiC,GAAI,SAAS,8BAA8B,+BAAyD,CAAC;AACnJ,eAAO,MAAM,kCAAkC,GAAI,SAAS,8BAA8B,+BAA0D,CAAC;AAErJ,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,gCAAgC,GAAG,0BAA0B,CAOrH;AAED,wBAAgB,qCAAqC,CAAC,OAAO,EAAE,sCAAsC,GAAG,0BAA0B,CAGjI"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { isIP } from "node:net";
|
|
3
|
+
import { canonicalJson } from "./trust-crypto.js";
|
|
4
|
+
export const PRODUCTION_EVALUATOR_OBSERVATION_VERSION = "witnora.production_evaluator_observation.v0.1";
|
|
5
|
+
export const createCrmRecordStateEvaluator = (options) => createHttpEvaluator("CRM_RECORD_STATE", options);
|
|
6
|
+
export const createTicketStatusEvaluator = (options) => createHttpEvaluator("TICKET_STATUS", options);
|
|
7
|
+
export const createEmailDeliveryEvaluator = (options) => createHttpEvaluator("EMAIL_DELIVERY", options);
|
|
8
|
+
export const createWebhookDeliveryEvaluator = (options) => createHttpEvaluator("WEBHOOK_DELIVERY", options);
|
|
9
|
+
export const createQueueJobCompletionEvaluator = (options) => createHttpEvaluator("QUEUE_JOB_COMPLETION", options);
|
|
10
|
+
export const createPaymentRefundResultEvaluator = (options) => createHttpEvaluator("PAYMENT_REFUND_RESULT", options);
|
|
11
|
+
export function createDatabaseReadOnlyEvaluator(options) {
|
|
12
|
+
validateCommon(options);
|
|
13
|
+
identifier(options.statementId, "statementId");
|
|
14
|
+
return evaluator("DATABASE_READ_ONLY", options, async (request, credential, signal) => {
|
|
15
|
+
const parameters = request.parameters ?? [request.resourceId];
|
|
16
|
+
if (parameters.length > 20 || parameters.some((value) => typeof value === "string" && value.length > 500))
|
|
17
|
+
throw new Error("Database evaluator parameters exceed the bounded contract.");
|
|
18
|
+
return options.executePrepared({ statementId: options.statementId, parameters, credential, signal });
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
export function createBrowserWorkflowOutcomeEvaluator(options) {
|
|
22
|
+
validateCommon(options);
|
|
23
|
+
componentIdentity(options.observerIdentity);
|
|
24
|
+
return evaluator("BROWSER_WORKFLOW_OUTCOME", options, (request, credential, signal) => options.observe({ resourceId: request.resourceId, credential, signal }), options.observerIdentity);
|
|
25
|
+
}
|
|
26
|
+
function createHttpEvaluator(template, options) {
|
|
27
|
+
validateCommon(options);
|
|
28
|
+
const origin = safeOrigin(options.allowedOrigin);
|
|
29
|
+
const requestFetch = options.fetch ?? fetch;
|
|
30
|
+
return evaluator(template, options, async (request, credential, signal) => {
|
|
31
|
+
const path = options.resourcePath(request.resourceId);
|
|
32
|
+
if (typeof path !== "string" || !path.startsWith("/") || path.startsWith("//") || path.includes("..") || path.length > 1_000)
|
|
33
|
+
throw new Error("Evaluator resource path is outside the fixed origin contract.");
|
|
34
|
+
const url = new URL(path, origin);
|
|
35
|
+
if (url.origin !== origin)
|
|
36
|
+
throw new Error("Evaluator resource path changed the fixed origin.");
|
|
37
|
+
const response = await requestFetch(url, { method: "GET", headers: { accept: "application/json", authorization: `Bearer ${credential}` }, redirect: "error", signal });
|
|
38
|
+
if (!response.ok)
|
|
39
|
+
throw new Error(`Read-only evaluator returned HTTP ${response.status}.`);
|
|
40
|
+
const contentLength = Number(response.headers.get("content-length") ?? 0);
|
|
41
|
+
if (contentLength > 64 * 1024)
|
|
42
|
+
throw new Error("Read-only evaluator response exceeded 64 KiB.");
|
|
43
|
+
const bytes = Buffer.from(await response.arrayBuffer());
|
|
44
|
+
if (bytes.length > 64 * 1024)
|
|
45
|
+
throw new Error("Read-only evaluator response exceeded 64 KiB.");
|
|
46
|
+
const parsed = JSON.parse(bytes.toString("utf8"));
|
|
47
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
48
|
+
throw new Error("Read-only evaluator response must be a JSON object.");
|
|
49
|
+
return parsed;
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function evaluator(template, options, observe, evaluatorIdentity) {
|
|
53
|
+
return Object.freeze({
|
|
54
|
+
template,
|
|
55
|
+
async evaluate(request) {
|
|
56
|
+
const resourceId = identifier(request.resourceId, "resourceId");
|
|
57
|
+
const criterionId = identifier(request.criterionId, "criterionId");
|
|
58
|
+
const expected = safeFields(request.expected, "expected");
|
|
59
|
+
const credential = await options.resolveCredential(options.credentialHandle);
|
|
60
|
+
if (typeof credential !== "string" || credential.length < 1 || credential.length > 8_192)
|
|
61
|
+
throw new Error("Read-only evaluator credential was unavailable.");
|
|
62
|
+
const timeoutMs = boundedTimeout(options.timeoutMs);
|
|
63
|
+
const raw = await observe({ ...request, resourceId, criterionId, expected }, credential, AbortSignal.timeout(timeoutMs));
|
|
64
|
+
const fields = safeFields(options.select(raw), "selected observation");
|
|
65
|
+
const result = Object.entries(expected).every(([key, value]) => Object.is(fields[key], value)) ? "SATISFIED" : "NOT_SATISFIED";
|
|
66
|
+
const observedAt = (options.now ?? (() => new Date()))().toISOString();
|
|
67
|
+
return {
|
|
68
|
+
schemaVersion: PRODUCTION_EVALUATOR_OBSERVATION_VERSION, template, provider: identifier(options.provider, "provider"), environment: options.environment,
|
|
69
|
+
criterion: { id: criterionId, expectedDigestSha256: sha256(canonicalJson(expected)) },
|
|
70
|
+
scope: { resourceIdSha256: sha256(resourceId), credentialHandleSha256: sha256(options.credentialHandle) },
|
|
71
|
+
result, observation: { fields, digestSha256: sha256(canonicalJson(fields)), observedAt },
|
|
72
|
+
...(evaluatorIdentity ? { evaluatorIdentity } : {}),
|
|
73
|
+
limitations: [
|
|
74
|
+
"This result proves one bounded read-only observation and does not authorize a write or generalize to future executions.",
|
|
75
|
+
"Credentials and raw provider payloads remain in the customer environment; only allowlisted scalar fields and digests are returned.",
|
|
76
|
+
],
|
|
77
|
+
};
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
function validateCommon(options) {
|
|
82
|
+
identifier(options.provider, "provider");
|
|
83
|
+
identifier(options.credentialHandle, "credentialHandle");
|
|
84
|
+
if (!["sandbox", "staging", "production"].includes(options.environment))
|
|
85
|
+
throw new Error("environment is invalid.");
|
|
86
|
+
boundedTimeout(options.timeoutMs);
|
|
87
|
+
}
|
|
88
|
+
function safeOrigin(value) {
|
|
89
|
+
let url;
|
|
90
|
+
try {
|
|
91
|
+
url = new URL(value);
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
throw new Error("Evaluator origin is invalid.");
|
|
95
|
+
}
|
|
96
|
+
const literalLoopback = (url.hostname === "127.0.0.1" || url.hostname === "[::1]") && isIP(url.hostname.replace(/^\[|\]$/g, ""));
|
|
97
|
+
if (url.protocol !== "https:" && !(url.protocol === "http:" && literalLoopback))
|
|
98
|
+
throw new Error("Remote evaluator origins must use HTTPS; local development must use a literal loopback address.");
|
|
99
|
+
if (url.username || url.password || url.pathname !== "/" || url.search || url.hash)
|
|
100
|
+
throw new Error("Evaluator origin must contain only scheme, host, and port.");
|
|
101
|
+
return url.origin;
|
|
102
|
+
}
|
|
103
|
+
function safeFields(value, field) {
|
|
104
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
105
|
+
throw new Error(`${field} must be an object.`);
|
|
106
|
+
const entries = Object.entries(value);
|
|
107
|
+
if (entries.length > 32)
|
|
108
|
+
throw new Error(`${field} contains too many fields.`);
|
|
109
|
+
const result = {};
|
|
110
|
+
for (const [key, item] of entries.sort(([left], [right]) => left.localeCompare(right))) {
|
|
111
|
+
if (!/^[A-Za-z][A-Za-z0-9_.-]{0,63}$/.test(key) || /(secret|token|credential|password|authorization|cookie|email|phone|name|address|payload|body|text|prompt)/i.test(key))
|
|
112
|
+
throw new Error(`${field} contains an unsafe field.`);
|
|
113
|
+
if (item !== null && typeof item !== "string" && typeof item !== "number" && typeof item !== "boolean")
|
|
114
|
+
throw new Error(`${field}.${key} must be a scalar.`);
|
|
115
|
+
if (typeof item === "string" && item.length > 500 || typeof item === "number" && !Number.isFinite(item))
|
|
116
|
+
throw new Error(`${field}.${key} exceeds the bounded contract.`);
|
|
117
|
+
result[key] = item;
|
|
118
|
+
}
|
|
119
|
+
return result;
|
|
120
|
+
}
|
|
121
|
+
function componentIdentity(value) {
|
|
122
|
+
identifier(value.id, "observerIdentity.id");
|
|
123
|
+
identifier(value.version, "observerIdentity.version");
|
|
124
|
+
if (!/^[a-f0-9]{64}$/.test(value.digestSha256))
|
|
125
|
+
throw new Error("observerIdentity.digestSha256 is invalid.");
|
|
126
|
+
}
|
|
127
|
+
function identifier(value, field) { if (typeof value !== "string" || !value.trim() || value.length > 200 || !/^[A-Za-z0-9][A-Za-z0-9._:/@-]*$/.test(value))
|
|
128
|
+
throw new Error(`${field} is invalid.`); return value; }
|
|
129
|
+
function boundedTimeout(value = 5_000) { if (!Number.isSafeInteger(value) || value < 100 || value > 10_000)
|
|
130
|
+
throw new Error("Evaluator timeout must be from 100 to 10000 ms."); return value; }
|
|
131
|
+
function sha256(value) { return createHash("sha256").update(value).digest("hex"); }
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { SourceSigner } from "./trust-types.js";
|
|
2
|
+
export declare const SIGNED_CHANGE_MANIFEST_SCHEMA_VERSION: "witnora.signed_change_manifest.v0.1";
|
|
3
|
+
export interface ChangeManifestComponentIdentity {
|
|
4
|
+
id: string;
|
|
5
|
+
version: string;
|
|
6
|
+
digestSha256: string;
|
|
7
|
+
}
|
|
8
|
+
export interface SignedChangeManifestPayload {
|
|
9
|
+
schemaVersion: typeof SIGNED_CHANGE_MANIFEST_SCHEMA_VERSION;
|
|
10
|
+
manifestId: string;
|
|
11
|
+
projectId: string;
|
|
12
|
+
agentId: string;
|
|
13
|
+
agentVersion: string;
|
|
14
|
+
environment: "sandbox" | "staging" | "production";
|
|
15
|
+
observedAt: string;
|
|
16
|
+
modelDigest?: string;
|
|
17
|
+
promptWorkflowDigest?: string;
|
|
18
|
+
toolManifestDigest?: string;
|
|
19
|
+
policyRevision?: string;
|
|
20
|
+
evaluatorIdentity?: ChangeManifestComponentIdentity;
|
|
21
|
+
adapterIdentity?: ChangeManifestComponentIdentity;
|
|
22
|
+
previousManifestDigest?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface SignedChangeManifestEnvelope {
|
|
25
|
+
payload: SignedChangeManifestPayload;
|
|
26
|
+
signature: {
|
|
27
|
+
algorithm: "Ed25519";
|
|
28
|
+
keyId: string;
|
|
29
|
+
signature: string;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export declare function createSignedChangeManifestEnvelope(payload: SignedChangeManifestPayload, signer: SourceSigner): SignedChangeManifestEnvelope;
|
|
33
|
+
export declare function uploadSignedChangeManifest(options: {
|
|
34
|
+
baseUrl: string;
|
|
35
|
+
projectId: string;
|
|
36
|
+
apiKey: string;
|
|
37
|
+
envelope: SignedChangeManifestEnvelope;
|
|
38
|
+
fetch?: typeof fetch;
|
|
39
|
+
}): Promise<unknown>;
|
|
40
|
+
//# sourceMappingURL=signed-change-manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signed-change-manifest.d.ts","sourceRoot":"","sources":["../../../../onegent-runtime/src/signed-change-manifest.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,eAAO,MAAM,qCAAqC,EAAG,qCAA8C,CAAC;AACpG,MAAM,WAAW,+BAA+B;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE;AACtG,MAAM,WAAW,2BAA2B;IAC1C,aAAa,EAAE,OAAO,qCAAqC,CAAC;IAC5D,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,SAAS,GAAG,SAAS,GAAG,YAAY,CAAC;IAClD,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,+BAA+B,CAAC;IACpD,eAAe,CAAC,EAAE,+BAA+B,CAAC;IAClD,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC;AACD,MAAM,WAAW,4BAA4B;IAC3C,OAAO,EAAE,2BAA2B,CAAC;IACrC,SAAS,EAAE;QAAE,SAAS,EAAE,SAAS,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;CACvE;AAED,wBAAgB,kCAAkC,CAAC,OAAO,EAAE,2BAA2B,EAAE,MAAM,EAAE,YAAY,GAAG,4BAA4B,CAM3I;AAED,wBAAsB,0BAA0B,CAAC,OAAO,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,4BAA4B,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,KAAK,CAAA;CAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAQhM"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { createPrivateKey, sign } from "node:crypto";
|
|
2
|
+
import { canonicalJson } from "./trust-crypto.js";
|
|
3
|
+
export const SIGNED_CHANGE_MANIFEST_SCHEMA_VERSION = "witnora.signed_change_manifest.v0.1";
|
|
4
|
+
export function createSignedChangeManifestEnvelope(payload, signer) {
|
|
5
|
+
if (payload.schemaVersion !== SIGNED_CHANGE_MANIFEST_SCHEMA_VERSION)
|
|
6
|
+
throw new Error("Signed Change Manifest schemaVersion is unsupported.");
|
|
7
|
+
return {
|
|
8
|
+
payload: structuredClone(payload),
|
|
9
|
+
signature: { algorithm: "Ed25519", keyId: signer.keyId, signature: sign(null, Buffer.from(canonicalJson(payload)), createPrivateKey(signer.privateKeyPem)).toString("base64url") },
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export async function uploadSignedChangeManifest(options) {
|
|
13
|
+
const response = await (options.fetch ?? fetch)(`${options.baseUrl.replace(/\/$/, "")}/v1/projects/${encodeURIComponent(options.projectId)}/change-manifests`, {
|
|
14
|
+
method: "POST", headers: { "content-type": "application/json", authorization: `Bearer ${options.apiKey}` }, body: JSON.stringify(options.envelope), redirect: "error", signal: AbortSignal.timeout(10_000),
|
|
15
|
+
});
|
|
16
|
+
const text = await response.text();
|
|
17
|
+
if (Buffer.byteLength(text) > 256 * 1024)
|
|
18
|
+
throw new Error("Witnora Change Manifest response exceeded 256 KiB.");
|
|
19
|
+
if (!response.ok)
|
|
20
|
+
throw new Error(`Witnora Change Manifest upload returned HTTP ${response.status}.`);
|
|
21
|
+
return JSON.parse(text);
|
|
22
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "witnora",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "Independent assurance for covered agent action paths across models and frameworks.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -44,6 +44,14 @@
|
|
|
44
44
|
"types": "./dist/vendor/onegent-runtime/business-task-evaluator.d.ts",
|
|
45
45
|
"import": "./dist/vendor/onegent-runtime/business-task-evaluator.js"
|
|
46
46
|
},
|
|
47
|
+
"./production-evaluator-kit": {
|
|
48
|
+
"types": "./dist/vendor/onegent-runtime/production-evaluator-kit.d.ts",
|
|
49
|
+
"import": "./dist/vendor/onegent-runtime/production-evaluator-kit.js"
|
|
50
|
+
},
|
|
51
|
+
"./change-manifest": {
|
|
52
|
+
"types": "./dist/vendor/onegent-runtime/signed-change-manifest.d.ts",
|
|
53
|
+
"import": "./dist/vendor/onegent-runtime/signed-change-manifest.js"
|
|
54
|
+
},
|
|
47
55
|
"./deployment-enforcement": {
|
|
48
56
|
"types": "./dist/internal/control-client/deployment-enforcement.d.ts",
|
|
49
57
|
"import": "./dist/internal/control-client/deployment-enforcement.js"
|