@cendor/guardrails 0.1.0 → 0.2.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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EACL,OAAO,EAQR,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,SAAS,EACd,iBAAiB,EAGlB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,MAAM,EACN,OAAO,EACP,OAAO,EACP,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,eAAe,GAChB,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,KAAK,EACL,MAAM,EACN,OAAO,EACP,KAAK,EACL,SAAS,EACT,sBAAsB,GACvB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AAEpC,qGAAqG;AACrG,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,iBAAiB,EAAE,CAAC;CAChC;AAyCD;;;;GAIG;AACH,wBAAgB,QAAQ,CACtB,UAAU,EAAE,SAAS,SAAS,EAAE,EAChC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,OAAO,EAChB,GAAG,CAAC,EAAE,OAAO,GACZ,UAAU,CAaZ;AAED,8FAA8F;AAC9F,wBAAsB,aAAa,CACjC,UAAU,EAAE,SAAS,SAAS,EAAE,EAChC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,OAAO,EAChB,GAAG,CAAC,EAAE,OAAO,GACZ,OAAO,CAAC,UAAU,CAAC,CASrB;AAED,+FAA+F;AAC/F,wBAAgB,KAAK,CACnB,UAAU,EAAE,SAAS,SAAS,EAAE,EAChC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,OAAO,EAChB,GAAG,CAAC,EAAE,OAAO,GACZ,iBAAiB,EAAE,CAErB;AAED,0CAA0C;AAC1C,wBAAsB,UAAU,CAC9B,UAAU,EAAE,SAAS,SAAS,EAAE,EAChC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,OAAO,EAChB,GAAG,CAAC,EAAE,OAAO,GACZ,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAE9B;AAOD;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,UAAU,EAAE,SAAS,SAAS,EAAE,GAAG,IAAI,CAoC9D;AAED,6FAA6F;AAC7F,wBAAgB,SAAS,IAAI,IAAI,CAKhC;AAQD,0FAA0F;AAC1F,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAQzD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EACL,OAAO,EAQR,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,SAAS,EACd,iBAAiB,EAGlB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,MAAM,EACN,OAAO,EACP,QAAQ,EACR,OAAO,EACP,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,uBAAuB,GACxB,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,KAAK,EACL,MAAM,EACN,OAAO,EACP,OAAO,EACP,KAAK,EACL,SAAS,EACT,sBAAsB,GACvB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AACpC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AACpC,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC5D,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACnE,YAAY,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACtF,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAElE,qGAAqG;AACrG,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,iBAAiB,EAAE,CAAC;CAChC;AA2GD;;;;;GAKG;AACH,wBAAgB,QAAQ,CACtB,UAAU,EAAE,SAAS,SAAS,EAAE,EAChC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,OAAO,EAChB,GAAG,CAAC,EAAE,OAAO,GACZ,UAAU,CAuBZ;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,UAAU,EAAE,SAAS,SAAS,EAAE,EAChC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,OAAO,EAChB,GAAG,CAAC,EAAE,OAAO,GACZ,OAAO,CAAC,UAAU,CAAC,CAiBrB;AAED,+FAA+F;AAC/F,wBAAgB,KAAK,CACnB,UAAU,EAAE,SAAS,SAAS,EAAE,EAChC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,OAAO,EAChB,GAAG,CAAC,EAAE,OAAO,GACZ,iBAAiB,EAAE,CAErB;AAED,0CAA0C;AAC1C,wBAAsB,UAAU,CAC9B,UAAU,EAAE,SAAS,SAAS,EAAE,EAChC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,OAAO,EAChB,GAAG,CAAC,EAAE,OAAO,GACZ,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAE9B;AA4CD;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CAAC,UAAU,EAAE,SAAS,SAAS,EAAE,GAAG,IAAI,CAS9D;AAED,6FAA6F;AAC7F,wBAAgB,SAAS,IAAI,IAAI,CAKhC;AA6DD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,MAAM,CAAC,CAAC,EACtB,UAAU,EAAE,SAAS,SAAS,EAAE,EAChC,EAAE,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GACvB,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAsBhB;AAQD,0FAA0F;AAC1F,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAQzD"}
package/dist/index.js CHANGED
@@ -11,9 +11,15 @@
11
11
  * Imports ONLY `@cendor/core` (constitution rule 2). See docs/guardrails.md.
12
12
  */
