@intutic/shared-types 1.10.0 → 1.10.1
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 +1 -1
- package/dist/anomaly.d.ts +11 -0
- package/dist/anomaly.d.ts.map +1 -1
- package/dist/api-contracts.d.ts +97 -9
- package/dist/api-contracts.d.ts.map +1 -1
- package/dist/api-contracts.js +9 -0
- package/dist/api-contracts.js.map +1 -1
- package/dist/auth.d.ts +157 -1
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +39 -1
- package/dist/auth.js.map +1 -1
- package/dist/billing.d.ts +2 -99
- package/dist/billing.d.ts.map +1 -1
- package/dist/billing.js +2 -17
- package/dist/billing.js.map +1 -1
- package/dist/enums.d.ts +341 -4
- package/dist/enums.d.ts.map +1 -1
- package/dist/enums.js +369 -6
- package/dist/enums.js.map +1 -1
- package/dist/errors.d.ts +20 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +20 -1
- package/dist/errors.js.map +1 -1
- package/dist/finops.d.ts +97 -1
- package/dist/finops.d.ts.map +1 -1
- package/dist/governanceCoverage.d.ts +82 -0
- package/dist/governanceCoverage.d.ts.map +1 -0
- package/dist/governanceCoverage.js +72 -0
- package/dist/governanceCoverage.js.map +1 -0
- package/dist/guardrailIr.d.ts +287 -0
- package/dist/guardrailIr.d.ts.map +1 -0
- package/dist/guardrailIr.js +301 -0
- package/dist/guardrailIr.js.map +1 -0
- package/dist/guardrailRender.d.ts +154 -0
- package/dist/guardrailRender.d.ts.map +1 -0
- package/dist/guardrailRender.js +440 -0
- package/dist/guardrailRender.js.map +1 -0
- package/dist/identity.d.ts +75 -0
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +5 -1
- package/dist/identity.js.map +1 -1
- package/dist/index.d.ts +34 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +124 -2
- package/dist/index.js.map +1 -1
- package/dist/intelligence.d.ts +37 -11
- package/dist/intelligence.d.ts.map +1 -1
- package/dist/intelligence.js.map +1 -1
- package/dist/modelCatalog.d.ts +89 -0
- package/dist/modelCatalog.d.ts.map +1 -0
- package/dist/modelCatalog.generated.d.ts +7204 -0
- package/dist/modelCatalog.generated.d.ts.map +1 -0
- package/dist/modelCatalog.generated.js +576 -0
- package/dist/modelCatalog.generated.js.map +1 -0
- package/dist/modelCatalog.js +112 -0
- package/dist/modelCatalog.js.map +1 -0
- package/dist/notifications.d.ts +134 -2
- package/dist/notifications.d.ts.map +1 -1
- package/dist/observability.d.ts +4 -0
- package/dist/observability.d.ts.map +1 -1
- package/dist/policyGuardrails.d.ts +433 -0
- package/dist/policyGuardrails.d.ts.map +1 -0
- package/dist/policyGuardrails.js +91 -0
- package/dist/policyGuardrails.js.map +1 -0
- package/dist/posturePresets.d.ts +74 -0
- package/dist/posturePresets.d.ts.map +1 -0
- package/dist/posturePresets.js +139 -0
- package/dist/posturePresets.js.map +1 -0
- package/dist/providerVerification.d.ts +64 -0
- package/dist/providerVerification.d.ts.map +1 -0
- package/dist/providerVerification.js +184 -0
- package/dist/providerVerification.js.map +1 -0
- package/dist/providers.d.ts +93 -0
- package/dist/providers.d.ts.map +1 -0
- package/dist/providers.js +176 -0
- package/dist/providers.js.map +1 -0
- package/dist/rulePredicateDsl.d.ts +101 -0
- package/dist/rulePredicateDsl.d.ts.map +1 -0
- package/dist/rulePredicateDsl.js +263 -0
- package/dist/rulePredicateDsl.js.map +1 -0
- package/dist/rulePredicateEval.d.ts +38 -0
- package/dist/rulePredicateEval.d.ts.map +1 -0
- package/dist/rulePredicateEval.js +124 -0
- package/dist/rulePredicateEval.js.map +1 -0
- package/dist/scriptScan.d.ts +162 -0
- package/dist/scriptScan.d.ts.map +1 -0
- package/dist/scriptScan.js +362 -0
- package/dist/scriptScan.js.map +1 -0
- package/dist/secretPatterns.d.ts +43 -0
- package/dist/secretPatterns.d.ts.map +1 -0
- package/dist/secretPatterns.js +73 -0
- package/dist/secretPatterns.js.map +1 -0
- package/dist/skillScan.d.ts +166 -0
- package/dist/skillScan.d.ts.map +1 -0
- package/dist/skillScan.js +398 -0
- package/dist/skillScan.js.map +1 -0
- package/dist/sop.d.ts +188 -9
- package/dist/sop.d.ts.map +1 -1
- package/dist/sop.js +54 -2
- package/dist/sop.js.map +1 -1
- package/dist/sourceProviders.d.ts +41 -0
- package/dist/sourceProviders.d.ts.map +1 -0
- package/dist/sourceProviders.js +48 -0
- package/dist/sourceProviders.js.map +1 -0
- package/dist/sync.d.ts +98 -8
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js.map +1 -1
- package/dist/toon.d.ts +80 -0
- package/dist/toon.d.ts.map +1 -0
- package/dist/toon.js +278 -0
- package/dist/toon.js.map +1 -0
- package/dist/usage.d.ts +23 -0
- package/dist/usage.d.ts.map +1 -1
- package/dist/wasmHost.d.ts +58 -0
- package/dist/wasmHost.d.ts.map +1 -0
- package/dist/wasmHost.js +80 -0
- package/dist/wasmHost.js.map +1 -0
- package/dist/workspaceSettings.d.ts +463 -21
- package/dist/workspaceSettings.d.ts.map +1 -1
- package/dist/workspaceSettings.js +86 -1
- package/dist/workspaceSettings.js.map +1 -1
- package/package.json +4 -3
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Guardrail IR — the only thing a policy compiler may say (LLD #71).
|
|
4
|
+
*
|
|
5
|
+
* An LLM reading corporate policy prose is allowed to propose exactly two
|
|
6
|
+
* things: a verbatim quote anchored to a passage it was shown, and a clause in
|
|
7
|
+
* this closed IR. Everything after that is deterministic code: the validator
|
|
8
|
+
* (`services/control-plane/src/lib/guardrailValidator.ts`) checks the quote by
|
|
9
|
+
* containment and the IR against the grammar the proxy and the harness gates
|
|
10
|
+
* already enforce, the renderers in `./guardrailRender.ts` turn it into the
|
|
11
|
+
* exact bytes those enforcers read, and cross-language parity fixtures prove
|
|
12
|
+
* the renderers and the Rust / gate-script parsers agree.
|
|
13
|
+
*
|
|
14
|
+
* The grammar is a subset of what a human may author, on purpose:
|
|
15
|
+
*
|
|
16
|
+
* - `hook_rule` — a per-call condition on a tool and its arguments, enforced
|
|
17
|
+
* by the sync daemon's emitted harness gate scripts. Regexes are never model
|
|
18
|
+
* output: the tool pattern is rendered from literal tool tokens and the
|
|
19
|
+
* argument pattern from literal substrings (`argContains` / `argNotContains`),
|
|
20
|
+
* escaped and composed as lookaheads — the dialect JS `RegExp` and Python
|
|
21
|
+
* `re` share, so the bash gates' `python3` clause and the JS gates agree.
|
|
22
|
+
* - the six union-safe SOP front-matter keys the Rust proxy enforces
|
|
23
|
+
* (`deny_tools`, `review_before`, `requires_before`, `forbid_after`,
|
|
24
|
+
* `max_calls`, `forbid_with`). `~>` adjacency is not offered; `->` only.
|
|
25
|
+
* - `wasm_predicate` — the existing closed predicate DSL, verdict 3 (reask)
|
|
26
|
+
* only. A generated rule can never originate a block.
|
|
27
|
+
* - `none` — "this passage contains no enforceable rule", so the corpus can
|
|
28
|
+
* measure over-generation.
|
|
29
|
+
*
|
|
30
|
+
* Deliberately absent: the three allowlist keys (`allow_harnesses`,
|
|
31
|
+
* `plan_steps`, `scope_paths` — intersection-composed, empty-means-unrestricted;
|
|
32
|
+
* a generated allowlist can silently deny everything), raw regexes, raw
|
|
33
|
+
* AssemblyScript, `BLOCK:` titles, DLP patterns, SSL graphs, verdict 1, OR.
|
|
34
|
+
*
|
|
35
|
+
* Structural impossibilities match the Rust parser's own refusals: a token with
|
|
36
|
+
* whitespace (a shell command) cannot exist, a `forbid_with` taint is an enum,
|
|
37
|
+
* and an ordering rule is one pair.
|
|
38
|
+
*
|
|
39
|
+
* @module
|
|
40
|
+
*/
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.FRONT_MATTER_KINDS = exports.IR_KINDS = exports.GuardrailIrSchema = exports.MAX_CALLS_LIMIT = exports.MAX_RATIONALE_CHARS = exports.MAX_TITLE_CHARS = exports.MAX_ROLES = exports.MAX_LITERAL_CHARS = exports.MAX_LITERALS = exports.MAX_LIST_TOKENS = exports.MAX_HOOK_TOOLS = exports.TOOL_TOKEN_RE = exports.ACTION_TOKENS = void 0;
|
|
43
|
+
exports.isActionToken = isActionToken;
|
|
44
|
+
exports.isFrontMatterIr = isFrontMatterIr;
|
|
45
|
+
exports.validateGuardrailIr = validateGuardrailIr;
|
|
46
|
+
exports.canonicalizeIr = canonicalizeIr;
|
|
47
|
+
exports.irTokens = irTokens;
|
|
48
|
+
const zod_1 = require("zod");
|
|
49
|
+
const rulePredicateDsl_js_1 = require("./rulePredicateDsl.js");
|
|
50
|
+
/**
|
|
51
|
+
* The eight `action:` tokens the proxy's classifier synthesises from tool
|
|
52
|
+
* calls. Moved here from `services/control-plane/src/services/learnedHoldService.ts`
|
|
53
|
+
* so the IR, the validator and the hold miner read one list; that file
|
|
54
|
+
* re-exports it. A token outside this set and outside the observed tool names
|
|
55
|
+
* compiles into a control that can never fire.
|
|
56
|
+
*/
|
|
57
|
+
exports.ACTION_TOKENS = [
|
|
58
|
+
'action:deploy',
|
|
59
|
+
'action:publish',
|
|
60
|
+
'action:release',
|
|
61
|
+
'action:db_write',
|
|
62
|
+
'action:secret_read',
|
|
63
|
+
'action:http_post',
|
|
64
|
+
'action:pii_export',
|
|
65
|
+
'action:run_tests',
|
|
66
|
+
];
|
|
67
|
+
function isActionToken(value) {
|
|
68
|
+
return exports.ACTION_TOKENS.includes(value);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* A tool name the harness could plausibly call: `Bash`, `run_command`,
|
|
72
|
+
* `mcp__github__create_issue`, `developer__shell`. No whitespace, so a shell
|
|
73
|
+
* command can never be mistaken for a tool (sops.rs `parse_ordering` refuses
|
|
74
|
+
* the same shape for the same reason). `.`, `:` and `-` are allowed because
|
|
75
|
+
* namespaced harness tools carry them.
|
|
76
|
+
*/
|
|
77
|
+
exports.TOOL_TOKEN_RE = /^[A-Za-z][A-Za-z0-9_.:-]{0,63}$/;
|
|
78
|
+
exports.MAX_HOOK_TOOLS = 8;
|
|
79
|
+
exports.MAX_LIST_TOKENS = 16;
|
|
80
|
+
exports.MAX_LITERALS = 4;
|
|
81
|
+
exports.MAX_LITERAL_CHARS = 64;
|
|
82
|
+
exports.MAX_ROLES = 8;
|
|
83
|
+
exports.MAX_TITLE_CHARS = 80;
|
|
84
|
+
exports.MAX_RATIONALE_CHARS = 480;
|
|
85
|
+
exports.MAX_CALLS_LIMIT = 1000;
|
|
86
|
+
const Token = zod_1.z
|
|
87
|
+
.string()
|
|
88
|
+
.min(1)
|
|
89
|
+
.max(64)
|
|
90
|
+
.refine((v) => isActionToken(v) || exports.TOOL_TOKEN_RE.test(v), {
|
|
91
|
+
message: 'a token is a tool name (`Bash`, `mcp__github__create_issue`) or one of the eight `action:` tokens — never a command',
|
|
92
|
+
});
|
|
93
|
+
/**
|
|
94
|
+
* A literal substring of the serialised tool input. No tab or newline (the
|
|
95
|
+
* `.rules` snapshot is line- and tab-delimited), and no `"` or `\` — those
|
|
96
|
+
* are JSON-escaped in the haystack the gates match against, so a literal
|
|
97
|
+
* containing them could never match the bytes it was written for.
|
|
98
|
+
*/
|
|
99
|
+
const Literal = zod_1.z
|
|
100
|
+
.string()
|
|
101
|
+
.min(1)
|
|
102
|
+
.max(exports.MAX_LITERAL_CHARS)
|
|
103
|
+
.refine((v) => !/[\t\r\n"\\]/.test(v), {
|
|
104
|
+
message: 'a literal may not contain a tab, newline, double quote or backslash',
|
|
105
|
+
});
|
|
106
|
+
const Roles = zod_1.z
|
|
107
|
+
.array(zod_1.z.string().regex(/^[a-z][a-z0-9_-]{0,31}$/, 'a role is lower-case: `deployer`, `reviewer`'))
|
|
108
|
+
.max(exports.MAX_ROLES)
|
|
109
|
+
.optional();
|
|
110
|
+
const Title = zod_1.z.string().min(1).max(exports.MAX_TITLE_CHARS);
|
|
111
|
+
const Rationale = zod_1.z.string().max(exports.MAX_RATIONALE_CHARS);
|
|
112
|
+
const HookRuleSchema = zod_1.z
|
|
113
|
+
.object({
|
|
114
|
+
kind: zod_1.z.literal('hook_rule'),
|
|
115
|
+
title: Title,
|
|
116
|
+
tools: zod_1.z.array(Token).min(1).max(exports.MAX_HOOK_TOOLS),
|
|
117
|
+
argContains: zod_1.z.array(Literal).max(exports.MAX_LITERALS).optional(),
|
|
118
|
+
argNotContains: zod_1.z.array(Literal).max(exports.MAX_LITERALS).optional(),
|
|
119
|
+
roles: Roles,
|
|
120
|
+
})
|
|
121
|
+
.strict();
|
|
122
|
+
const DenyToolsSchema = zod_1.z
|
|
123
|
+
.object({ kind: zod_1.z.literal('deny_tools'), tools: zod_1.z.array(Token).min(1).max(exports.MAX_LIST_TOKENS), roles: Roles })
|
|
124
|
+
.strict();
|
|
125
|
+
const ReviewBeforeSchema = zod_1.z
|
|
126
|
+
.object({ kind: zod_1.z.literal('review_before'), tokens: zod_1.z.array(Token).min(1).max(exports.MAX_LIST_TOKENS), roles: Roles })
|
|
127
|
+
.strict();
|
|
128
|
+
const orderingShape = {
|
|
129
|
+
first: Token,
|
|
130
|
+
then: Token,
|
|
131
|
+
roles: Roles,
|
|
132
|
+
};
|
|
133
|
+
// Discriminated-union members must be plain objects, so the two cross-field
|
|
134
|
+
// rules (ordering tokens differ; a wasm predicate validates) are applied in
|
|
135
|
+
// `validateGuardrailIr` after the shape parse rather than as refinements here.
|
|
136
|
+
const RequiresBeforeSchema = zod_1.z.object({ kind: zod_1.z.literal('requires_before'), ...orderingShape }).strict();
|
|
137
|
+
const ForbidAfterSchema = zod_1.z.object({ kind: zod_1.z.literal('forbid_after'), ...orderingShape }).strict();
|
|
138
|
+
const MaxCallsSchema = zod_1.z
|
|
139
|
+
.object({
|
|
140
|
+
kind: zod_1.z.literal('max_calls'),
|
|
141
|
+
token: Token,
|
|
142
|
+
limit: zod_1.z.number().int().min(1).max(exports.MAX_CALLS_LIMIT),
|
|
143
|
+
roles: Roles,
|
|
144
|
+
})
|
|
145
|
+
.strict();
|
|
146
|
+
const ForbidWithSchema = zod_1.z
|
|
147
|
+
.object({
|
|
148
|
+
kind: zod_1.z.literal('forbid_with'),
|
|
149
|
+
taint: zod_1.z.enum(['secrets()', 'pii()']),
|
|
150
|
+
token: Token,
|
|
151
|
+
roles: Roles,
|
|
152
|
+
})
|
|
153
|
+
.strict();
|
|
154
|
+
const WasmPredicateSchema = zod_1.z
|
|
155
|
+
.object({
|
|
156
|
+
kind: zod_1.z.literal('wasm_predicate'),
|
|
157
|
+
title: Title,
|
|
158
|
+
rationale: Rationale,
|
|
159
|
+
predicate: zod_1.z.unknown(),
|
|
160
|
+
verdict: zod_1.z.literal(3),
|
|
161
|
+
roles: Roles,
|
|
162
|
+
})
|
|
163
|
+
.strict();
|
|
164
|
+
const NoneSchema = zod_1.z.object({ kind: zod_1.z.literal('none'), reason: Rationale }).strict();
|
|
165
|
+
exports.GuardrailIrSchema = zod_1.z.discriminatedUnion('kind', [
|
|
166
|
+
HookRuleSchema,
|
|
167
|
+
DenyToolsSchema,
|
|
168
|
+
ReviewBeforeSchema,
|
|
169
|
+
RequiresBeforeSchema,
|
|
170
|
+
ForbidAfterSchema,
|
|
171
|
+
MaxCallsSchema,
|
|
172
|
+
ForbidWithSchema,
|
|
173
|
+
WasmPredicateSchema,
|
|
174
|
+
NoneSchema,
|
|
175
|
+
]);
|
|
176
|
+
/** Every kind, in one place, for the lint gate (`check-guardrail-ir-keys.js`). */
|
|
177
|
+
exports.IR_KINDS = [
|
|
178
|
+
'hook_rule',
|
|
179
|
+
'deny_tools',
|
|
180
|
+
'review_before',
|
|
181
|
+
'requires_before',
|
|
182
|
+
'forbid_after',
|
|
183
|
+
'max_calls',
|
|
184
|
+
'forbid_with',
|
|
185
|
+
'wasm_predicate',
|
|
186
|
+
'none',
|
|
187
|
+
];
|
|
188
|
+
/** The kinds that render to a SOP front-matter key the Rust proxy reads. */
|
|
189
|
+
exports.FRONT_MATTER_KINDS = [
|
|
190
|
+
'deny_tools',
|
|
191
|
+
'review_before',
|
|
192
|
+
'requires_before',
|
|
193
|
+
'forbid_after',
|
|
194
|
+
'max_calls',
|
|
195
|
+
'forbid_with',
|
|
196
|
+
];
|
|
197
|
+
function isFrontMatterIr(ir) {
|
|
198
|
+
return exports.FRONT_MATTER_KINDS.includes(ir.kind);
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Parse an untrusted value into the IR, or say why it is not one. Never
|
|
202
|
+
* throws. This — not `GuardrailIrSchema.parse` — is the entry point: the
|
|
203
|
+
* shape parse cannot express "the two ordering tokens differ" or "the wasm
|
|
204
|
+
* predicate is in the closed DSL", so both are checked here.
|
|
205
|
+
*/
|
|
206
|
+
function validateGuardrailIr(value) {
|
|
207
|
+
const parsed = exports.GuardrailIrSchema.safeParse(value);
|
|
208
|
+
if (!parsed.success) {
|
|
209
|
+
const first = parsed.error.issues[0];
|
|
210
|
+
const where = first?.path?.length ? `${first.path.join('.')}: ` : '';
|
|
211
|
+
return { ok: false, reason: `${where}${first?.message ?? 'not a guardrail IR'}` };
|
|
212
|
+
}
|
|
213
|
+
const ir = parsed.data;
|
|
214
|
+
if ((ir.kind === 'requires_before' || ir.kind === 'forbid_after') && ir.first === ir.then) {
|
|
215
|
+
return { ok: false, reason: `${ir.kind}: an ordering rule needs two different tokens` };
|
|
216
|
+
}
|
|
217
|
+
if (ir.kind === 'wasm_predicate') {
|
|
218
|
+
try {
|
|
219
|
+
(0, rulePredicateDsl_js_1.validatePredicate)(ir.predicate);
|
|
220
|
+
}
|
|
221
|
+
catch (err) {
|
|
222
|
+
return { ok: false, reason: `predicate: ${err instanceof Error ? err.message : String(err)}` };
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return { ok: true, ir };
|
|
226
|
+
}
|
|
227
|
+
function uniqueSorted(values) {
|
|
228
|
+
return [...new Set(values)].sort();
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* The identity of a control, as a stable string.
|
|
232
|
+
*
|
|
233
|
+
* Two proposals that name the same control from the same passage are one
|
|
234
|
+
* proposal — `policy_clauses` is unique on `(passage_hash, ir_canonical)` —
|
|
235
|
+
* so the title and rationale, which change nothing about what is enforced,
|
|
236
|
+
* are not part of it. Lists are sorted and deduplicated; roles are lower-case
|
|
237
|
+
* (the proxy lowercases them too); tool tokens keep their case (the proxy
|
|
238
|
+
* matches `Bash` case-sensitively).
|
|
239
|
+
*/
|
|
240
|
+
function canonicalizeIr(ir) {
|
|
241
|
+
const roles = ir.kind === 'none' ? undefined : ir.roles && ir.roles.length ? uniqueSorted(ir.roles.map((r) => r.toLowerCase())) : undefined;
|
|
242
|
+
let core;
|
|
243
|
+
switch (ir.kind) {
|
|
244
|
+
case 'hook_rule':
|
|
245
|
+
core = {
|
|
246
|
+
tools: uniqueSorted(ir.tools),
|
|
247
|
+
argContains: uniqueSorted(ir.argContains ?? []),
|
|
248
|
+
argNotContains: uniqueSorted(ir.argNotContains ?? []),
|
|
249
|
+
};
|
|
250
|
+
break;
|
|
251
|
+
case 'deny_tools':
|
|
252
|
+
core = { tools: uniqueSorted(ir.tools) };
|
|
253
|
+
break;
|
|
254
|
+
case 'review_before':
|
|
255
|
+
core = { tokens: uniqueSorted(ir.tokens) };
|
|
256
|
+
break;
|
|
257
|
+
case 'requires_before':
|
|
258
|
+
case 'forbid_after':
|
|
259
|
+
core = { first: ir.first, then: ir.then };
|
|
260
|
+
break;
|
|
261
|
+
case 'max_calls':
|
|
262
|
+
core = { token: ir.token, limit: ir.limit };
|
|
263
|
+
break;
|
|
264
|
+
case 'forbid_with':
|
|
265
|
+
core = { taint: ir.taint, token: ir.token };
|
|
266
|
+
break;
|
|
267
|
+
case 'wasm_predicate':
|
|
268
|
+
core = { predicate: ir.predicate, verdict: ir.verdict };
|
|
269
|
+
break;
|
|
270
|
+
case 'none':
|
|
271
|
+
core = {};
|
|
272
|
+
break;
|
|
273
|
+
}
|
|
274
|
+
return JSON.stringify({ kind: ir.kind, ...core, ...(roles ? { roles } : {}) }, sortedKeys);
|
|
275
|
+
}
|
|
276
|
+
function sortedKeys(_key, value) {
|
|
277
|
+
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
278
|
+
return Object.fromEntries(Object.entries(value).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0)));
|
|
279
|
+
}
|
|
280
|
+
return value;
|
|
281
|
+
}
|
|
282
|
+
/** Every token (tool or action) an IR names — the set a validator must find in the cited passage. */
|
|
283
|
+
function irTokens(ir) {
|
|
284
|
+
switch (ir.kind) {
|
|
285
|
+
case 'hook_rule':
|
|
286
|
+
case 'deny_tools':
|
|
287
|
+
return [...ir.tools];
|
|
288
|
+
case 'review_before':
|
|
289
|
+
return [...ir.tokens];
|
|
290
|
+
case 'requires_before':
|
|
291
|
+
case 'forbid_after':
|
|
292
|
+
return [ir.first, ir.then];
|
|
293
|
+
case 'max_calls':
|
|
294
|
+
case 'forbid_with':
|
|
295
|
+
return [ir.token];
|
|
296
|
+
case 'wasm_predicate':
|
|
297
|
+
case 'none':
|
|
298
|
+
return [];
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
//# sourceMappingURL=guardrailIr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guardrailIr.js","sourceRoot":"","sources":["../src/guardrailIr.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Guardrail renderers and their parsers (LLD #71).
|
|
3
|
+
*
|
|
4
|
+
* Two artifacts come out of the IR, and both are read by code this package
|
|
5
|
+
* does not own:
|
|
6
|
+
*
|
|
7
|
+
* - **Hook rules** become `{toolPattern, argPattern, reason}` — the shape
|
|
8
|
+
* `services/sync-daemon/src/lib/policySnapshot.ts` turns into a
|
|
9
|
+
* `policy-snapshot.rules` line and the emitted gate scripts match with
|
|
10
|
+
* `new RegExp(toolPattern)` / `new RegExp(argPattern)` against the tool name
|
|
11
|
+
* and `JSON.stringify(tool_input)`. The tool pattern must be portable ERE
|
|
12
|
+
* (the daemon's `assertPortableEre` refuses `\s`, `(?`, anchors, …); the
|
|
13
|
+
* argument pattern is exempt from that but must mean the same thing to JS
|
|
14
|
+
* `RegExp` and Python `re`, because the bash gates delegate it to `python3`.
|
|
15
|
+
* - **Front-matter lines** become the YAML-ish block `packages/proxy/src/sops.rs`
|
|
16
|
+
* parses with `parse_front_matter`. `parseFrontMatterEnforcing` below is a
|
|
17
|
+
* line-for-line mirror of that parser's split semantics so a render can be
|
|
18
|
+
* re-parsed and compared to the IR it came from — and so the cargo fixture
|
|
19
|
+
* test can prove the Rust side reads the same fields.
|
|
20
|
+
*
|
|
21
|
+
* Every renderer is byte-stable: the same IR always yields the same bytes, so
|
|
22
|
+
* a rendered artifact is content-addressable and a reviewer diffing two
|
|
23
|
+
* versions sees only what changed.
|
|
24
|
+
*
|
|
25
|
+
* @module
|
|
26
|
+
*/
|
|
27
|
+
import { type GuardrailIr, type HookRuleIr, type FrontMatterIr } from './guardrailIr.js';
|
|
28
|
+
export interface HookRuleCitation {
|
|
29
|
+
/** Verbatim quote from the cited passage. */
|
|
30
|
+
quote: string;
|
|
31
|
+
/** Deep link to the upstream document, or null when the provider has none. */
|
|
32
|
+
sourceUrl: string | null;
|
|
33
|
+
}
|
|
34
|
+
export interface RenderedHookRule {
|
|
35
|
+
toolPattern: string;
|
|
36
|
+
argPattern?: string;
|
|
37
|
+
reason: string;
|
|
38
|
+
}
|
|
39
|
+
/** Longest reason the gates print and the hook-events route accepts with margin (its cap is 512). */
|
|
40
|
+
export declare const MAX_REASON_CHARS = 300;
|
|
41
|
+
/** Longest quote embedded in a reason; truncated with an ellipsis beyond it. */
|
|
42
|
+
export declare const MAX_QUOTE_IN_REASON = 200;
|
|
43
|
+
/**
|
|
44
|
+
* Escape a literal for a regex that both JS `RegExp` (no flags) and Python
|
|
45
|
+
* `re` compile identically: every non-alphanumeric ASCII character is
|
|
46
|
+
* backslash-escaped, alphanumerics never are (`\d`-style escapes would mean
|
|
47
|
+
* something else). Non-ASCII characters are left alone — neither engine
|
|
48
|
+
* treats them as syntax.
|
|
49
|
+
*/
|
|
50
|
+
export declare function escapeRegexLiteral(literal: string): string;
|
|
51
|
+
/**
|
|
52
|
+
* The tool half of a hook rule. Tokens are alternated inside one group; the
|
|
53
|
+
* only character a token may contain that is regex syntax is `.`, and it is
|
|
54
|
+
* escaped. Anchored, because two of the three consumers (`matchSopRule` and
|
|
55
|
+
* the MCP proxy's `matchRule`) test the pattern unanchored against the bare
|
|
56
|
+
* tool name — `Bash` would match `BashHistory` there. The daemon strips the
|
|
57
|
+
* anchors and wraps the pattern for whole-token matching itself, so all three
|
|
58
|
+
* read it as "exactly this tool".
|
|
59
|
+
*/
|
|
60
|
+
export declare function renderToolPattern(tools: readonly string[]): string;
|
|
61
|
+
/**
|
|
62
|
+
* The argument half: one positive lookahead per required literal, one
|
|
63
|
+
* negative lookahead per forbidden literal, over the whole serialised input.
|
|
64
|
+
* `[\s\S]*` rather than `.*` so a multi-line argument (a heredoc in a Bash
|
|
65
|
+
* command) is still searched end to end. Undefined when there is nothing to
|
|
66
|
+
* say about the arguments.
|
|
67
|
+
*/
|
|
68
|
+
export declare function renderArgPattern(contains?: readonly string[], notContains?: readonly string[]): string | undefined;
|
|
69
|
+
/**
|
|
70
|
+
* A whole SOP file around rendered front-matter lines: the shape the control
|
|
71
|
+
* plane projects a front-matter guardrail into `GET /api/v1/workspace/
|
|
72
|
+
* sops-policy` with, and the shape the parity fixtures under
|
|
73
|
+
* `fixtures/guardrail-ir/` are generated in — one function, so the cargo
|
|
74
|
+
* fixture test covers the projection byte for byte. `source:` and `cite:`
|
|
75
|
+
* are informational lines the proxy ignores; `mode: shadow` is the one it
|
|
76
|
+
* reads.
|
|
77
|
+
*/
|
|
78
|
+
export interface GuardrailSopFileInput {
|
|
79
|
+
/** The enforcing lines, as `renderFrontMatterLines` produced them. */
|
|
80
|
+
lines: string;
|
|
81
|
+
title: string;
|
|
82
|
+
/** Markdown body under the H1; the cited passage usually goes here as a quote. */
|
|
83
|
+
body: string;
|
|
84
|
+
sourceUrl?: string | null;
|
|
85
|
+
/** The passage hash the rule stands on. */
|
|
86
|
+
cite?: string | null;
|
|
87
|
+
shadow: boolean;
|
|
88
|
+
}
|
|
89
|
+
export declare function renderGuardrailSopFile(input: GuardrailSopFileInput): string;
|
|
90
|
+
/** Tabs and newlines would break the `.rules` projection; collapse them. */
|
|
91
|
+
export declare function scrubReason(text: string): string;
|
|
92
|
+
/**
|
|
93
|
+
* The reason a developer sees on stderr when the rule fires:
|
|
94
|
+
* `<title> — policy: "<quote>" (<url>)`. The citation travels into the block
|
|
95
|
+
* message itself, which is the whole point of a grounded guardrail.
|
|
96
|
+
*/
|
|
97
|
+
export declare function renderHookReason(title: string, citation: HookRuleCitation): string;
|
|
98
|
+
export declare function renderHookRule(ir: HookRuleIr, citation: HookRuleCitation): RenderedHookRule;
|
|
99
|
+
/**
|
|
100
|
+
* The front-matter lines for a set of IRs — no fences, no `mode:`; the
|
|
101
|
+
* projection that ships them adds those. One line per rule for the pair
|
|
102
|
+
* keys (the Rust parser splits `requires_before:`/`forbid_after:`/`max_calls:`
|
|
103
|
+
* on commas but `forbid_with:` deliberately not, so one-per-line is the only
|
|
104
|
+
* shape that is right for all four), and one comma-joined line for the list
|
|
105
|
+
* keys. Deterministic: sorted, deduplicated, fixed key order.
|
|
106
|
+
*/
|
|
107
|
+
export declare function renderFrontMatterLines(irs: readonly FrontMatterIr[]): string;
|
|
108
|
+
export interface ParsedFrontMatter {
|
|
109
|
+
roles: string[];
|
|
110
|
+
allowHarnesses: string[];
|
|
111
|
+
denyTools: string[];
|
|
112
|
+
planSteps: string[];
|
|
113
|
+
scopePaths: string[];
|
|
114
|
+
reviewBefore: string[];
|
|
115
|
+
/** `[first, then, adjacent]` — `adjacent` is true for `~>`. */
|
|
116
|
+
requiresBefore: Array<[string, string, boolean]>;
|
|
117
|
+
forbidAfter: Array<[string, string, boolean]>;
|
|
118
|
+
maxCalls: Array<[string, number]>;
|
|
119
|
+
forbidWith: Array<[string, string]>;
|
|
120
|
+
mode: 'shadow' | 'enforce';
|
|
121
|
+
/** Rules that failed to parse, in the Rust parser's own wording. */
|
|
122
|
+
errors: string[];
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Split a document into the text between its `---` fences and the body,
|
|
126
|
+
* with the Rust parser's fallback contract: no fence, or an unterminated
|
|
127
|
+
* one, means the whole document is body and there is no front matter.
|
|
128
|
+
*/
|
|
129
|
+
export declare function splitFrontMatter(raw: string): {
|
|
130
|
+
front: string;
|
|
131
|
+
body: string;
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* Parse the text between the fences exactly as `parse_front_matter` in
|
|
135
|
+
* sops.rs does: a key is a line prefix, list keys split on commas and strip
|
|
136
|
+
* quotes/brackets, `requires_before`/`forbid_after` parse `A -> B`,
|
|
137
|
+
* `max_calls` parses `A <= N` (comma-split), `forbid_with` parses
|
|
138
|
+
* `taint(), token` (never comma-split), unknown keys are ignored, and an
|
|
139
|
+
* unparseable rule is reported rather than dropped.
|
|
140
|
+
*/
|
|
141
|
+
export declare function parseFrontMatterEnforcing(front: string): ParsedFrontMatter;
|
|
142
|
+
/** Mirror of `is_enforceable`: does this front matter declare anything the proxy can act on? */
|
|
143
|
+
export declare function isEnforceableFrontMatter(fm: ParsedFrontMatter): boolean;
|
|
144
|
+
/**
|
|
145
|
+
* The IRs a parsed front matter expresses — the inverse of
|
|
146
|
+
* {@link renderFrontMatterLines} for the six generated keys. Allowlist keys
|
|
147
|
+
* (`allow_harnesses`, `plan_steps`, `scope_paths`) have no IR and are not
|
|
148
|
+
* returned; adjacency (`~>`) rules are returned as plain ordering rules,
|
|
149
|
+
* which is the only shape the IR offers.
|
|
150
|
+
*/
|
|
151
|
+
export declare function frontMatterToIrs(fm: ParsedFrontMatter): FrontMatterIr[];
|
|
152
|
+
/** Render a mixed IR list's front-matter half; non-front-matter kinds are ignored. */
|
|
153
|
+
export declare function frontMatterIrsOf(irs: readonly GuardrailIr[]): FrontMatterIr[];
|
|
154
|
+
//# sourceMappingURL=guardrailRender.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guardrailRender.d.ts","sourceRoot":"","sources":["../src/guardrailRender.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,aAAa,EAEnB,MAAM,kBAAkB,CAAA;AAIzB,MAAM,WAAW,gBAAgB;IAC/B,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAA;IACb,8EAA8E;IAC9E,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,qGAAqG;AACrG,eAAO,MAAM,gBAAgB,MAAM,CAAA;AAEnC,gFAAgF;AAChF,eAAO,MAAM,mBAAmB,MAAM,CAAA;AAEtC;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAGlE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,GAAE,SAAS,MAAM,EAAO,EAAE,WAAW,GAAE,SAAS,MAAM,EAAO,GAAG,MAAM,GAAG,SAAS,CAc1H;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,qBAAqB;IACpC,sEAAsE;IACtE,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,kFAAkF;IAClF,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,MAAM,EAAE,OAAO,CAAA;CAChB;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,qBAAqB,GAAG,MAAM,CAM3E;AAED,4EAA4E;AAC5E,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,GAAG,MAAM,CAQlF;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,gBAAgB,GAAG,gBAAgB,CAO3F;AAMD;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,SAAS,aAAa,EAAE,GAAG,MAAM,CA+D5E;AAID,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,+DAA+D;IAC/D,cAAc,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;IAChD,WAAW,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;IAC7C,QAAQ,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IACjC,UAAU,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IACnC,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAA;IAC1B,oEAAoE;IACpE,MAAM,EAAE,MAAM,EAAE,CAAA;CACjB;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAO7E;AA8ID;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,iBAAiB,CAmB1E;AAED,gGAAgG;AAChG,wBAAgB,wBAAwB,CAAC,EAAE,EAAE,iBAAiB,GAAG,OAAO,CAYvE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,iBAAiB,GAAG,aAAa,EAAE,CAYvE;AAED,sFAAsF;AACtF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,SAAS,WAAW,EAAE,GAAG,aAAa,EAAE,CAE7E"}
|