@directive-run/claude-plugin 1.16.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/.claude-plugin/plugin.json +6 -0
- package/LICENSE +26 -0
- package/README.md +113 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +66 -0
- package/dist/index.d.ts +66 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/package.json +64 -0
- package/skills/README.md +9 -0
- package/skills/building-ai-agents/SKILL.md +414 -0
- package/skills/building-ai-agents/ai-adapters.md +257 -0
- package/skills/building-ai-agents/ai-agents-streaming.md +307 -0
- package/skills/building-ai-agents/ai-communication.md +304 -0
- package/skills/building-ai-agents/api-skeleton.md +5 -0
- package/skills/building-ai-agents/examples.md +849 -0
- package/skills/building-ai-orchestrators/SKILL.md +401 -0
- package/skills/building-ai-orchestrators/ai-multi-agent.md +375 -0
- package/skills/building-ai-orchestrators/ai-orchestrator.md +466 -0
- package/skills/building-ai-orchestrators/ai-tasks.md +268 -0
- package/skills/building-ai-orchestrators/api-skeleton.md +5 -0
- package/skills/building-ai-orchestrators/examples.md +1609 -0
- package/skills/building-directive-systems/SKILL.md +499 -0
- package/skills/building-directive-systems/api-skeleton.md +5 -0
- package/skills/building-directive-systems/examples.md +4149 -0
- package/skills/building-directive-systems/multi-module.md +327 -0
- package/skills/building-directive-systems/plugins.md +361 -0
- package/skills/building-directive-systems/react-adapter.md +376 -0
- package/skills/building-directive-systems/system-api.md +463 -0
- package/skills/getting-started-with-directive/SKILL.md +198 -0
- package/skills/getting-started-with-directive/api-skeleton.md +5 -0
- package/skills/getting-started-with-directive/core-patterns.md +240 -0
- package/skills/getting-started-with-directive/examples.md +87 -0
- package/skills/getting-started-with-directive/sitemap.md +202 -0
- package/skills/hardening-ai-systems/SKILL.md +377 -0
- package/skills/hardening-ai-systems/ai-budget-resilience.md +408 -0
- package/skills/hardening-ai-systems/ai-guardrails-memory.md +370 -0
- package/skills/hardening-ai-systems/ai-security.md +400 -0
- package/skills/hardening-ai-systems/api-skeleton.md +5 -0
- package/skills/hardening-ai-systems/examples.md +628 -0
- package/skills/migrating-to-directive/SKILL.md +249 -0
- package/skills/migrating-to-directive/anti-patterns.md +382 -0
- package/skills/migrating-to-directive/api-skeleton.md +5 -0
- package/skills/migrating-to-directive/core-patterns.md +240 -0
- package/skills/migrating-to-directive/examples.md +511 -0
- package/skills/migrating-to-directive/schema-types.md +273 -0
- package/skills/reviewing-directive-code/SKILL.md +232 -0
- package/skills/reviewing-directive-code/anti-patterns.md +382 -0
- package/skills/reviewing-directive-code/api-skeleton.md +5 -0
- package/skills/reviewing-directive-code/core-patterns.md +240 -0
- package/skills/reviewing-directive-code/examples.md +463 -0
- package/skills/reviewing-directive-code/naming.md +321 -0
- package/skills/scaffolding-directive-modules/SKILL.md +218 -0
- package/skills/scaffolding-directive-modules/api-skeleton.md +5 -0
- package/skills/scaffolding-directive-modules/core-patterns.md +240 -0
- package/skills/scaffolding-directive-modules/examples.md +1386 -0
- package/skills/scaffolding-directive-modules/naming.md +321 -0
- package/skills/scaffolding-directive-modules/schema-types.md +273 -0
- package/skills/testing-ai-systems/SKILL.md +398 -0
- package/skills/testing-ai-systems/ai-debug-observability.md +329 -0
- package/skills/testing-ai-systems/ai-mcp-rag.md +293 -0
- package/skills/testing-ai-systems/ai-testing-evals.md +485 -0
- package/skills/testing-ai-systems/api-skeleton.md +5 -0
- package/skills/testing-ai-systems/examples.md +1261 -0
- package/skills/testing-directive-code/SKILL.md +479 -0
- package/skills/testing-directive-code/api-skeleton.md +5 -0
- package/skills/testing-directive-code/examples.md +156 -0
- package/skills/testing-directive-code/history.md +351 -0
- package/skills/testing-directive-code/testing.md +412 -0
- package/skills/writing-directive-constraints/SKILL.md +486 -0
- package/skills/writing-directive-constraints/api-skeleton.md +5 -0
- package/skills/writing-directive-constraints/constraints.md +274 -0
- package/skills/writing-directive-constraints/error-boundaries.md +330 -0
- package/skills/writing-directive-constraints/examples.md +1361 -0
- package/skills/writing-directive-constraints/resolvers.md +367 -0
- package/skills/writing-directive-modules/SKILL.md +342 -0
- package/skills/writing-directive-modules/anti-patterns.md +382 -0
- package/skills/writing-directive-modules/api-skeleton.md +5 -0
- package/skills/writing-directive-modules/core-patterns.md +240 -0
- package/skills/writing-directive-modules/examples.md +1639 -0
- package/skills/writing-directive-modules/naming.md +321 -0
- package/skills/writing-directive-modules/schema-types.md +273 -0
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
# AI security
|
|
2
|
+
|
|
3
|
+
> Covers `@directive-run/ai` and `@directive-run/ai/guardrails` — `createPIIGuardrail`, `createPromptInjectionGuardrail`, `createAuditTrail`, `createCompliance` (GDPR/CCPA).
|
|
4
|
+
|
|
5
|
+
PII detection and redaction, prompt-injection defense, audit trails with non-repudiation, and GDPR/CCPA compliance — all wired in via Directive's guardrail and instance APIs. Import the audit + compliance instances from `@directive-run/ai` (NOT `@directive-run/core/plugins`); import the security guardrails from `@directive-run/ai/guardrails`.
|
|
6
|
+
|
|
7
|
+
## Decision tree
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
What are you protecting against?
|
|
11
|
+
├── PII in input → createPIIGuardrail() or createEnhancedPIIGuardrail()
|
|
12
|
+
├── PII in output → createOutputPIIGuardrail()
|
|
13
|
+
├── Prompt injection → createPromptInjectionGuardrail()
|
|
14
|
+
├── Audit / forensics → createAuditTrail(config)
|
|
15
|
+
├── GDPR / CCPA → createCompliance(config)
|
|
16
|
+
├── Tool restriction → createToolGuardrail({ allowlist | denylist })
|
|
17
|
+
└── Sensitive content → createContentFilterGuardrail({ blockedPatterns })
|
|
18
|
+
|
|
19
|
+
Where do these go?
|
|
20
|
+
├── Guardrails → orchestrator.guardrails.input / output / toolCall
|
|
21
|
+
├── Audit → record into auditInstance from your call sites (NOT a plugins:[…] entry)
|
|
22
|
+
└── Compliance → instance you call directly (exportData, deleteData, consent.*)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## PII detection + redaction
|
|
26
|
+
|
|
27
|
+
### Basic PII guardrail (input only)
|
|
28
|
+
|
|
29
|
+
`createPIIGuardrail` returns a `GuardrailFn<InputGuardrailData>` — input only. For output PII protection, use `createOutputPIIGuardrail`.
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import { createPIIGuardrail } from "@directive-run/ai/guardrails";
|
|
33
|
+
|
|
34
|
+
const piiInput = createPIIGuardrail({
|
|
35
|
+
patterns: [
|
|
36
|
+
/\b\d{3}-\d{2}-\d{4}\b/, // SSN — already a default, here as a custom example
|
|
37
|
+
/\b[A-Z]{2}\d{6,8}\b/, // Passport
|
|
38
|
+
/ACCT-\d{10}/, // Internal account IDs
|
|
39
|
+
],
|
|
40
|
+
redact: true, // default: false (block instead of redact)
|
|
41
|
+
redactReplacement: "[REDACTED]",
|
|
42
|
+
});
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Built-in default patterns: SSN, credit card numbers, email addresses. Custom `patterns` are added on top.
|
|
46
|
+
|
|
47
|
+
### Enhanced PII guardrails (input + output)
|
|
48
|
+
|
|
49
|
+
For production scenarios — context-aware detection, multi-region defaults, output coverage — use the enhanced factories:
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
import { createEnhancedPIIGuardrail, createOutputPIIGuardrail } from "@directive-run/ai/guardrails";
|
|
53
|
+
|
|
54
|
+
const piiInput = createEnhancedPIIGuardrail({ /* …config… */ });
|
|
55
|
+
const piiOutput = createOutputPIIGuardrail({ /* …config… */ });
|
|
56
|
+
|
|
57
|
+
const orchestrator = createAgentOrchestrator({
|
|
58
|
+
runner,
|
|
59
|
+
guardrails: {
|
|
60
|
+
input: [piiInput],
|
|
61
|
+
output: [piiOutput],
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Wiring it in
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
const orchestrator = createAgentOrchestrator({
|
|
70
|
+
runner,
|
|
71
|
+
guardrails: {
|
|
72
|
+
input: [piiInput],
|
|
73
|
+
output: [piiOutput],
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Prompt-injection defense
|
|
79
|
+
|
|
80
|
+
`createPromptInjectionGuardrail` ships with default + strict pattern sets and a 0–100 risk score. The real options are `strictMode`, `blockThreshold`, `additionalPatterns`, `replacePatterns`, `sanitize`, `onBlocked`, `ignoreCategories`. There is no `sensitivity` field and no `allowlist`.
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
import { createPromptInjectionGuardrail } from "@directive-run/ai/guardrails";
|
|
84
|
+
|
|
85
|
+
// Basic — uses default patterns + 50 block threshold
|
|
86
|
+
const injection = createPromptInjectionGuardrail();
|
|
87
|
+
|
|
88
|
+
// Strict — for high-security applications
|
|
89
|
+
const strictInjection = createPromptInjectionGuardrail({
|
|
90
|
+
strictMode: true, // use STRICT_INJECTION_PATTERNS instead of DEFAULT
|
|
91
|
+
blockThreshold: 25, // lower threshold — more aggressive blocking
|
|
92
|
+
additionalPatterns: [ // your own patterns layered on top
|
|
93
|
+
{ name: "custom_role_override", regex: /you are now a /i, score: 70, category: "role_manipulation" },
|
|
94
|
+
],
|
|
95
|
+
sanitize: false, // when true, attempts to neutralize the input instead of blocking
|
|
96
|
+
onBlocked: (input, result) => {
|
|
97
|
+
metrics.increment("prompt_injection_blocked", { risk: result.riskScore });
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// Roleplay app — allow role-manipulation patterns, keep everything else
|
|
102
|
+
const roleplayInjection = createPromptInjectionGuardrail({
|
|
103
|
+
ignoreCategories: ["role_manipulation"],
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// Replace all defaults
|
|
107
|
+
const customOnly = createPromptInjectionGuardrail({
|
|
108
|
+
replacePatterns: myPatternList,
|
|
109
|
+
});
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Catching the block
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
import { isGuardrailError } from "@directive-run/ai";
|
|
116
|
+
|
|
117
|
+
try {
|
|
118
|
+
await orchestrator.run(agent, userInput);
|
|
119
|
+
} catch (error) {
|
|
120
|
+
if (isGuardrailError(error)) {
|
|
121
|
+
console.log(error.guardrailName); // "prompt-injection"
|
|
122
|
+
console.log(error.code); // "INPUT_GUARDRAIL_FAILED"
|
|
123
|
+
console.log(error.userMessage); // safe-to-display rejection reason
|
|
124
|
+
// error.input and error.data are NON-enumerable (won't leak via JSON.stringify)
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
`GuardrailError` does not expose `errorCode` (it's `code`) or `reason` (the rejection reason becomes the error `message` / `userMessage`). See `ai-guardrails-memory.md` for the full error shape.
|
|
130
|
+
|
|
131
|
+
## Audit trail
|
|
132
|
+
|
|
133
|
+
`createAuditTrail(config)` returns an `AuditInstance` you record into from your call sites — it is NOT a plugin you put in `plugins: […]`. The factory is named `createAuditTrail`, NOT `createAuditTrailPlugin`, and it lives in `@directive-run/ai`, NOT `@directive-run/core/plugins`.
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
import { createAuditTrail } from "@directive-run/ai";
|
|
137
|
+
|
|
138
|
+
const audit = createAuditTrail({
|
|
139
|
+
maxEntries: 10_000, // default 10000
|
|
140
|
+
retentionMs: 7 * 24 * 60 * 60 * 1000, // default: 7 days
|
|
141
|
+
exportInterval: 60_000, // default 60s — async exporter cadence
|
|
142
|
+
exporter: async (entries) => {
|
|
143
|
+
await sendToSIEM(entries);
|
|
144
|
+
},
|
|
145
|
+
piiMasking: {
|
|
146
|
+
enabled: true,
|
|
147
|
+
fields: ["input", "output"],
|
|
148
|
+
},
|
|
149
|
+
signing: { // optional non-repudiation chain
|
|
150
|
+
signFn: (hash) => signWithHSM(hash),
|
|
151
|
+
verifyFn: (hash, sig) => verifyWithHSM(hash, sig),
|
|
152
|
+
},
|
|
153
|
+
sessionId: currentSessionId,
|
|
154
|
+
actorId: currentUserId,
|
|
155
|
+
events: {
|
|
156
|
+
onEntryAdded: (entry) => log("audit:entry", entry.eventType),
|
|
157
|
+
onChainBroken: (result) => alertOnTamper(result),
|
|
158
|
+
onExportError: (err, entries) => log("audit:export:fail", err, entries.length),
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
// Query
|
|
163
|
+
const failed = audit.getEntries({ eventType: "guardrail_check" });
|
|
164
|
+
const verified = await audit.verifyChain();
|
|
165
|
+
const exported = await audit.export(Date.now() - 24 * 60 * 60 * 1000);
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Each `AuditEntry` carries a hash-chained sequence number so `verifyChain()` can prove no entries were dropped or rewritten in flight.
|
|
169
|
+
|
|
170
|
+
### Recording entries
|
|
171
|
+
|
|
172
|
+
For most workflows the orchestrator records relevant events automatically when an audit instance is attached via your own integration code. The bare minimum from a call site:
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
// In your resolver / event handler / orchestrator hook
|
|
176
|
+
audit.record({
|
|
177
|
+
eventType: "agent_run",
|
|
178
|
+
agentName: agent.name,
|
|
179
|
+
input,
|
|
180
|
+
output: result.output,
|
|
181
|
+
tokenUsage: result.tokenUsage,
|
|
182
|
+
});
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
See the API skeleton for the full `AuditEntry` shape.
|
|
186
|
+
|
|
187
|
+
## GDPR / CCPA compliance
|
|
188
|
+
|
|
189
|
+
`createCompliance(config)` returns a `ComplianceInstance` you call directly. The factory is named `createCompliance`, NOT `createCompliancePlugin`, and lives in `@directive-run/ai`. **`storage` is required.**
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
import { createCompliance } from "@directive-run/ai";
|
|
193
|
+
|
|
194
|
+
const compliance = createCompliance({
|
|
195
|
+
storage: myComplianceStorage, // REQUIRED — your ComplianceStorage adapter
|
|
196
|
+
retention: {
|
|
197
|
+
maxAgeMs: 30 * 24 * 60 * 60 * 1000, // 30 days
|
|
198
|
+
autoEnforce: true,
|
|
199
|
+
},
|
|
200
|
+
consentPurposes: ["analytics", "personalization", "training"],
|
|
201
|
+
exportExpirationMs: 24 * 60 * 60 * 1000, // signed export links expire in 24h (default)
|
|
202
|
+
auditOperations: true, // mirror every compliance op into the audit trail
|
|
203
|
+
events: {
|
|
204
|
+
onExport: (result) => log("gdpr:export", result.subjectId),
|
|
205
|
+
onDelete: (result) => log("gdpr:delete", result.certificate),
|
|
206
|
+
onConsentChange: (record) => log("consent:change", record),
|
|
207
|
+
onRetentionEnforced: (category, count) => log("retention:enforced", category, count),
|
|
208
|
+
},
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
// GDPR Article 20 — right to data portability
|
|
212
|
+
const exportResult = await compliance.exportData({ subjectId: "user-42", format: "json" });
|
|
213
|
+
|
|
214
|
+
// GDPR Article 17 — right to erasure (returns a signed deletion certificate)
|
|
215
|
+
const deletion = await compliance.deleteData({ subjectId: "user-42", scope: "all" });
|
|
216
|
+
console.log(deletion.certificate.signature);
|
|
217
|
+
|
|
218
|
+
// Consent
|
|
219
|
+
compliance.consent.grant({ subjectId: "user-42", purpose: "analytics" });
|
|
220
|
+
compliance.consent.revoke({ subjectId: "user-42", purpose: "personalization" });
|
|
221
|
+
const consents = compliance.consent.list("user-42");
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
The `storage` adapter is your responsibility — Directive provides the policy + signed-receipt machinery; you provide the database. The `ComplianceStorage` interface lives in `@directive-run/ai`.
|
|
225
|
+
|
|
226
|
+
## Combining the surface
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
import { createAgentOrchestrator } from "@directive-run/ai";
|
|
230
|
+
import { createAuditTrail, createCompliance } from "@directive-run/ai";
|
|
231
|
+
import {
|
|
232
|
+
createPIIGuardrail,
|
|
233
|
+
createOutputPIIGuardrail,
|
|
234
|
+
createPromptInjectionGuardrail,
|
|
235
|
+
createToolGuardrail,
|
|
236
|
+
} from "@directive-run/ai/guardrails";
|
|
237
|
+
|
|
238
|
+
const audit = createAuditTrail({ /* ... */ });
|
|
239
|
+
const compliance = createCompliance({ storage: myStorage });
|
|
240
|
+
|
|
241
|
+
const orchestrator = createAgentOrchestrator({
|
|
242
|
+
runner,
|
|
243
|
+
guardrails: {
|
|
244
|
+
input: [createPIIGuardrail({ redact: true }), createPromptInjectionGuardrail({ strictMode: true })],
|
|
245
|
+
output: [createOutputPIIGuardrail()],
|
|
246
|
+
toolCall: [createToolGuardrail({ allowlist: ["search", "calculator"] })],
|
|
247
|
+
},
|
|
248
|
+
maxTokenBudget: 100_000,
|
|
249
|
+
budgetWarningThreshold: 0.8,
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
// Wire audit + compliance into your orchestrator hooks
|
|
253
|
+
orchestrator.run = (orig => async (agent, input, opts) => {
|
|
254
|
+
audit.record({ eventType: "agent_run", agentName: agent.name, input });
|
|
255
|
+
return orig(agent, input, opts);
|
|
256
|
+
})(orchestrator.run);
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## Security best practices
|
|
260
|
+
|
|
261
|
+
### Validate input before dispatch
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
// WRONG — raw user input goes straight to the agent
|
|
265
|
+
await orchestrator.run(agent, userInput);
|
|
266
|
+
|
|
267
|
+
// CORRECT — sanitize / shape-check first, even with guardrails
|
|
268
|
+
const sanitized = sanitizeInput(userInput);
|
|
269
|
+
await orchestrator.run(agent, sanitized);
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Always set a token budget
|
|
273
|
+
|
|
274
|
+
```typescript
|
|
275
|
+
createAgentOrchestrator({
|
|
276
|
+
runner,
|
|
277
|
+
maxTokenBudget: 100_000,
|
|
278
|
+
budgetWarningThreshold: 0.8,
|
|
279
|
+
onBudgetWarning: (e) => alertOps(e),
|
|
280
|
+
})
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Restrict tool access
|
|
284
|
+
|
|
285
|
+
```typescript
|
|
286
|
+
import { createToolGuardrail } from "@directive-run/ai/guardrails";
|
|
287
|
+
|
|
288
|
+
const tools = createToolGuardrail({
|
|
289
|
+
allowlist: ["search", "calculator", "readFile"],
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
const orchestrator = createAgentOrchestrator({
|
|
293
|
+
runner,
|
|
294
|
+
guardrails: { toolCall: [tools] },
|
|
295
|
+
});
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
For MCP-mediated tools, see `ai-mcp-rag.md` for per-tool approval + risk-scoring.
|
|
299
|
+
|
|
300
|
+
### Always validate output
|
|
301
|
+
|
|
302
|
+
```typescript
|
|
303
|
+
import {
|
|
304
|
+
createOutputSchemaGuardrail,
|
|
305
|
+
createContentFilterGuardrail,
|
|
306
|
+
createOutputPIIGuardrail,
|
|
307
|
+
} from "@directive-run/ai/guardrails";
|
|
308
|
+
|
|
309
|
+
createAgentOrchestrator({
|
|
310
|
+
runner,
|
|
311
|
+
guardrails: {
|
|
312
|
+
output: [
|
|
313
|
+
createOutputSchemaGuardrail({ validate: zodAdapter(expectedSchema) }),
|
|
314
|
+
createContentFilterGuardrail({ blockedPatterns: [/eval\(/, /<script/i] }),
|
|
315
|
+
createOutputPIIGuardrail(),
|
|
316
|
+
],
|
|
317
|
+
},
|
|
318
|
+
});
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
(`createOutputSchemaGuardrail` takes `validate` — not `schema` + `retries`. For automatic retry on schema failure, set `outputSchema` + `maxSchemaRetries` directly on the orchestrator.)
|
|
322
|
+
|
|
323
|
+
## Anti-patterns
|
|
324
|
+
|
|
325
|
+
### Importing audit/compliance from `@directive-run/core/plugins`
|
|
326
|
+
|
|
327
|
+
```typescript
|
|
328
|
+
// WRONG — these names + path don't exist
|
|
329
|
+
import { createAuditTrailPlugin, createCompliancePlugin } from "@directive-run/core/plugins";
|
|
330
|
+
|
|
331
|
+
// CORRECT — createAuditTrail / createCompliance from @directive-run/ai
|
|
332
|
+
import { createAuditTrail, createCompliance } from "@directive-run/ai";
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
### Putting `createAuditTrail()` into `plugins: [...]`
|
|
336
|
+
|
|
337
|
+
```typescript
|
|
338
|
+
// WRONG — createAuditTrail returns an AuditInstance, not a Directive Plugin
|
|
339
|
+
plugins: [createAuditTrail({ /* … */ })],
|
|
340
|
+
|
|
341
|
+
// CORRECT — keep the instance, record into it
|
|
342
|
+
const audit = createAuditTrail({ /* … */ });
|
|
343
|
+
audit.record({ /* … */ });
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
### `createPromptInjectionGuardrail({ sensitivity, allowlist })`
|
|
347
|
+
|
|
348
|
+
```typescript
|
|
349
|
+
// WRONG — sensitivity + allowlist are hallucinated
|
|
350
|
+
createPromptInjectionGuardrail({ sensitivity: "high", allowlist: ["safe phrase"] })
|
|
351
|
+
|
|
352
|
+
// CORRECT — strictMode + blockThreshold + ignoreCategories + replacePatterns
|
|
353
|
+
createPromptInjectionGuardrail({
|
|
354
|
+
strictMode: true,
|
|
355
|
+
blockThreshold: 25,
|
|
356
|
+
ignoreCategories: ["role_manipulation"],
|
|
357
|
+
})
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
### Using `createPIIGuardrail` for output
|
|
361
|
+
|
|
362
|
+
```typescript
|
|
363
|
+
// WRONG — createPIIGuardrail is input-only (GuardrailFn<InputGuardrailData>)
|
|
364
|
+
guardrails: { output: [createPIIGuardrail({ redact: true })] }
|
|
365
|
+
|
|
366
|
+
// CORRECT — createOutputPIIGuardrail for output
|
|
367
|
+
guardrails: { output: [createOutputPIIGuardrail()] }
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
### `createCompliance` without `storage`
|
|
371
|
+
|
|
372
|
+
```typescript
|
|
373
|
+
// WRONG — storage is required
|
|
374
|
+
createCompliance({ retention: { maxAgeMs: 30 * 24 * 60 * 60 * 1000 } })
|
|
375
|
+
|
|
376
|
+
// CORRECT — pass your ComplianceStorage adapter
|
|
377
|
+
createCompliance({
|
|
378
|
+
storage: myStorage,
|
|
379
|
+
retention: { maxAgeMs: 30 * 24 * 60 * 60 * 1000, autoEnforce: true },
|
|
380
|
+
})
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
## Quick reference
|
|
384
|
+
|
|
385
|
+
| API | Import path | Returns | Purpose |
|
|
386
|
+
|---|---|---|---|
|
|
387
|
+
| `createPIIGuardrail` | `@directive-run/ai/guardrails` | `GuardrailFn<InputGuardrailData>` | Basic input PII detection (block or redact) |
|
|
388
|
+
| `createEnhancedPIIGuardrail` | `@directive-run/ai/guardrails` | guardrail | Context-aware input PII |
|
|
389
|
+
| `createOutputPIIGuardrail` | `@directive-run/ai/guardrails` | guardrail | Output PII coverage |
|
|
390
|
+
| `createPromptInjectionGuardrail` | `@directive-run/ai/guardrails` | guardrail | Risk-scored injection defense (`strictMode`, `blockThreshold`) |
|
|
391
|
+
| `createAuditTrail` | `@directive-run/ai` | `AuditInstance` | Hash-chained audit log w/ signing + PII masking + async export |
|
|
392
|
+
| `createCompliance` | `@directive-run/ai` | `ComplianceInstance` | GDPR exportData / deleteData / consent + retention enforcement |
|
|
393
|
+
| `createToolGuardrail` | `@directive-run/ai/guardrails` | guardrail | Tool allow/deny lists |
|
|
394
|
+
| `createContentFilterGuardrail` | `@directive-run/ai/guardrails` | guardrail | Block sensitive patterns (block-only — no redact) |
|
|
395
|
+
| `GuardrailError` / `isGuardrailError` | `@directive-run/ai` | error class + guard | Carries `code`, `guardrailName`, `userMessage` |
|
|
396
|
+
|
|
397
|
+
## See also
|
|
398
|
+
|
|
399
|
+
- [`ai-guardrails-memory.md`](./ai-guardrails-memory.md) — the broader guardrail surface (length, schema, content filter, tool allowlist) this file's security-flavored guardrails compose with
|
|
400
|
+
- [`ai-mcp-rag.md`](./ai-mcp-rag.md) — `toolConstraints[…].requireApproval` is where MCP tool calls thread into the approval workflow surfaced here
|