13
13
  import { LLMCall, MISS, Reroute, ToolCall, addInterceptor, bus, currentTraceId, removeInterceptor, } from '@cendor/core';
14
- import { GuardrailDecision, GuardrailTripped, } from './decision.js';
15
- export { STAGES, ACTIONS, Verdict, GuardrailDecision, GuardrailTripped, defineGuardrail, normalizeStages, } from './decision.js';
14
+ import { GuardrailDecision, GuardrailTripped, Verdict, } from './decision.js';
15
+ export { STAGES, ACTIONS, ON_ERROR, Verdict, GuardrailDecision, GuardrailTripped, defineGuardrail, normalizeStages, validateExecutionPolicy, } from './decision.js';
16
16
  export * as rules from './rules.js';
17
+ export * as judge from './judge.js';
18
+ export * as adapters from './adapters.js';
19
+ export * as semantic from './semantic.js';
20
+ export * as redteam from './redteam.js';
21
+ export { loadPolicy, POLICY_RULE_NAMES } from './policy.js';
22
+ export { loadCorpus, runRedteam, runRedteamAsync, RedTeamReport } from './redteam.js';
17
23
  function applicable(guardrails, stage) {
18
24
  return guardrails.filter((g) => g.stages.includes(stage));
19
25
  }
@@ -27,7 +33,9 @@ function emit(g, stage, verdict, ctx) {
27
33
  tool: ctx.tool ?? '',
28
34
  traceId: ctx.traceId || currentTraceId(),
29
35
  ts: new Date(),
30
- metadata: { ...(ctx.metadata ?? {}) },
36
+ // the guardrail's static metadata (e.g. loadPolicy's policy_hash/version) is the base; the
37
+ // caller's per-call Context.metadata layers on top and wins any key clash.
38
+ metadata: { ...(g.metadata ?? {}), ...(ctx.metadata ?? {}) },
31
39
  });
32
40
  bus.emit(decision); // acttrace (if attached) chains this as a guardrail_decision entry
33
41
  return decision;
