@kindgi/guardrails 0.1.1 → 0.1.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"define-check.d.ts","sourceRoot":"","sources":["../src/define-check.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAG/D,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAShF;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI,CAAC,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAA;CAAE,GACvF,CAAC,GACD,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAEtC;;;;;;;;;;GAUG;AACH,MAAM,WAAW,eAAe,CAAC,aAAa,SAAS,SAAS;IAC9D;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B;;;;;;OAMG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,aAAa,CAAC;IACtC;;;;;;;OAOG;IACH,QAAQ,CAAC,QAAQ,EAAE,CACjB,MAAM,EAAE,gBAAgB,CAAC,aAAa,CAAC,EACvC,KAAK,EAAE,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EACnC,QAAQ,EAAE,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,KACnC,UAAU,CAAC,aAAa,CAAC,CAAC;IAC/B;;;;OAIG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,MAAM,GAAG,SAAS,CAAC;CACnE;AAED;;;;;GAKG;AACH,MAAM,MAAM,YAAY,CAAC,aAAa,SAAS,SAAS,IAAI,eAAe,GAAG;IAC5E,QAAQ,CAAC,SAAS,EAAE,aAAa,SAAS,aAAa,GAAG,aAAa,GAAG,SAAS,CAAC;IACpF,QAAQ,CAAC,gBAAgB,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAC/D,CAAC;AAEF;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,CAAC,aAAa,SAAS,SAAS,GAAG,SAAS,EACrE,IAAI,EAAE,eAAe,CAAC,aAAa,CAAC,GACnC,YAAY,CAAC,aAAa,CAAC,CAiE7B"}
1
+ {"version":3,"file":"define-check.d.ts","sourceRoot":"","sources":["../src/define-check.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAG/D,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAShF;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI,CAAC,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAA;CAAE,GACvF,CAAC,GACD,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAEtC;;;;;;;;;;GAUG;AACH,MAAM,WAAW,eAAe,CAAC,aAAa,SAAS,SAAS;IAC9D;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B;;;;;;OAMG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,aAAa,CAAC;IACtC;;;;;;;OAOG;IACH,QAAQ,CAAC,QAAQ,EAAE,CACjB,MAAM,EAAE,gBAAgB,CAAC,aAAa,CAAC,EACvC,KAAK,EAAE,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EACnC,QAAQ,EAAE,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,KACnC,UAAU,CAAC,aAAa,CAAC,CAAC;IAC/B;;;;OAIG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,MAAM,GAAG,SAAS,CAAC;CACnE;AAED;;;;;GAKG;AACH,MAAM,MAAM,YAAY,CAAC,aAAa,SAAS,SAAS,IAAI,eAAe,GAAG;IAC5E,QAAQ,CAAC,SAAS,EAAE,aAAa,SAAS,aAAa,GAAG,aAAa,GAAG,SAAS,CAAC;IACpF,QAAQ,CAAC,gBAAgB,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAC/D,CAAC;AAEF;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,CAAC,aAAa,SAAS,SAAS,GAAG,SAAS,EACrE,IAAI,EAAE,eAAe,CAAC,aAAa,CAAC,GACnC,YAAY,CAAC,aAAa,CAAC,CA0E7B"}
@@ -76,18 +76,68 @@ export function defineCheck(spec) {
76
76
  };
77
77
  };
78
78
  const validate = chainValidator(derivedValidator, spec.validateConfig);
79
+ // `evaluate` gets the config its schema resolves: the schema's defaults
80
+ // applied (a guardrail that declares no config gets them all), and a
81
+ // config that doesn't fit refused, naming where. Python's guardrails do
82
+ // the same. Without a schema, the config as declared.
83
+ const evaluate = evaluateWithResolvedConfig(spec.evaluate, configResolver(zodSchema, jsonSchema, spec.id));
79
84
  const check = {
80
85
  id: spec.id,
81
86
  kind: spec.kind,
82
- evaluate: spec.evaluate,
87
+ evaluate,
83
88
  ...(validate !== undefined && { validateConfig: validate }),
84
89
  ...(zodSchema !== undefined && { configZod: zodSchema }),
85
90
  ...(jsonSchema !== undefined && { configJsonSchema: jsonSchema }),
86
91
  };
87
92
  return check;
88
93
  }
