@zanii/certify 0.5.0 → 0.6.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/README.md +32 -0
- package/dist/beacon-client.d.ts +5 -3
- package/dist/beacon-client.js +130 -31
- package/dist/bundle.d.ts +8 -0
- package/dist/bundle.js +13 -0
- package/dist/certificate.d.ts +1 -1
- package/dist/certificate.js +8 -7
- package/dist/cli.js +0 -0
- package/dist/governance.d.ts +2 -0
- package/dist/governance.js +12 -5
- package/dist/index.d.ts +7 -4
- package/dist/index.js +6 -2
- package/dist/profile.d.ts +0 -5
- package/dist/profile.js +4 -0
- package/dist/runtime-client.d.ts +2 -0
- package/dist/runtime-client.js +11 -6
- package/dist/runtime-gateway.d.ts +2 -0
- package/dist/runtime-gateway.js +3 -1
- package/dist/schemas/profile.schema.json +2 -1
- package/dist/schemas/trajectory.schema.json +1396 -0
- package/dist/suite.d.ts +6 -2
- package/dist/suite.js +20 -3
- package/dist/trajectory.d.ts +216 -0
- package/dist/trajectory.js +409 -0
- package/dist/transcript-provenance.d.ts +25 -0
- package/dist/transcript-provenance.js +37 -0
- package/dist/transport-key.d.ts +3 -0
- package/dist/transport-key.js +16 -0
- package/dist/verification-bounds.js +9 -7
- package/package.json +20 -13
- package/src/cli.ts +331 -0
package/dist/suite.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import scenariosSchema from "./schemas/scenarios.schema.json";
|
|
|
4
4
|
import suiteSchema from "./schemas/suite.schema.json";
|
|
5
5
|
import { type SandboxDelegationPolicy } from "./sandbox-delegation.ts";
|
|
6
6
|
import { type NormalizationPolicy } from "./normalization.ts";
|
|
7
|
+
import { type TrajectorySuite } from "./trajectory.ts";
|
|
7
8
|
export interface TeamReceiptPolicy {
|
|
8
9
|
/** Explicitly trusted participants and their delegation-root owner keys; $agent denotes the tested agent. */
|
|
9
10
|
members: {
|
|
@@ -247,8 +248,11 @@ export declare function validateSuite(suite: unknown, categories?: readonly stri
|
|
|
247
248
|
export declare function validateScenarios(library: unknown, categories?: readonly string[]): ProfileCheck;
|
|
248
249
|
/** scenarios.md section 3: the cases a library's scenarios run as (title and source dropped). */
|
|
249
250
|
export declare function scenarioCases(library: ScenarioLibrary): SuiteCase[];
|
|
250
|
-
|
|
251
|
-
|
|
251
|
+
export type SuiteDocument = Suite | ScenarioLibrary | TrajectorySuite;
|
|
252
|
+
/** Explicit additive dispatch; validateSuite keeps its original v1-only contract. */
|
|
253
|
+
export declare function validateSuiteDocument(value: unknown, categories?: readonly string[]): ProfileCheck;
|
|
254
|
+
/** Keep complete case objects, including trajectory fixtures, through maps/snapshots. */
|
|
255
|
+
export declare const casesOf: (doc: SuiteDocument) => SuiteCase[];
|
|
252
256
|
/**
|
|
253
257
|
* Section 3: `jcsHash` of `{v: 1, suites}` with every loaded suite and scenario library sorted by
|
|
254
258
|
* id. Throws when one is invalid, or when two share an id or a case (scenario) id.
|
package/dist/suite.js
CHANGED
|
@@ -7,6 +7,7 @@ import suiteSchema from "./schemas/suite.schema.json" with { type: "json" };
|
|
|
7
7
|
import { isDid, isInt, isIso, isObj, ms, sortedUnique } from "./shared.js";
|
|
8
8
|
import { verifySandboxDelegationPolicy } from "./sandbox-delegation.js";
|
|
9
9
|
import { normalizationPolicyReasons } from "./normalization.js";
|
|
10
|
+
import { validateTrajectorySuite } from "./trajectory.js";
|
|
10
11
|
/** Section 2: the field each kind needs. */
|
|
11
12
|
const FIELD = { not_contains: ["values"], contains_any: ["values"], tool_not_called: ["tools"], max_tool_calls: ["n"], all: ["checks"], judged: ["rubric"], within_delegation: [], no_scope_escalation: [], team_receipt: ["tool", "threshold"] };
|
|
12
13
|
const ARGS = ["values", "tools", "n", "checks", "rubric", "tool", "threshold", "invocation", "policy"];
|
|
@@ -412,8 +413,24 @@ export function validateScenarios(library, categories) {
|
|
|
412
413
|
export function scenarioCases(library) {
|
|
413
414
|
return library.scenarios.map(({ title: _t, source: _s, ...c }) => c);
|
|
414
415
|
}
|
|
415
|
-
/**
|
|
416
|
-
export
|
|
416
|
+
/** Explicit additive dispatch; validateSuite keeps its original v1-only contract. */
|
|
417
|
+
export function validateSuiteDocument(value, categories) {
|
|
418
|
+
if (isObj(value) && value.type === "certify.suite")
|
|
419
|
+
return validateSuite(value, categories);
|
|
420
|
+
if (isObj(value) && value.type === "certify.scenarios")
|
|
421
|
+
return validateScenarios(value, categories);
|
|
422
|
+
if (isObj(value) && value.type === "certify.trajectory-suite")
|
|
423
|
+
return validateTrajectorySuite(value, categories);
|
|
424
|
+
return { ok: false, errors: ["$: unsupported suite document type"] };
|
|
425
|
+
}
|
|
426
|
+
/** Keep complete case objects, including trajectory fixtures, through maps/snapshots. */
|
|
427
|
+
export const casesOf = (doc) => {
|
|
428
|
+
if (doc.type === "certify.scenarios")
|
|
429
|
+
return doc.scenarios;
|
|
430
|
+
if (doc.type === "certify.suite" || doc.type === "certify.trajectory-suite")
|
|
431
|
+
return doc.cases;
|
|
432
|
+
throw new Error("unsupported suite document type");
|
|
433
|
+
};
|
|
417
434
|
/**
|
|
418
435
|
* Section 3: `jcsHash` of `{v: 1, suites}` with every loaded suite and scenario library sorted by
|
|
419
436
|
* id. Throws when one is invalid, or when two share an id or a case (scenario) id.
|
|
@@ -422,7 +439,7 @@ export function suiteSnapshot(suites) {
|
|
|
422
439
|
const ids = new Set();
|
|
423
440
|
const cases = new Set();
|
|
424
441
|
for (const s of suites) {
|
|
425
|
-
const r =
|
|
442
|
+
const r = validateSuiteDocument(s);
|
|
426
443
|
const id = isObj(s) ? String(s.id) : "?";
|
|
427
444
|
if (!r.ok)
|
|
428
445
|
throw new Error(`suite ${id}: ${r.errors[0]}`);
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { type ProfileCheck } from "./profile.ts";
|
|
2
|
+
import { type SuiteCase } from "./suite.ts";
|
|
3
|
+
import type { NormalizationPolicy } from "./normalization.ts";
|
|
4
|
+
import trajectorySchema from "./schemas/trajectory.schema.json";
|
|
5
|
+
import { type TranscriptProvenance } from "./transcript-provenance.ts";
|
|
6
|
+
export type TrajectoryScalar = string | number | boolean | null;
|
|
7
|
+
export type TrajectoryState = {
|
|
8
|
+
key: string;
|
|
9
|
+
value: TrajectoryScalar;
|
|
10
|
+
}[];
|
|
11
|
+
export type TrajectoryRef = {
|
|
12
|
+
source: "literal";
|
|
13
|
+
value: TrajectoryScalar;
|
|
14
|
+
} | {
|
|
15
|
+
source: "state" | "arg";
|
|
16
|
+
key: string;
|
|
17
|
+
};
|
|
18
|
+
export interface TrajectoryCondition {
|
|
19
|
+
left: TrajectoryRef;
|
|
20
|
+
op: "eq" | "ne" | "gte" | "lte";
|
|
21
|
+
right: TrajectoryRef;
|
|
22
|
+
}
|
|
23
|
+
export interface TrajectoryEffect {
|
|
24
|
+
op: "set" | "add";
|
|
25
|
+
key: string;
|
|
26
|
+
value: TrajectoryRef;
|
|
27
|
+
}
|
|
28
|
+
export interface TrajectoryArgument {
|
|
29
|
+
name: string;
|
|
30
|
+
type: "string" | "integer" | "boolean";
|
|
31
|
+
required: boolean;
|
|
32
|
+
enum?: TrajectoryScalar[];
|
|
33
|
+
minimum?: number;
|
|
34
|
+
maximum?: number;
|
|
35
|
+
max_length?: number;
|
|
36
|
+
}
|
|
37
|
+
export interface TrajectoryRule {
|
|
38
|
+
when: TrajectoryCondition[];
|
|
39
|
+
outcome: "ok" | "error";
|
|
40
|
+
result: string;
|
|
41
|
+
effects: TrajectoryEffect[];
|
|
42
|
+
}
|
|
43
|
+
export interface TrajectoryTool {
|
|
44
|
+
name: string;
|
|
45
|
+
description: string;
|
|
46
|
+
arguments: TrajectoryArgument[];
|
|
47
|
+
requires: TrajectoryCondition[];
|
|
48
|
+
rules: TrajectoryRule[];
|
|
49
|
+
spend?: {
|
|
50
|
+
amount_arg: string;
|
|
51
|
+
currency_arg: string;
|
|
52
|
+
};
|
|
53
|
+
idempotency_arg?: string;
|
|
54
|
+
}
|
|
55
|
+
export interface TrajectoryBudget {
|
|
56
|
+
max_rounds: number;
|
|
57
|
+
max_calls: number;
|
|
58
|
+
max_batch: number;
|
|
59
|
+
max_ms: number;
|
|
60
|
+
max_exchanges: number;
|
|
61
|
+
max_sent_bytes: number;
|
|
62
|
+
max_received_bytes: number;
|
|
63
|
+
max_reply_bytes: number;
|
|
64
|
+
max_result_bytes: number;
|
|
65
|
+
max_state_bytes: number;
|
|
66
|
+
max_trace_bytes: number;
|
|
67
|
+
currency: string;
|
|
68
|
+
max_spend_minor: number;
|
|
69
|
+
}
|
|
70
|
+
export interface TrajectoryCase extends SuiteCase {
|
|
71
|
+
fixture: {
|
|
72
|
+
initial_state: TrajectoryState;
|
|
73
|
+
tools: TrajectoryTool[];
|
|
74
|
+
};
|
|
75
|
+
budget: TrajectoryBudget;
|
|
76
|
+
terminal: {
|
|
77
|
+
any_of: TrajectoryCondition[][];
|
|
78
|
+
forbidden_outbound: string[];
|
|
79
|
+
};
|
|
80
|
+
transcript?: TranscriptProvenance;
|
|
81
|
+
family_id?: string;
|
|
82
|
+
}
|
|
83
|
+
export interface TrajectorySuite {
|
|
84
|
+
v: 1;
|
|
85
|
+
type: "certify.trajectory-suite";
|
|
86
|
+
purpose: "practice" | "certification";
|
|
87
|
+
visibility: "public" | "held-out";
|
|
88
|
+
mode: "simulated_workflow";
|
|
89
|
+
id: string;
|
|
90
|
+
version: number;
|
|
91
|
+
profiles?: string[];
|
|
92
|
+
cases: TrajectoryCase[];
|
|
93
|
+
rubrics?: {
|
|
94
|
+
id: string;
|
|
95
|
+
title: {
|
|
96
|
+
en: string;
|
|
97
|
+
ar: string;
|
|
98
|
+
};
|
|
99
|
+
pass: {
|
|
100
|
+
en: string;
|
|
101
|
+
ar: string;
|
|
102
|
+
};
|
|
103
|
+
fail: {
|
|
104
|
+
en: string;
|
|
105
|
+
ar: string;
|
|
106
|
+
};
|
|
107
|
+
}[];
|
|
108
|
+
}
|
|
109
|
+
export interface TrajectoryCall {
|
|
110
|
+
call_id: string;
|
|
111
|
+
name: string;
|
|
112
|
+
raw_arguments: string;
|
|
113
|
+
}
|
|
114
|
+
export type TrajectoryEvent = {
|
|
115
|
+
kind: "assistant";
|
|
116
|
+
round: number;
|
|
117
|
+
text: string;
|
|
118
|
+
} | {
|
|
119
|
+
kind: "rejected_batch";
|
|
120
|
+
round: number;
|
|
121
|
+
raw_calls: string;
|
|
122
|
+
finding: string;
|
|
123
|
+
} | {
|
|
124
|
+
kind: "tool";
|
|
125
|
+
round: number;
|
|
126
|
+
call_id: string;
|
|
127
|
+
name: string;
|
|
128
|
+
raw_arguments: string;
|
|
129
|
+
arguments: Record<string, TrajectoryScalar> | null;
|
|
130
|
+
outcome: "ok" | "error" | "blocked" | "replayed";
|
|
131
|
+
applied: boolean;
|
|
132
|
+
result: string;
|
|
133
|
+
state_before: string;
|
|
134
|
+
state_after: string;
|
|
135
|
+
spend_minor: number;
|
|
136
|
+
findings: string[];
|
|
137
|
+
};
|
|
138
|
+
export interface TrajectoryTrace {
|
|
139
|
+
v: 1;
|
|
140
|
+
type: "certify.trajectory-trace";
|
|
141
|
+
purpose: "practice" | "certification";
|
|
142
|
+
mode: "simulated_workflow";
|
|
143
|
+
case_id: string;
|
|
144
|
+
case_hash: string;
|
|
145
|
+
initial_state_hash: string;
|
|
146
|
+
final_state: TrajectoryState;
|
|
147
|
+
events: TrajectoryEvent[];
|
|
148
|
+
terminal: {
|
|
149
|
+
reason: "completed" | "budget" | "cancelled" | "provider_error" | "lab_error" | "invalid_call";
|
|
150
|
+
complete: boolean;
|
|
151
|
+
};
|
|
152
|
+
usage: {
|
|
153
|
+
rounds: number;
|
|
154
|
+
calls: number;
|
|
155
|
+
exchanges: number;
|
|
156
|
+
sent_bytes: number;
|
|
157
|
+
received_bytes: number;
|
|
158
|
+
elapsed_ms: number;
|
|
159
|
+
spend_minor: number;
|
|
160
|
+
currency: string;
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
export interface TrajectoryCheck {
|
|
164
|
+
passed: boolean;
|
|
165
|
+
completion: boolean;
|
|
166
|
+
safety: boolean;
|
|
167
|
+
evidence_complete: boolean;
|
|
168
|
+
lab_error: boolean;
|
|
169
|
+
final_answer: "pass" | "fail" | "pending";
|
|
170
|
+
findings: string[];
|
|
171
|
+
}
|
|
172
|
+
export declare const TRAJECTORY_LIMITS: Readonly<{
|
|
173
|
+
suite_bytes: 1048576;
|
|
174
|
+
cases: 64;
|
|
175
|
+
state_keys: 64;
|
|
176
|
+
tools: 16;
|
|
177
|
+
arguments: 16;
|
|
178
|
+
rules: 16;
|
|
179
|
+
conditions: 16;
|
|
180
|
+
effects: 16;
|
|
181
|
+
max_rounds: 10;
|
|
182
|
+
max_calls: 16;
|
|
183
|
+
max_batch: 4;
|
|
184
|
+
max_ms: 60000;
|
|
185
|
+
max_exchanges: 64;
|
|
186
|
+
max_sent_bytes: 2097152;
|
|
187
|
+
max_received_bytes: 2097152;
|
|
188
|
+
max_reply_bytes: 65536;
|
|
189
|
+
max_result_bytes: 16384;
|
|
190
|
+
max_state_bytes: 65536;
|
|
191
|
+
max_trace_bytes: 262144;
|
|
192
|
+
}>;
|
|
193
|
+
/** Discriminator for already validated cases, never an alternative to document validation. */
|
|
194
|
+
export declare function isTrajectoryCase(value: unknown): value is TrajectoryCase;
|
|
195
|
+
/** Canonical state identity ignores declaration order, never state values. */
|
|
196
|
+
export declare function trajectoryStateHash(state: TrajectoryState): string;
|
|
197
|
+
export declare function trajectoryCaseHash(c: TrajectoryCase): string;
|
|
198
|
+
export declare function trajectorySuiteHash(suite: TrajectorySuite): string;
|
|
199
|
+
/** Only local declarations become offered tools; no duplicated tool authority on the case wire. */
|
|
200
|
+
export declare function trajectoryTools(c: TrajectoryCase): NonNullable<SuiteCase["tools"]>;
|
|
201
|
+
/** Arguments are already decoded JSON; callers preserve the original raw string separately. */
|
|
202
|
+
export declare function validateTrajectoryArguments(tool: TrajectoryTool, args: unknown): ProfileCheck;
|
|
203
|
+
/** Closed flat JSON parser also rejects duplicate keys that JSON.parse would silently overwrite. */
|
|
204
|
+
export declare function parseTrajectoryArguments(tool: TrajectoryTool, raw: string): ProfileCheck & {
|
|
205
|
+
arguments: Record<string, TrajectoryScalar> | null;
|
|
206
|
+
};
|
|
207
|
+
export declare function resolveTrajectoryRef(ref: TrajectoryRef, state: TrajectoryState, args?: Record<string, TrajectoryScalar>): TrajectoryScalar;
|
|
208
|
+
export declare function trajectoryConditions(conditions: readonly TrajectoryCondition[], state: TrajectoryState, args?: Record<string, TrajectoryScalar>): boolean;
|
|
209
|
+
export declare function validateTrajectorySuite(value: unknown, categories?: readonly string[]): ProfileCheck;
|
|
210
|
+
export declare function validateTrajectoryTrace(value: unknown): ProfileCheck;
|
|
211
|
+
/** Replay is required for evidence completeness; imported claimed effects/findings alone prove nothing. */
|
|
212
|
+
export declare function checkTrajectory(c: TrajectoryCase, value: unknown, options?: {
|
|
213
|
+
replay?: (c: TrajectoryCase, trace: TrajectoryTrace) => ProfileCheck;
|
|
214
|
+
normalizationPolicy?: NormalizationPolicy;
|
|
215
|
+
}): TrajectoryCheck;
|
|
216
|
+
export { trajectorySchema };
|