@@ -45,32 +53,109 @@ function handle(verdict, g, stage, payload, ctx, decisions) {
45
53
  function isPromise(x) {
46
54
  return x != null && typeof x.then === 'function';
47
55
  }
56
+ const ERROR_REASON_MAX = 200;
57
+ /** A timeout marker error — a check that outran its `timeout` on the async path. */
58
+ class GuardrailTimeoutError extends Error {
59
+ constructor(message) {
60
+ super(message);
61
+ this.name = 'TimeoutError';
62
+ }
63
+ }
64
+ /**
65
+ * Map a check error/timeout to a verdict per `g.onError`. Either way this becomes a
66
+ * `GuardrailDecision`, so the audit chain records that the check could not run — never a silently
67
+ * swallowed exception. The reason carries the error *name* + a truncated message, never the payload
68
+ * the check saw.
69
+ */
70
+ function onErrorVerdict(g, exc) {
71
+ const name = exc?.name ??
72
+ exc?.constructor?.name ??
73
+ 'Error';
74
+ const message = exc?.message ?? String(exc);
75
+ let detail = `${name}: ${message}`;
76
+ if (detail.length > ERROR_REASON_MAX)
77
+ detail = `${detail.slice(0, ERROR_REASON_MAX)}…`;
78
+ if ((g.onError ?? 'fail_closed') === 'fail_open') {
79
+ return new Verdict('flag', `check errored (fail-open): ${detail}`);
80
+ }
81
+ return new Verdict('block', `check errored (fail-closed): ${detail}`);
82
+ }
83
+ /**
84
+ * Run one guardrail's check on the async path, bounding an `async` check to `g.timeout` via
85
+ * `Promise.race`. A *sync* check runs inline (a sync `timeout` cannot be enforced without threads —
86
+ * see {@link Guardrail}). Throws propagate to the caller's `onError` mapping.
87
+ */
88
+ async function runCheckAsync(g, payload, ctx) {
89
+ const result = g.check(payload, ctx);
90
+ if (isPromise(result) && g.timeout !== undefined) {
91
+ const seconds = g.timeout;
92
+ let handle;
93
+ const timeout = new Promise((_resolve, reject) => {
94
+ handle = setTimeout(() => reject(new GuardrailTimeoutError(`guardrail ${JSON.stringify(g.name)} check exceeded ${seconds}s`)), seconds * 1000);
95
+ });
96
+ try {
97
+ return (await Promise.race([result, timeout]));
98
+ }
99
+ finally {
100
+ if (handle !== undefined)
101
+ clearTimeout(handle);
102
+ }
103
+ }
104
+ return (await result);
105
+ }
48
106
  /**
49
107
  * Run the `stage` guardrails over `payload` **synchronously**. Returns `{ payload, decisions }`
50
108
  * with any redactions applied in order; throws `GuardrailTripped` on the first block. An `async`
51
- * check throws here — use {@link evaluateAsync}.
109
+ * check throws here — use {@link evaluateAsync}. A *throwing* sync check honours its `onError`
110
+ * policy; `timeout` applies to the async path only (no sync threads in JS).
52
111
  */
53
112
  export function evaluate(guardrails, stage, payload, ctx) {
54
113
  const context = ctx ?? { stage };
55
114
  const decisions = [];
56
115
  let current = payload;
57
116
  for (const g of applicable(guardrails, stage)) {
58
- const verdict = g.check(current, context);
59
- if (isPromise(verdict)) {
60
- void verdict.catch(() => { }); // swallow the rejection of the discarded promise
117
+ let result;
118
+ try {
119
+ result = g.check(current, context);
120
+ }
121
+ catch (err) {
122
+ if (err instanceof GuardrailTripped)
123
+ throw err;
124
+ // a THROWING sync check → its on_error policy (recorded), never a swallowed exception
125
+ current = handle(onErrorVerdict(g, err), g, stage, current, context, decisions);
126
+ continue;
127
+ }
128
+ // An async check on the sync path is a misuse: this TypeError is raised OUTSIDE the on_error
129
+ // try above so it always propagates (parity with Python `_invoke_sync`), never mapped to a block.
130
+ if (isPromise(result)) {
131
+ void result.catch(() => { }); // swallow the rejection of the discarded promise
61
132
  throw new TypeError(`guardrail ${JSON.stringify(g.name)} is async; use evaluateAsync`);
62
133
  }
63
- current = handle(verdict, g, stage, current, context, decisions);
134
+ current = handle(result, g, stage, current, context, decisions);
64
135
  }
65
136
  return { payload: current, decisions };
66
137
  }
67
- /** Async counterpart of {@link evaluate}: awaits `async` checks, calls sync ones directly. */
138
+ /**
139
+ * Async counterpart of {@link evaluate}: awaits `async` checks (bounded by each guardrail's
140
+ * `timeout`), calls sync ones directly, and applies each guardrail's `onError` policy on a
141
+ * throw/timeout.
142
+ */
68
143
  export async function evaluateAsync(guardrails, stage, payload, ctx) {
69
144
  const context = ctx ?? { stage };
70
145
  const decisions = [];
71
146
  let current = payload;
72
147
  for (const g of applicable(guardrails, stage)) {
73
- const verdict = await g.check(current, context);
148
+ let verdict;
149
+ try {
150
+ verdict = await runCheckAsync(g, current, context);
151
+ }
152
+ catch (err) {
153
+ if (err instanceof GuardrailTripped)
154
+ throw err; // a block from a nested handle propagates
155
+ verdict = onErrorVerdict(g, err); // throw / timeout → on_error policy (recorded)
156
+ }
157
+ // handle() throws GuardrailTripped on a block — OUTSIDE the try, so a block is never caught as
158
+ // an on_error (only the CHECK's own throws map to on_error).
74
159
  current = handle(verdict, g, stage, current, context, decisions);
75
160
  }
76
161
  return { payload: current, decisions };
@@ -86,46 +171,58 @@ export async function applyAsync(guardrails, stage, payload, ctx) {
86
171
  // --------------------------------------------------------------------------- standalone wiring
87
172
  let installedInterceptor = null;
88
173
  let installedSubscriber = null;
174
+ /**
175
+ * The shared interceptor body used by {@link install} and {@link scoped} — gate an `LLMCall` at the
176
+ * `input` stage (redact reroutes, block raises, pass declines) and a `ToolCall` at the `tool_call`
177
+ * stage (block raises; redact/flag recorded but the call proceeds).
178
+ */
179
+ function gateInterceptor(gl, event) {
180
+ if (event instanceof LLMCall) {
181
+ const ctx = { stage: 'input', traceId: event.traceId };
182
+ const { payload, decisions } = evaluate(gl, 'input', event.messages, ctx);
183
+ if (decisions.some((d) => d.action === 'redact'))
184
+ return new Reroute({ messages: payload });
185
+ return MISS;
186
+ }
187
+ if (event instanceof ToolCall) {
188
+ const ctx = {
189
+ stage: 'tool_call',
190
+ tool: event.name,
191
+ toolArgs: event.arguments,
192
+ traceId: event.traceId,
193
+ };
194
+ evaluate(gl, 'tool_call', event.arguments, ctx); // block throws; else record + proceed
195
+ return MISS;
196
+ }
197
+ return MISS;
198
+ }
199
+ /**
200
+ * The shared post-flight output subscriber body: gate the completed `LLMCall`'s response text at the
201
+ * `output` stage (block raises after the call ran).
202
+ */
203
+ function gateOutput(gl, event) {
204
+ if (!(event instanceof LLMCall))
205
+ return;
206
+ const text = responseText(event);
207
+ if (text === null)
208
+ return;
209
+ const ctx = { stage: 'output', traceId: event.traceId };
210
+ evaluate(gl, 'output', text, ctx); // block throws post-flight
211
+ }
89
212
  /**
90
213
  * Gate every instrumented call by registering ONE `@cendor/core` interceptor (+ an output
91
214
  * subscriber). Framework-independent. Input: a block raises (nothing spends), a redact reroutes the
92
215
  * cleaned messages, a pass declines. tool_call: a block raises; else record + proceed (tools have
93
216
  * no message-rewrite seam). Output: a bus subscriber raises **post-flight** on a block (same
94
217
  * overshoot semantics as tokenguard's `onExceed:"raise"`). Runs sync checks only. Call
95
- * {@link uninstall} to remove.
218
+ * {@link uninstall} to remove. `install()` is **process-global** — for a concurrent server that
219
+ * varies guardrails per request, use {@link scoped} instead.
96
220
  */
97
221
  export function install(guardrails) {
98
222
  uninstall();
99
223
  const gl = [...guardrails];
100
- const interceptor = (event) => {
101
- if (event instanceof LLMCall) {
102
- const ctx = { stage: 'input', traceId: event.traceId };
103
- const { payload, decisions } = evaluate(gl, 'input', event.messages, ctx);
104
- if (decisions.some((d) => d.action === 'redact'))
105
- return new Reroute({ messages: payload });
106
- return MISS;
107
- }
108
- if (event instanceof ToolCall) {
109
- const ctx = {
110
- stage: 'tool_call',
111
- tool: event.name,
112
- toolArgs: event.arguments,
113
- traceId: event.traceId,
114
- };
115
- evaluate(gl, 'tool_call', event.arguments, ctx); // block throws; else record + proceed
116
- return MISS;
117
- }
118
- return MISS;
119
- };
120
- const subscriber = (event) => {
121
- if (!(event instanceof LLMCall))
122
- return;
123
- const text = responseText(event);
124
- if (text === null)
125
- return;
126
- const ctx = { stage: 'output', traceId: event.traceId };
127
- evaluate(gl, 'output', text, ctx); // block throws post-flight
128
- };
224
+ const interceptor = (event) => gateInterceptor(gl, event);
225
+ const subscriber = (event) => gateOutput(gl, event);
129
226
  addInterceptor(interceptor);
130
227
  bus.subscribe(subscriber);
131
228
  installedInterceptor = interceptor;
@@ -140,6 +237,98 @@ export function uninstall() {
140
237
  installedInterceptor = null;
141
238
  installedSubscriber = null;
142
239
  }
240
+ //: The guardrails active in *this* execution context, or `undefined` outside any `scoped` block.
241
+ //: With a real `AsyncLocalStorage` installed (Node), overlapping async tasks each see their own
242
+ //: value; the ambient fallback is single-context (documented — not concurrency-safe).
243
+ let scopeStore;
244
+ let ambientScope;
245
+ let alsRequested = false;
246
+ /**
247
+ * Lazily install a real `AsyncLocalStorage`-backed scope store (Node only), so overlapping async
248
+ * requests stay isolated. Best-effort + idempotent: on edge/browser (`node:async_hooks` missing) it
249
+ * quietly keeps the ambient fallback, so `@cendor/guardrails` stays all-runtime (no `node:*` at the
250
+ * module top). Mirrors the spirit of `@cendor/core`'s `installTraceContext`.
251
+ */
252
+ async function ensureAls() {
253
+ if (alsRequested)
254
+ return;
255
+ alsRequested = true;
256
+ try {
257
+ const { AsyncLocalStorage } = await import('node:async_hooks');
258
+ if (!scopeStore)
259
+ scopeStore = new AsyncLocalStorage();
260
+ }
261
+ catch {
262
+ // node:async_hooks unavailable (edge/browser) — keep the ambient fallback (single-context)
263
+ }
264
+ }
265
+ void ensureAls(); // best-effort auto-install so real Node usage gets concurrency-correct isolation
266
+ function activeScope() {
267
+ return scopeStore ? scopeStore.getStore() : ambientScope;
268
+ }
269
+ function scopedInterceptor(event) {
270
+ const gl = activeScope();
271
+ if (!gl || gl.length === 0)
272
+ return MISS; // no active scope in this context — decline
273
+ return gateInterceptor(gl, event);
274
+ }
275
+ function scopedSubscriber(event) {
276
+ const gl = activeScope();
277
+ if (!gl || gl.length === 0)
278
+ return;
279
+ gateOutput(gl, event);
280
+ }
281
+ /**
282
+ * Register the context-gated interceptor + subscriber (idempotent — `addInterceptor` / `bus.subscribe`
283
+ * de-dupe). They stay registered and are no-ops outside a {@link scoped} block, so leaving them
284
+ * installed costs a store lookup per call and needs no teardown.
285
+ */
286
+ function ensureScopedSeam() {
287
+ addInterceptor(scopedInterceptor);
288
+ bus.subscribe(scopedSubscriber);
289
+ }
290
+ /**
291
+ * Gate every instrumented call for the duration of `fn` — like {@link install}, but **scoped to the
292
+ * current execution context** rather than process-global. Runs `fn` with `guardrails` active and
293
+ * returns its result (sync or a `Promise`); the previous scope is restored on exit.
294
+ *
295
+ * With a real `AsyncLocalStorage` (auto-installed on Node), a concurrent server (async tasks) can
296
+ * vary guardrails per request without one request's set leaking into another. On edge/browser the
297
+ * fallback is a save/restore module variable — correct for sequential/nested use, **not**
298
+ * concurrency-safe. Nest freely — an inner `scoped` replaces the set for its block. Runs sync checks
299
+ * only (the seam is sync).
300
+ *
301
+ * ```ts
302
+ * await scoped([rules.keywordDeny(['secret'], { action: 'block' })], async () => {
303
+ * await client.chat.completions.create(...); // gated here
304
+ * });
305
+ * ```
306
+ */
307
+ export function scoped(guardrails, fn) {
308
+ ensureScopedSeam();
309
+ void ensureAls();
310
+ const gl = [...guardrails];
311
+ if (scopeStore)
312
+ return scopeStore.run(gl, fn);
313
+ // Ambient fallback (single-context): save/restore, honouring sync or async `fn` like core's trace.
314
+ const previous = ambientScope;
315
+ ambientScope = gl;
316
+ let result;
317
+ try {
318
+ result = fn();
319
+ }
320
+ catch (err) {
321
+ ambientScope = previous;
322
+ throw err;
323
+ }
324
+ if (result instanceof Promise) {
325
+ return result.finally(() => {
326
+ ambientScope = previous;
327
+ });
328
+ }
329
+ ambientScope = previous;
330
+ return result;
331
+ }
143
332
  function get(obj, name) {
144
333
  return obj != null && typeof obj === 'object'
145
334
  ? obj[name]
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * LLM-judge helpers — turn a bring-your-own model call into a usable guardrail. The TS port of
3
+ * `cendor.guardrails.judge`.
4
+ *
5
+ * cendor ships **no** classifier. `rules.llmJudge` is an adapter *contract*: you supply the model
6
+ * call. These helpers give that call the boring, error-prone parts so you don't hand-roll them —
7
+ *
8
+ * - {@link verdictPrompt} — a strict system instruction that pins the model to a two-field JSON
9
+ * verdict (`{"trip": <bool>, "reason": "<short>"}`), so the output is parseable, not prose.
10
+ * - {@link parseVerdict} — strict JSON → `Verdict` (or `null` to pass). Malformed output *throws* so
11
+ * the guardrail's `onError` policy decides (a garbled judge fails **closed** by default).
12
+ * - {@link judge} — glue the two around your `respond(system, user)` callable (sync or async) into a
13
+ * check you hand straight to `rules.llmJudge`.
14
+ *
15
+ * The judge's own spend is budgeted and audited: make the call through an `instrument()`-ed client
16
+ * and its tokens + cost land in tokenguard / acttrace like any other call.
17
+ */
18
+ import { type Context, Verdict } from './decision.js';
19
+ /** A `respond(system, user)` model callable (sync or async) — returns the assistant's reply string. */
20
+ export type Respond = (system: string, user: string) => string | Promise<string>;
21
+ /**
22
+ * The default judge instruction. `{policy}` is filled with your risk description. It pins the model
23
+ * to strict JSON so {@link parseVerdict} can read it — no chain-of-thought, no prose.
24
+ */
25
+ export declare const DEFAULT_SYSTEM: string;
26
+ /**
27
+ * Build the judge's system instruction for `policy` (a plain-language description of what should
28
+ * trip). Override `template` to customise, keeping the `{policy}` placeholder and the strict-JSON
29
+ * verdict contract {@link parseVerdict} expects.
30
+ */
31
+ export declare function verdictPrompt(policy: string, template?: string): string;
32
+ /**
33
+ * Parse a strict-JSON judge reply into a `Verdict` (trip) or `null` (pass). Expects
34
+ * `{"trip": <bool>, "reason": "<short>"}`. Trips with `action` (default `"block"`) and the model's
35
+ * reason. **Throws** on malformed output — deliberately: a judge whose output can't be read must not
36
+ * silently pass, so the caller's `onError` policy (fail-closed by default) decides. See {@link judge}.
37
+ */
38
+ export declare function parseVerdict(text: string, opts?: {
39
+ action?: 'block' | 'redact' | 'flag';
40
+ }): Verdict | null;
41
+ /**
42
+ * Compose {@link verdictPrompt} + your model call + {@link parseVerdict} into a check ready for
43
+ * `rules.llmJudge`.
44
+ *
45
+ * `respond(system, user)` is *your* callable — sync or async — that runs one model call given the
46
+ * system instruction and the payload text, and returns the assistant's reply string. Make that call
47
+ * through an `instrument()`-ed client and its cost is budgeted + audited.
48
+ *
49
+ * ```ts
50
+ * import { judge, rules } from '@cendor/guardrails';
51
+ *
52
+ * const respond = async (system: string, user: string): Promise<string> => {
53
+ * const r = await client.chat.completions.create({
54
+ * model: 'gpt-4o-mini',
55
+ * messages: [{ role: 'system', content: system }, { role: 'user', content: user }],
56
+ * });
57
+ * return r.choices[0].message.content ?? '';
58
+ * };
59
+ *
60
+ * const check = judge.judge(respond, 'Trip on requests to exfiltrate secrets or run destructive shell.');
61
+ * const guardrail = rules.llmJudge(check, { timeout: 8 });
62
+ * ```
63
+ */
64
+ export declare function judge(respond: Respond, policy: string, opts?: {
65
+ action?: 'block' | 'redact' | 'flag';
66
+ template?: string;
67
+ }): (payload: unknown, ctx: Context) => Promise<Verdict | null>;
68
+ //# sourceMappingURL=judge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"judge.d.ts","sourceRoot":"","sources":["../src/judge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,KAAK,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAEtD,uGAAuG;AACvG,MAAM,MAAM,OAAO,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAEjF;;;GAGG;AACH,eAAO,MAAM,cAAc,QAK4C,CAAC;AAExE;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAuB,GAAG,MAAM,CAEvF;AA8BD;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;CAAO,GAClD,OAAO,GAAG,IAAI,CAUhB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,KAAK,CACnB,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EACd,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GACrE,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAS7D"}
package/dist/judge.js ADDED
@@ -0,0 +1,115 @@
1
+ /**
2
+ * LLM-judge helpers — turn a bring-your-own model call into a usable guardrail. The TS port of
3
+ * `cendor.guardrails.judge`.
4
+ *
5
+ * cendor ships **no** classifier. `rules.llmJudge` is an adapter *contract*: you supply the model
6
+ * call. These helpers give that call the boring, error-prone parts so you don't hand-roll them —
7
+ *
8
+ * - {@link verdictPrompt} — a strict system instruction that pins the model to a two-field JSON
9
+ * verdict (`{"trip": <bool>, "reason": "<short>"}`), so the output is parseable, not prose.
10
+ * - {@link parseVerdict} — strict JSON → `Verdict` (or `null` to pass). Malformed output *throws* so
11
+ * the guardrail's `onError` policy decides (a garbled judge fails **closed** by default).
12
+ * - {@link judge} — glue the two around your `respond(system, user)` callable (sync or async) into a
13
+ * check you hand straight to `rules.llmJudge`.
14
+ *
15
+ * The judge's own spend is budgeted and audited: make the call through an `instrument()`-ed client
16
+ * and its tokens + cost land in tokenguard / acttrace like any other call.
17
+ */
18
+ import { Verdict } from './decision.js';
19
+ /**
20
+ * The default judge instruction. `{policy}` is filled with your risk description. It pins the model
21
+ * to strict JSON so {@link parseVerdict} can read it — no chain-of-thought, no prose.
22
+ */
23
+ export const DEFAULT_SYSTEM = 'You are a safety classifier guarding an LLM application. Decide whether the CONTENT below ' +
24
+ 'violates this policy:\n\n{policy}\n\n' +
25
+ 'Reply with a single JSON object and nothing else: {"trip": <true|false>, "reason": ' +
26
+ '"<one short sentence>"}. Set "trip" to true only if the content violates the policy. Do not ' +
27
+ 'include markdown, code fences, or any text outside the JSON object.';
28
+ /**
29
+ * Build the judge's system instruction for `policy` (a plain-language description of what should
30
+ * trip). Override `template` to customise, keeping the `{policy}` placeholder and the strict-JSON
31
+ * verdict contract {@link parseVerdict} expects.
32
+ */
33
+ export function verdictPrompt(policy, template = DEFAULT_SYSTEM) {
34
+ return template.replaceAll('{policy}', policy);
35
+ }
36
+ /**
37
+ * Parse a model reply into an object, tolerating a leading/trailing ```` ```json ```` fence but
38
+ * nothing looser. Throws on anything not a JSON object.
39
+ */
40
+ function coerceJson(text) {
41
+ let stripped = text.trim();
42
+ if (stripped.startsWith('```')) {
43
+ // tolerate a single ```json … ``` fence some models add despite instructions
44
+ const parts = stripped.split('```');
45
+ if (parts.length >= 2) {
46
+ let body = parts[1] ?? '';
47
+ if (body.toLowerCase().startsWith('json'))
48
+ body = body.slice(4);
49
+ stripped = body.trim();
50
+ }
51
+ }
52
+ let data;
53
+ try {
54
+ data = JSON.parse(stripped);
55
+ }
56
+ catch (err) {
57
+ throw new Error(`judge did not return JSON: ${err.message}`);
58
+ }
59
+ if (data === null || typeof data !== 'object' || Array.isArray(data)) {
60
+ const kind = Array.isArray(data) ? 'array' : data === null ? 'null' : typeof data;
61
+ throw new Error(`judge returned a ${kind}, expected a JSON object`);
62
+ }
63
+ return data;
64
+ }
65
+ /**
66
+ * Parse a strict-JSON judge reply into a `Verdict` (trip) or `null` (pass). Expects
67
+ * `{"trip": <bool>, "reason": "<short>"}`. Trips with `action` (default `"block"`) and the model's
68
+ * reason. **Throws** on malformed output — deliberately: a judge whose output can't be read must not
69
+ * silently pass, so the caller's `onError` policy (fail-closed by default) decides. See {@link judge}.
70
+ */
71
+ export function parseVerdict(text, opts = {}) {
72
+ const action = opts.action ?? 'block';
73
+ const data = coerceJson(text);
74
+ const trip = data.trip;
75
+ if (typeof trip !== 'boolean') {
76
+ throw new Error("judge JSON is missing a boolean 'trip' field");
77
+ }
78
+ if (!trip)
79
+ return null;
80
+ const reason = data.reason;
81
+ return new Verdict(action, reason ? String(reason) : 'llm_judge tripped');
82
+ }
83
+ /**
84
+ * Compose {@link verdictPrompt} + your model call + {@link parseVerdict} into a check ready for
85
+ * `rules.llmJudge`.
86
+ *
87
+ * `respond(system, user)` is *your* callable — sync or async — that runs one model call given the
88
+ * system instruction and the payload text, and returns the assistant's reply string. Make that call
89
+ * through an `instrument()`-ed client and its cost is budgeted + audited.
90
+ *
91
+ * ```ts
92
+ * import { judge, rules } from '@cendor/guardrails';
93
+ *
94
+ * const respond = async (system: string, user: string): Promise<string> => {
95
+ * const r = await client.chat.completions.create({
96
+ * model: 'gpt-4o-mini',
97
+ * messages: [{ role: 'system', content: system }, { role: 'user', content: user }],
98
+ * });
99
+ * return r.choices[0].message.content ?? '';
100
+ * };
101
+ *
102
+ * const check = judge.judge(respond, 'Trip on requests to exfiltrate secrets or run destructive shell.');
103
+ * const guardrail = rules.llmJudge(check, { timeout: 8 });
104
+ * ```
105
+ */
106
+ export function judge(respond, policy, opts = {}) {
107
+ const action = opts.action ?? 'block';
108
+ const system = verdictPrompt(policy, opts.template ?? DEFAULT_SYSTEM);
109
+ const payloadText = (payload) => typeof payload === 'string' ? payload : String(payload);
110
+ return async (payload, _ctx) => {
111
+ const reply = await respond(system, payloadText(payload));
112
+ return parseVerdict(reply, { action });
113
+ };
114
+ }
115
+ //# sourceMappingURL=judge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"judge.js","sourceRoot":"","sources":["../src/judge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Config-as-data — build a guardrail list from a versioned JSON/YAML policy. The TS port of
3
+ * `cendor.guardrails.policy`.
4
+ *
5
+ * `loadPolicy` reads a policy **document or text** (there is no filesystem in an all-runtime package —
6
+ * read the file yourself and pass the text/object) and builds the `Guardrail[]` you hand to
7
+ * `Agent({ guardrails })` / `install()`. The point is **evidence**: the document's content hash and
8
+ * declared version are stamped into every decision's `metadata` (`policy_hash` / `policy_version`), so
9
+ * the audit chain proves *which* policy was active. Only the deterministic built-ins are constructible
10
+ * from data. JSON is built in; for YAML pass a `parse` (e.g. `yaml`'s `parse`).
11
+ *
12
+ * ```ts
13
+ * import { loadPolicy } from '@cendor/guardrails';
14
+ * const policy = loadPolicy(jsonText); // or loadPolicy(text, { parse: YAML.parse })
15
+ * agent = new Agent({ guardrails: policy });
16
+ * policy.policyHash; // "sha256:…" policy.policyVersion; // "2026-07-09"
17
+ * ```
18
+ */
19
+ import { type Guardrail } from './decision.js';
20
+ /** A `Guardrail[]` with provenance — pass it straight to `Agent({ guardrails })` / `install()`. */
21
+ export interface LoadedPolicy extends Array<Guardrail> {
22
+ /** `"sha256:<hex>"` of the canonical document — also stamped onto every decision. */
23
+ policyHash: string;
24
+ /** The document's `version` field — also stamped onto every decision. */
25
+ policyVersion: string;
26
+ }
27
+ export interface LoadPolicyOptions {
28
+ /** Parse `source` when it is a string (default `JSON.parse`); pass e.g. a YAML parser for YAML. */
29
+ parse?: (text: string) => unknown;
30
+ }
31
+ /** The rule names a policy document may use (deterministic built-ins only). */
32
+ export declare const POLICY_RULE_NAMES: readonly string[];
33
+ /**
34
+ * Build a {@link LoadedPolicy} from a JSON/YAML document (a parsed object, or text parsed with
35
+ * `JSON.parse` / your `opts.parse`). Every guardrail is stamped with `policy_hash` / `policy_version`
36
+ * in its metadata, so each decision records which policy was active.
37
+ *
38
+ * @throws if the document is malformed or names an unknown / non-declarative rule.
39
+ */
40
+ export declare function loadPolicy(source: string | Record<string, unknown>, opts?: LoadPolicyOptions): LoadedPolicy;
41
+ //# sourceMappingURL=policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,KAAK,SAAS,EAAmB,MAAM,eAAe,CAAC;AAchE,mGAAmG;AACnG,MAAM,WAAW,YAAa,SAAQ,KAAK,CAAC,SAAS,CAAC;IACpD,qFAAqF;IACrF,UAAU,EAAE,MAAM,CAAC;IACnB,yEAAyE;IACzE,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC,mGAAmG;IACnG,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;CACnC;AAyCD,+EAA+E;AAC/E,eAAO,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAA8B,CAAC;AAgB9E;;;;;;GAMG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACxC,IAAI,GAAE,iBAAsB,GAC3B,YAAY,CA8Cd"}