89
- function compileValidator(schema, checkId) {
90
- const ajv = new Ajv2020({ strict: true, allErrors: true, allowUnionTypes: false });
94
+ /** `evaluate`, called with the config `resolve` gives (as declared without one). */
95
+ function evaluateWithResolvedConfig(evaluate, resolve) {
96
+ if (resolve === undefined)
97
+ return evaluate;
98
+ return async (config, trace, bindings) => evaluate((await resolve(config)), trace, bindings);
99
+ }
100
+ /** The resolver for the check's schema: Zod's own parse, or Ajv for JSON Schema; none without one. */
101
+ function configResolver(zodSchema, jsonSchema, checkId) {
102
+ if (zodSchema !== undefined)
103
+ return zodConfigResolver(zodSchema, checkId);
104
+ if (jsonSchema !== undefined)
105
+ return jsonConfigResolver(jsonSchema, checkId);
106
+ return undefined;
107
+ }
108
+ /** A Zod config, parsed by Zod itself (through `~standard`): its defaults and transforms apply. */
109
+ function zodConfigResolver(schema, checkId) {
110
+ const standard = schema['~standard'];
111
+ return async (config) => {
112
+ const result = await standard.validate(config ?? {});
113
+ if (result.issues === undefined)
114
+ return result.value;
115
+ const issue = result.issues[0];
116
+ const path = (issue?.path ?? [])
117
+ .map((segment) => String(typeof segment === 'object' && segment !== null ? segment.key : segment))
118
+ .join('.');
119
+ throw new Error(`Check "${checkId}": the guardrail's config doesn't fit its configSchema${path === '' ? '' : ` at ${path}`}: ${issue?.message ?? 'invalid config'}`);
120
+ };
121
+ }
122
+ /** A JSON Schema config: checked by Ajv, which fills in the schema's `default`s (on a copy). */
123
+ function jsonConfigResolver(schema, checkId) {
124
+ const validator = compileValidator(schema, checkId, { useDefaults: true });
125
+ return async (config) => {
126
+ const resolved = structuredClone(config ?? {});
127
+ if (validator(resolved))
128
+ return resolved;
129
+ const first = validator.errors?.[0];
130
+ const path = first?.instancePath ?? '';
131
+ throw new Error(`Check "${checkId}": the guardrail's config doesn't fit its configSchema${path === '' ? '' : ` at ${path}`}: ${first?.message ?? 'invalid config'}`);
132
+ };
133
+ }
134
+ function compileValidator(schema, checkId, options = {}) {
135
+ const ajv = new Ajv2020({
136
+ strict: true,
137
+ allErrors: true,
138
+ allowUnionTypes: false,
139
+ ...(options.useDefaults === true && { useDefaults: true }),
140
+ });
91
141
  addFormats(ajv);
92
142
  try {
93
143
  return ajv.compile(schema);
@@ -1 +1 @@
1
- {"version":3,"file":"define-check.js","sourceRoot":"","sources":["../src/define-check.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"define-check.js","sourceRoot":"","sources":["../src/define-check.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kindgi/guardrails",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Runtime + CI enforcement of agent-behavior guardrails for Kindgi. Same declaration runs at runtime (halt / retry / escalate / log-only / compensate on violation) and in CI (fails the build) — no drift between test and prod. Zero-LLM checks (must-cite, never-call-tool, max-tool-calls, output-matches, tool-order, required-substring, forbidden-substring) are the default fast path; LLM-judge guardrails route via @kindgi/capabilities with explicit budget declarations. Execution strategies and action handlers are pluggable registries, and failed checks optionally emit compliance evidence.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -18,7 +18,8 @@
18
18
  "exports": {
19
19
  ".": {
20
20
  "types": "./dist/index.d.ts",
21
- "import": "./dist/index.js"
21
+ "import": "./dist/index.js",
22
+ "default": "./dist/index.js"
22
23
  }
23
24
  },
24
25
  "files": [
@@ -29,10 +30,10 @@
29
30
  "type-manifest.json"
30
31
  ],
31
32
  "dependencies": {
32
- "@kindgi/capabilities": "0.1.1",
33
- "@kindgi/compliance": "0.1.1",
34
- "@kindgi/schema": "0.1.1",
35
- "@kindgi/types": "0.1.1",
33
+ "@kindgi/capabilities": "0.1.2",
34
+ "@kindgi/compliance": "0.1.2",
35
+ "@kindgi/schema": "0.1.2",
36
+ "@kindgi/types": "0.1.2",
36
37
  "ajv": "^8.17.1",
37
38
  "ajv-formats": "^3.0.1"
38
39
  },
@@ -45,14 +46,14 @@
45
46
  }
46
47
  },
47
48
  "devDependencies": {
48
- "@kindgi/specs": "0.1.1",
49
+ "@kindgi/specs": "0.1.2",
49
50
  "@types/node": "^22.10.5",
50
51
  "typescript": "^5.7.3",
51
52
  "vitest": "^2.1.8",
52
53
  "zod": "^4.6.5"
53
54
  },
54
55
  "engines": {
55
- "node": ">=22.0.0"
56
+ "node": ">=22.12.0"
56
57
  },
57
58
  "publishConfig": {
58
59
  "access": "public",
@@ -169,10 +169,19 @@ export function defineCheck<TConfigSchema extends AnySchema = AnySchema>(
169
169
 
170
170
  const validate = chainValidator(derivedValidator, spec.validateConfig);
171
171
 
172
+ // `evaluate` gets the config its schema resolves: the schema's defaults
173
+ // applied (a guardrail that declares no config gets them all), and a
174
+ // config that doesn't fit refused, naming where. Python's guardrails do
175
+ // the same. Without a schema, the config as declared.
176
+ const evaluate = evaluateWithResolvedConfig(
177
+ spec.evaluate as CheckFunction,
178
+ configResolver(zodSchema, jsonSchema, spec.id),
179
+ );
180
+
172
181
  const check = {
173
182
  id: spec.id,
174
183
  kind: spec.kind,
175
- evaluate: spec.evaluate as CheckFunction,
184
+ evaluate,
176
185
  ...(validate !== undefined && { validateConfig: validate }),
177
186
  ...(zodSchema !== undefined && { configZod: zodSchema }),
178
187
  ...(jsonSchema !== undefined && { configJsonSchema: jsonSchema }),
@@ -181,11 +190,89 @@ export function defineCheck<TConfigSchema extends AnySchema = AnySchema>(
181
190
  return check;
182
191
  }
183
192
 
193
+ /** `evaluate`, called with the config `resolve` gives (as declared without one). */
194
+ function evaluateWithResolvedConfig(
195
+ evaluate: CheckFunction,
196
+ resolve: ConfigResolver | undefined,
197
+ ): CheckFunction {
198
+ if (resolve === undefined) return evaluate;
199
+ return async (config, trace, bindings) =>
200
+ evaluate((await resolve(config)) as Parameters<CheckFunction>[0], trace, bindings);
201
+ }
202
+
203
+ /** The resolver for the check's schema: Zod's own parse, or Ajv for JSON Schema; none without one. */
204
+ function configResolver(
205
+ zodSchema: ZodLikeSchema | undefined,
206
+ jsonSchema: Readonly<Record<string, unknown>> | undefined,
207
+ checkId: string,
208
+ ): ConfigResolver | undefined {
209
+ if (zodSchema !== undefined) return zodConfigResolver(zodSchema, checkId);
210
+ if (jsonSchema !== undefined) return jsonConfigResolver(jsonSchema, checkId);
211
+ return undefined;
212
+ }
213
+
214
+ /** A config resolved by its schema: defaults applied, or an error naming what doesn't fit. */
215
+ type ConfigResolver = (config: unknown) => Promise<unknown>;
216
+
217
+ /** The Standard Schema interface (`~standard`) every Zod v4 schema implements. */
218
+ interface StandardSchema {
219
+ readonly validate: (value: unknown) => StandardResult | Promise<StandardResult>;
220
+ }
221
+ type StandardResult =
222
+ | { readonly value: unknown; readonly issues?: undefined }
223
+ | {
224
+ readonly issues: readonly {
225
+ readonly message: string;
226
+ readonly path?: readonly (PropertyKey | { readonly key: PropertyKey })[];
227
+ }[];
228
+ };
229
+
230
+ /** A Zod config, parsed by Zod itself (through `~standard`): its defaults and transforms apply. */
231
+ function zodConfigResolver(schema: ZodLikeSchema, checkId: string): ConfigResolver {
232
+ const standard = schema['~standard'] as StandardSchema;
233
+ return async (config) => {
234
+ const result = await standard.validate(config ?? {});
235
+ if (result.issues === undefined) return result.value;
236
+ const issue = result.issues[0];
237
+ const path = (issue?.path ?? [])
238
+ .map((segment) =>
239
+ String(typeof segment === 'object' && segment !== null ? segment.key : segment),
240
+ )
241
+ .join('.');
242
+ throw new Error(
243
+ `Check "${checkId}": the guardrail's config doesn't fit its configSchema${path === '' ? '' : ` at ${path}`}: ${issue?.message ?? 'invalid config'}`,
244
+ );
245
+ };
246
+ }
247
+
248
+ /** A JSON Schema config: checked by Ajv, which fills in the schema's `default`s (on a copy). */
249
+ function jsonConfigResolver(
250
+ schema: Readonly<Record<string, unknown>>,
251
+ checkId: string,
252
+ ): ConfigResolver {
253
+ const validator = compileValidator(schema, checkId, { useDefaults: true });
254
+ return async (config) => {
255
+ const resolved = structuredClone(config ?? {});
256
+ if (validator(resolved)) return resolved;
257
+ const first = validator.errors?.[0] as { instancePath?: string; message?: string } | undefined;
258
+ const path = first?.instancePath ?? '';
259
+ throw new Error(
260
+ `Check "${checkId}": the guardrail's config doesn't fit its configSchema${path === '' ? '' : ` at ${path}`}: ${first?.message ?? 'invalid config'}`,
261
+ );
262
+ };
263
+ }
264
+
184
265
  function compileValidator(
185
266
  schema: Readonly<Record<string, unknown>>,
186
267
  checkId: string,
268
+ options: { readonly useDefaults?: boolean } = {},
187
269
  ): ValidateFunction {
188
- const ajv = new Ajv2020({ strict: true, allErrors: true, allowUnionTypes: false });
270
+ const ajv = new Ajv2020({
271
+ strict: true,
272
+ allErrors: true,
273
+ allowUnionTypes: false,
274
+ ...(options.useDefaults === true && { useDefaults: true }),
275
+ });
189
276
  addFormats(ajv);
190
277
  try {
191
278
  return ajv.compile(schema as object);