@armoriq/policy-ir 0.1.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.
@@ -0,0 +1,969 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/vectors.ts
21
+ var vectors_exports = {};
22
+ __export(vectors_exports, {
23
+ vectors: () => vectors
24
+ });
25
+ module.exports = __toCommonJS(vectors_exports);
26
+
27
+ // vectors/canonical.json
28
+ var canonical_default = [
29
+ {
30
+ name: "empty object",
31
+ input: {},
32
+ canonical: "{}"
33
+ },
34
+ {
35
+ name: "keys sorted bytewise",
36
+ input: {
37
+ "9": 6,
38
+ "10": 5,
39
+ b: 1,
40
+ a: 2,
41
+ B: 3,
42
+ _: 4
43
+ },
44
+ canonical: '{"10":5,"9":6,"B":3,"_":4,"a":2,"b":1}'
45
+ },
46
+ {
47
+ name: "nested and arrays keep order",
48
+ input: {
49
+ z: [
50
+ 3,
51
+ 1,
52
+ {
53
+ y: null,
54
+ x: [
55
+ true,
56
+ false
57
+ ]
58
+ }
59
+ ],
60
+ a: "x"
61
+ },
62
+ canonical: '{"a":"x","z":[3,1,{"x":[true,false],"y":null}]}'
63
+ },
64
+ {
65
+ name: "undefined members dropped, null kept",
66
+ input: {
67
+ b: null,
68
+ c: 0
69
+ },
70
+ canonical: '{"b":null,"c":0}'
71
+ },
72
+ {
73
+ name: "ascii escapes",
74
+ input: {
75
+ s: 'quote " backslash \\ tab newline \n \xE9 \u2713 \u{1F600}'
76
+ },
77
+ canonical: '{"s":"quote \\" backslash \\\\ tab \\t newline \\n \\u00e9 \\u2713 \\ud83d\\ude00"}'
78
+ },
79
+ {
80
+ name: "numbers",
81
+ input: {
82
+ i: 42,
83
+ f: 0.5,
84
+ neg: -1,
85
+ exp: 1e21,
86
+ small: 1e-7,
87
+ zero: 0,
88
+ negzero: 0
89
+ },
90
+ canonical: '{"exp":1e+21,"f":0.5,"i":42,"neg":-1,"negzero":0,"small":1e-7,"zero":0}'
91
+ },
92
+ {
93
+ name: "unicode key",
94
+ input: {
95
+ \u043A\u043B\u044E\u0447: 1,
96
+ key: 2
97
+ },
98
+ canonical: '{"key":2,"\\u043a\\u043b\\u044e\\u0447":1}'
99
+ }
100
+ ];
101
+
102
+ // vectors/hash.json
103
+ var hash_default = [
104
+ {
105
+ name: "hold on create_payment above 5000",
106
+ document: {
107
+ schemaVersion: "armor.policy.v2",
108
+ policyId: "11111111-1111-4111-8111-111111111111",
109
+ target: {
110
+ agent: "d5c85519-3b8e-4f1e-9d2a-000000000001",
111
+ mcpServers: [
112
+ "github"
113
+ ]
114
+ },
115
+ layer: "agent",
116
+ defaults: {
117
+ tools: "hold",
118
+ network: "block",
119
+ files: "allow",
120
+ skills: "allow"
121
+ },
122
+ capture: {
123
+ arguments: true,
124
+ redact: [
125
+ "*token*"
126
+ ],
127
+ maxBytesPerCall: 16384,
128
+ sample: 1
129
+ },
130
+ expiresAt: "never",
131
+ statements: [
132
+ {
133
+ id: "st-pay-hold",
134
+ subject: null,
135
+ match: {
136
+ tool: "create_payment",
137
+ keyTier: "exact",
138
+ order: 0
139
+ },
140
+ effect: "hold",
141
+ conditions: [
142
+ {
143
+ field: "args.amount",
144
+ op: "gt",
145
+ value: 5e3,
146
+ schemaBinding: {
147
+ schemaHash: "sha256:1111111111111111111111111111111111111111111111111111111111111111"
148
+ }
149
+ }
150
+ ],
151
+ approval: {
152
+ approvers: 2,
153
+ roles: [
154
+ "finance_lead"
155
+ ]
156
+ },
157
+ expiresAt: "never",
158
+ provenance: {
159
+ ruleKey: "create_payment",
160
+ variant: 0,
161
+ source: "yaml",
162
+ layer: "agent"
163
+ }
164
+ },
165
+ {
166
+ id: "st-files-ssh",
167
+ subject: null,
168
+ match: {
169
+ capability: "files"
170
+ },
171
+ effect: "block",
172
+ conditions: [
173
+ {
174
+ field: "path",
175
+ op: "glob",
176
+ value: "~/.ssh/**"
177
+ }
178
+ ],
179
+ expiresAt: "never",
180
+ provenance: {
181
+ ruleKey: "files.deny",
182
+ variant: 0,
183
+ source: "yaml",
184
+ layer: "agent"
185
+ }
186
+ }
187
+ ]
188
+ },
189
+ policyHash: "sha256:007f204da14735e58b74d23a4909ee972d53cc2c8bd293217b71cab3d7b292bb"
190
+ },
191
+ {
192
+ name: "org floor with no statements",
193
+ document: {
194
+ schemaVersion: "armor.policy.v2",
195
+ policyId: "22222222-2222-4222-8222-222222222222",
196
+ target: {
197
+ org: "*"
198
+ },
199
+ layer: "floor",
200
+ defaults: {
201
+ tools: "hold",
202
+ network: "block",
203
+ files: "allow",
204
+ skills: "allow"
205
+ },
206
+ capture: {
207
+ arguments: false,
208
+ redact: [],
209
+ maxBytesPerCall: 0,
210
+ sample: 0
211
+ },
212
+ expiresAt: "2027-01-01T00:00:00Z",
213
+ statements: []
214
+ },
215
+ policyHash: "sha256:02a98fe3c5263f505f72562a87154fc3bd67f561ffb0f264f7fb5b90bd3d65c4"
216
+ }
217
+ ];
218
+
219
+ // vectors/schema-hash-vectors.json
220
+ var schema_hash_vectors_default = {
221
+ _comment: [
222
+ "Golden vectors for the tool-inventory canonicalizer (Tool Inventory PRD T4, armoriq/conmap-auto#968).",
223
+ "Three implementations must agree byte-for-byte: conmap src/tool-inventory/canonical.ts,",
224
+ "armoriq-sdk-customer (python) and armoriq-sdk-customer-ts. conmap is the source of truth;",
225
+ "each SDK keeps a byte-identical copy of this file plus its sha256 in a sibling .sha256, and a",
226
+ "test in each repo asserts the file still hashes to it -- so changing a vector forces all three",
227
+ "copies to move together.",
228
+ "canonicalJson = sorted keys, compact separators, ensure_ascii escaping. This is NOT RFC 8785;",
229
+ "see the header of canonical.ts for why, and vector 5 for the number forms left outside the",
230
+ "agreed set."
231
+ ],
232
+ algorithm: {
233
+ canonicalJson: "sorted keys, no whitespace, ASCII-escaped (json.dumps sort_keys=True separators=(',',':') ensure_ascii=True)",
234
+ schemaHash: "'sha256:' + sha256_hex(canonicalJson(strip description/title only where they are annotation keywords (never as names under properties/patternProperties/$defs/definitions/dependentSchemas or strings in required, never inside enum/const/default/examples values), resolve local #/ $ref)); null when inputSchema is null",
235
+ manifestHash: "'sha256:' + sha256_hex(canonicalJson({name, description|null, annotations|{}, inputSchema|null}))"
236
+ },
237
+ vectors: [
238
+ {
239
+ id: 1,
240
+ name: "key-order-irrelevant",
241
+ note: "Object keys are sorted, so two spellings that differ only in key order produce identical bytes.",
242
+ inputSchema: {
243
+ type: "object",
244
+ required: [
245
+ "b"
246
+ ],
247
+ properties: {
248
+ b: {
249
+ type: "string"
250
+ },
251
+ a: {
252
+ type: "number"
253
+ }
254
+ }
255
+ },
256
+ schemaHash: "sha256:597b8b01f9b5b640dd6856455c6156c631bb3e36768be54f79f21c89392c064d",
257
+ equivalentSpellings: [
258
+ {
259
+ properties: {
260
+ a: {
261
+ type: "number"
262
+ },
263
+ b: {
264
+ type: "string"
265
+ }
266
+ },
267
+ required: [
268
+ "b"
269
+ ],
270
+ type: "object"
271
+ }
272
+ ]
273
+ },
274
+ {
275
+ id: 2,
276
+ name: "nested-description-and-title-stripped",
277
+ note: "description and title are removed wherever they are schema annotation keywords, so prose-only edits never move schemaHash. Equals vector 1.",
278
+ inputSchema: {
279
+ title: "Thing",
280
+ description: "top level prose",
281
+ type: "object",
282
+ required: [
283
+ "b"
284
+ ],
285
+ properties: {
286
+ a: {
287
+ type: "number",
288
+ description: "the a"
289
+ },
290
+ b: {
291
+ title: "B",
292
+ type: "string",
293
+ description: "the b"
294
+ }
295
+ }
296
+ },
297
+ schemaHash: "sha256:597b8b01f9b5b640dd6856455c6156c631bb3e36768be54f79f21c89392c064d",
298
+ equalsVector: 1
299
+ },
300
+ {
301
+ id: 3,
302
+ name: "local-ref-resolved",
303
+ note: "A local #/$defs pointer is inlined before hashing, so spelling a shape out and pointing at it hash the same.",
304
+ inputSchema: {
305
+ type: "object",
306
+ $defs: {
307
+ Id: {
308
+ type: "string",
309
+ pattern: "^[a-z]+$"
310
+ }
311
+ },
312
+ properties: {
313
+ id: {
314
+ $ref: "#/$defs/Id"
315
+ }
316
+ }
317
+ },
318
+ schemaHash: "sha256:ed8f92e2b3119b897b4c3fb2322e4a94aefb4e345b2520c95ef96459ff532073"
319
+ },
320
+ {
321
+ id: 4,
322
+ name: "unicode-including-astral-plane",
323
+ note: "Non-ASCII escapes as \\uXXXX; an astral-plane character (U+1F600, U+1F680) escapes as its UTF-16 surrogate pair, matching Python ensure_ascii and JS charCodeAt iteration. All keys here are ASCII on purpose: JS sorts keys by UTF-16 code unit and Python by code point, which differ for astral-plane KEYS, so those are outside the agreed set.",
324
+ inputSchema: {
325
+ type: "string",
326
+ enum: [
327
+ "caf\xE9",
328
+ "\u65E5\u672C\u8A9E",
329
+ "\u{1F600}"
330
+ ],
331
+ const: "na\xEFve \u{1F680}"
332
+ },
333
+ schemaHash: "sha256:bd1abce15a0b8bcd6e5c0571a22858e1e14d889ed9ffc68fc2c06f4c5c68be40"
334
+ },
335
+ {
336
+ id: 5,
337
+ name: "number-forms",
338
+ note: "Numbers are emitted by the host JSON writer, not RFC 8785. Integers and decimals are distinct canonical bytes.",
339
+ knownDivergence: 'A float-valued integer diverges across languages (Python json.dumps(1.0) -> "1.0", JSON.stringify(1.0) -> "1"), as does -0.0 (Python "-0.0", JS "0"). Neither appears in a real JSON Schema, and neither is in this vector: agreeing on them requires a shared number formatter, which is the RFC 8785 migration, not a patch here.',
340
+ inputSchema: {
341
+ type: "number",
342
+ multipleOf: 1,
343
+ minimum: 0,
344
+ maximum: 10,
345
+ default: 2.5,
346
+ exclusiveMinimum: -1
347
+ },
348
+ schemaHash: "sha256:bcafbb074da1b4c0217c2438646e132ab73398dc1570efd186017abdf21f5029"
349
+ },
350
+ {
351
+ id: 6,
352
+ name: "empty-object-schema",
353
+ note: "An empty schema {} is a real, hashable schema. It is NOT the same fact as 'no schema' (vector 7).",
354
+ inputSchema: {},
355
+ schemaHash: "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a"
356
+ },
357
+ {
358
+ id: 7,
359
+ name: "null-schema-has-no-hash",
360
+ note: "No schema at all: schemaHash is null, never the hash of {} and never the hash of the string 'null'. FR-7 warns on exactly this row.",
361
+ inputSchema: null,
362
+ schemaHash: null,
363
+ manifestDoc: {
364
+ name: "unschemad_tool",
365
+ description: "declared with a name only"
366
+ },
367
+ manifestHash: "sha256:61f5054dde7e535542c2e04a739dc78d1341504f798c7642ab9ad29f1b456bee"
368
+ },
369
+ {
370
+ id: 8,
371
+ name: "array-order-is-significant",
372
+ note: "Canonicalization sorts object keys and never sequences: reordering prefixItems is a different schema.",
373
+ inputSchema: {
374
+ type: "array",
375
+ prefixItems: [
376
+ {
377
+ type: "string"
378
+ },
379
+ {
380
+ type: "number"
381
+ },
382
+ {
383
+ type: "boolean"
384
+ }
385
+ ],
386
+ items: {
387
+ anyOf: [
388
+ {
389
+ type: "null"
390
+ },
391
+ {
392
+ type: "string"
393
+ }
394
+ ]
395
+ }
396
+ },
397
+ schemaHash: "sha256:9dd8bbfb2bc524842d1203e4f914a5743cceaa228fcf328182f4bc9260fb747e"
398
+ },
399
+ {
400
+ id: 9,
401
+ name: "nested-required-arrays",
402
+ note: "required lists nested inside properties survive verbatim, order included, at every depth.",
403
+ inputSchema: {
404
+ type: "object",
405
+ required: [
406
+ "outer"
407
+ ],
408
+ properties: {
409
+ outer: {
410
+ type: "object",
411
+ required: [
412
+ "z",
413
+ "a"
414
+ ],
415
+ properties: {
416
+ z: {
417
+ type: "string"
418
+ },
419
+ a: {
420
+ type: "object",
421
+ required: [
422
+ "q"
423
+ ],
424
+ properties: {
425
+ q: {
426
+ type: "integer"
427
+ }
428
+ }
429
+ }
430
+ }
431
+ }
432
+ }
433
+ },
434
+ schemaHash: "sha256:864f94090821218ef480510c415eaac315715d2f8ee3be1cbc7517594b51ab13"
435
+ },
436
+ {
437
+ id: 10,
438
+ name: "booleans-nulls-and-escaped-strings",
439
+ note: "true/false/null literals, and a string carrying a quote, a backslash, a tab, a newline and a control character.",
440
+ inputSchema: {
441
+ type: "object",
442
+ additionalProperties: false,
443
+ deprecated: true,
444
+ properties: {
445
+ q: {
446
+ type: "string",
447
+ default: 'he said "hi" one\\two\nthree',
448
+ const: null
449
+ }
450
+ }
451
+ },
452
+ schemaHash: "sha256:f5cdf2e3025ce09cb931b6cc918484a14de97a057e9667874593f0a3bc50877c"
453
+ },
454
+ {
455
+ id: 11,
456
+ name: "argument-named-description-is-kept",
457
+ note: "`description` and `title` are stripped only as schema annotation keywords, never as argument names under `properties`, `required`, `patternProperties`, `$defs`, `definitions` or `dependentSchemas`. create_ticket(title, description, priority) must NOT hash like create_ticket(priority). The annotation on `priority` is stripped; the two argument names are kept. `equivalentSpellings` differs only in annotation prose and must hash identically; `distinctSpelling` drops the two arguments and must NOT.",
458
+ inputSchema: {
459
+ type: "object",
460
+ properties: {
461
+ title: {
462
+ type: "string",
463
+ title: "Title",
464
+ description: "Short summary"
465
+ },
466
+ description: {
467
+ type: "string",
468
+ description: "Long form body"
469
+ },
470
+ priority: {
471
+ type: "integer",
472
+ description: "P0-P3"
473
+ }
474
+ },
475
+ required: [
476
+ "title",
477
+ "description"
478
+ ]
479
+ },
480
+ schemaHash: "sha256:996c1f968a21b24a3f171a432a3de33257901beb2d172e3dfa3d345b7e3e6a3c",
481
+ equivalentSpellings: [
482
+ {
483
+ type: "object",
484
+ properties: {
485
+ title: {
486
+ type: "string"
487
+ },
488
+ description: {
489
+ type: "string",
490
+ title: "Body"
491
+ },
492
+ priority: {
493
+ type: "integer"
494
+ }
495
+ },
496
+ required: [
497
+ "title",
498
+ "description"
499
+ ]
500
+ }
501
+ ],
502
+ distinctSpelling: {
503
+ type: "object",
504
+ properties: {
505
+ priority: {
506
+ type: "integer"
507
+ }
508
+ }
509
+ }
510
+ },
511
+ {
512
+ id: 12,
513
+ name: "real-mcp-input-schema",
514
+ note: "A verbatim MCP tools/list inputSchema (GitHub MCP create_issue), prose included, with the manifestHash of the full tool entry.",
515
+ inputSchema: {
516
+ type: "object",
517
+ properties: {
518
+ owner: {
519
+ type: "string",
520
+ description: "Repository owner"
521
+ },
522
+ repo: {
523
+ type: "string",
524
+ description: "Repository name"
525
+ },
526
+ title: {
527
+ type: "string",
528
+ description: "Issue title"
529
+ },
530
+ body: {
531
+ type: "string",
532
+ description: "Issue body content"
533
+ },
534
+ assignees: {
535
+ type: "array",
536
+ items: {
537
+ type: "string"
538
+ },
539
+ description: "Usernames to assign"
540
+ },
541
+ labels: {
542
+ type: "array",
543
+ items: {
544
+ type: "string"
545
+ },
546
+ description: "Labels to apply"
547
+ },
548
+ milestone: {
549
+ type: "number",
550
+ description: "Milestone number"
551
+ }
552
+ },
553
+ required: [
554
+ "owner",
555
+ "repo",
556
+ "title"
557
+ ],
558
+ additionalProperties: false,
559
+ $schema: "http://json-schema.org/draft-07/schema#"
560
+ },
561
+ schemaHash: "sha256:b06130f66f945f4ca2bc4474340c7f934c5e7b10168978fb8f507ecc146c091b",
562
+ manifestDoc: {
563
+ name: "create_issue",
564
+ description: "Create a new issue in a GitHub repository",
565
+ annotations: {
566
+ readOnlyHint: false,
567
+ destructiveHint: false,
568
+ idempotentHint: false
569
+ },
570
+ inputSchema: {
571
+ type: "object",
572
+ properties: {
573
+ owner: {
574
+ type: "string",
575
+ description: "Repository owner"
576
+ },
577
+ repo: {
578
+ type: "string",
579
+ description: "Repository name"
580
+ },
581
+ title: {
582
+ type: "string",
583
+ description: "Issue title"
584
+ },
585
+ body: {
586
+ type: "string",
587
+ description: "Issue body content"
588
+ },
589
+ assignees: {
590
+ type: "array",
591
+ items: {
592
+ type: "string"
593
+ },
594
+ description: "Usernames to assign"
595
+ },
596
+ labels: {
597
+ type: "array",
598
+ items: {
599
+ type: "string"
600
+ },
601
+ description: "Labels to apply"
602
+ },
603
+ milestone: {
604
+ type: "number",
605
+ description: "Milestone number"
606
+ }
607
+ },
608
+ required: [
609
+ "owner",
610
+ "repo",
611
+ "title"
612
+ ],
613
+ additionalProperties: false,
614
+ $schema: "http://json-schema.org/draft-07/schema#"
615
+ }
616
+ },
617
+ manifestHash: "sha256:a0bc53dbf453b8c5860924781ddc912d1b118a64adb3ee4b5089bf599b936113"
618
+ },
619
+ {
620
+ id: 13,
621
+ name: "data-literals-are-not-schemas",
622
+ note: "The values of `enum`, `const`, `default` and `examples` are data, not schema nodes: a `title` or `description` key inside them is part of the value and is kept verbatim. `equivalentSpellings` reorders keys inside the literals only; `distinctSpelling` removes those keys from the literals and must NOT hash equal.",
623
+ inputSchema: {
624
+ type: "object",
625
+ properties: {
626
+ payload: {
627
+ type: "object",
628
+ default: {
629
+ title: "Untitled",
630
+ description: "",
631
+ priority: 2
632
+ },
633
+ examples: [
634
+ {
635
+ title: "First",
636
+ description: "Body"
637
+ }
638
+ ]
639
+ },
640
+ kind: {
641
+ type: "object",
642
+ enum: [
643
+ {
644
+ title: "bug"
645
+ },
646
+ {
647
+ title: "task"
648
+ }
649
+ ],
650
+ const: {
651
+ description: "fixed"
652
+ }
653
+ }
654
+ }
655
+ },
656
+ schemaHash: "sha256:cae41d7dfcc5d51cf9ce1756903979b1fc5754fa8e95a69d9e5bec5df0266dc8",
657
+ equivalentSpellings: [
658
+ {
659
+ properties: {
660
+ kind: {
661
+ const: {
662
+ description: "fixed"
663
+ },
664
+ enum: [
665
+ {
666
+ title: "bug"
667
+ },
668
+ {
669
+ title: "task"
670
+ }
671
+ ],
672
+ type: "object"
673
+ },
674
+ payload: {
675
+ examples: [
676
+ {
677
+ description: "Body",
678
+ title: "First"
679
+ }
680
+ ],
681
+ default: {
682
+ priority: 2,
683
+ description: "",
684
+ title: "Untitled"
685
+ },
686
+ type: "object"
687
+ }
688
+ },
689
+ type: "object"
690
+ }
691
+ ],
692
+ distinctSpelling: {
693
+ type: "object",
694
+ properties: {
695
+ payload: {
696
+ type: "object",
697
+ default: {
698
+ priority: 2
699
+ },
700
+ examples: [
701
+ {}
702
+ ]
703
+ },
704
+ kind: {
705
+ type: "object",
706
+ enum: [
707
+ {},
708
+ {}
709
+ ],
710
+ const: {}
711
+ }
712
+ }
713
+ }
714
+ }
715
+ ]
716
+ };
717
+
718
+ // vectors/evaluate.json
719
+ var evaluate_default = [
720
+ { id: "VE-1", name: "absent argument in when falls through to the next variant", bound: { agent: { schemaVersion: "armor.policy.v2", policyId: "p-agent", target: { agent: "aaaaaaaa-0000-4000-8000-000000000001" }, layer: "agent", defaults: { tools: "hold", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [{ id: "st-pay-hold", subject: null, conditions: [{ field: "args.amount", op: "gt", value: 5e3, schemaBinding: { schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" } }], expiresAt: "never", provenance: { ruleKey: "create_payment", variant: 0, source: "yaml", layer: "agent" }, match: { tool: "create_payment", keyTier: "exact", order: 0 }, effect: "hold", approval: { approvers: 2, roles: ["finance_lead"] } }, { id: "st-pay-allow", subject: null, conditions: [], expiresAt: "never", provenance: { ruleKey: "create_payment", variant: 1, source: "yaml", layer: "agent" }, match: { tool: "create_payment", keyTier: "exact", order: 1 }, effect: "allow" }] } }, input: { tool: "create_payment", arguments: { recipient: "acme" }, timestamp: "2026-09-18T12:00:00Z" }, expect: { verdict: "allow", statementId: "st-pay-allow", layer: "agent", ruleKey: "create_payment" } },
721
+ { id: "VE-8", name: "hold carries its resolved approval", bound: { agent: { schemaVersion: "armor.policy.v2", policyId: "p-agent", target: { agent: "aaaaaaaa-0000-4000-8000-000000000001" }, layer: "agent", defaults: { tools: "hold", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [{ id: "st-pay-hold", subject: null, conditions: [{ field: "args.amount", op: "gt", value: 5e3, schemaBinding: { schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" } }], expiresAt: "never", provenance: { ruleKey: "create_payment", variant: 0, source: "yaml", layer: "agent" }, match: { tool: "create_payment", keyTier: "exact", order: 0 }, effect: "hold", approval: { approvers: 2, roles: ["finance_lead"] } }, { id: "st-pay-allow", subject: null, conditions: [], expiresAt: "never", provenance: { ruleKey: "create_payment", variant: 1, source: "yaml", layer: "agent" }, match: { tool: "create_payment", keyTier: "exact", order: 1 }, effect: "allow" }] } }, input: { tool: "create_payment", arguments: { amount: 9e3 }, timestamp: "2026-09-18T12:00:00Z", schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" }, expect: { verdict: "hold", statementId: "st-pay-hold", layer: "agent", ruleKey: "create_payment", approval: { approvers: 2, roles: ["finance_lead"] }, obligations: [] } },
722
+ { id: "VE-2", name: "schema drift still evaluates by name and attaches schema_drift", bound: { agent: { schemaVersion: "armor.policy.v2", policyId: "p-agent", target: { agent: "aaaaaaaa-0000-4000-8000-000000000001" }, layer: "agent", defaults: { tools: "hold", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [{ id: "st-pay-hold", subject: null, conditions: [{ field: "args.amount", op: "gt", value: 5e3, schemaBinding: { schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" } }], expiresAt: "never", provenance: { ruleKey: "create_payment", variant: 0, source: "yaml", layer: "agent" }, match: { tool: "create_payment", keyTier: "exact", order: 0 }, effect: "hold", approval: { approvers: 2, roles: ["finance_lead"] } }, { id: "st-pay-allow", subject: null, conditions: [], expiresAt: "never", provenance: { ruleKey: "create_payment", variant: 1, source: "yaml", layer: "agent" }, match: { tool: "create_payment", keyTier: "exact", order: 1 }, effect: "allow" }] } }, input: { tool: "create_payment", arguments: { amount: 9e3 }, timestamp: "2026-09-18T12:00:00Z", schemaHash: "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" }, expect: { verdict: "hold", statementId: "st-pay-hold", layer: "agent", ruleKey: "create_payment", obligations: [{ type: "schema_drift", statementId: "st-pay-hold", bound: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", observed: "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" }] } },
723
+ { id: "VE-3", name: "exact key beats glob key", bound: { agent: { schemaVersion: "armor.policy.v2", policyId: "p-agent", target: { agent: "aaaaaaaa-0000-4000-8000-000000000001" }, layer: "agent", defaults: { tools: "hold", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [{ id: "st-glob", subject: null, conditions: [], expiresAt: "never", provenance: { ruleKey: "mcp__github__*", variant: 0, source: "yaml", layer: "agent" }, match: { tool: "mcp__github__*", keyTier: "glob", order: 0 }, effect: "allow" }, { id: "st-exact", subject: null, conditions: [], expiresAt: "never", provenance: { ruleKey: "mcp__github__create_issue", variant: 0, source: "yaml", layer: "agent" }, match: { tool: "mcp__github__create_issue", keyTier: "exact", order: 0 }, effect: "hold" }] } }, input: { tool: "mcp__github__create_issue", arguments: {}, timestamp: "2026-09-18T12:00:00Z" }, expect: { verdict: "hold", statementId: "st-exact", layer: "agent", ruleKey: "mcp__github__create_issue" } },
724
+ { id: "VE-3b", name: "longer glob beats shorter glob", bound: { agent: { schemaVersion: "armor.policy.v2", policyId: "p-agent", target: { agent: "aaaaaaaa-0000-4000-8000-000000000001" }, layer: "agent", defaults: { tools: "hold", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [{ id: "st-short", subject: null, conditions: [], expiresAt: "never", provenance: { ruleKey: "mcp__*", variant: 0, source: "yaml", layer: "agent" }, match: { tool: "mcp__*", keyTier: "glob", order: 0 }, effect: "allow" }, { id: "st-long", subject: null, conditions: [], expiresAt: "never", provenance: { ruleKey: "mcp__github__*", variant: 0, source: "yaml", layer: "agent" }, match: { tool: "mcp__github__*", keyTier: "glob", order: 0 }, effect: "hold" }] } }, input: { tool: "mcp__github__delete_repo", arguments: {}, timestamp: "2026-09-18T12:00:00Z" }, expect: { verdict: "hold", statementId: "st-long", layer: "agent", ruleKey: "mcp__github__*" } },
725
+ { id: "VE-4", name: "floor merge: files.deny blocks a Read the agent allows", bound: { floor: { schemaVersion: "armor.policy.v2", policyId: "p-floor", target: { org: "*" }, layer: "floor", defaults: { tools: "allow", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [{ id: "st-ssh", subject: null, conditions: [{ field: "path", op: "glob", value: "**/.ssh/**" }], expiresAt: "never", provenance: { ruleKey: "files", variant: 0, source: "yaml", layer: "floor" }, match: { capability: "files" }, effect: "block" }] }, agent: { schemaVersion: "armor.policy.v2", policyId: "p-agent", target: { agent: "aaaaaaaa-0000-4000-8000-000000000001" }, layer: "agent", defaults: { tools: "hold", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [{ id: "st-read", subject: null, conditions: [], expiresAt: "never", provenance: { ruleKey: "Read", variant: 0, source: "yaml", layer: "agent" }, match: { tool: "Read", keyTier: "exact", order: 0 }, effect: "allow" }] } }, input: { tool: "Read", arguments: { file_path: "/home/u/.ssh/id_rsa" }, timestamp: "2026-09-18T12:00:00Z", capabilities: ["files"], derived: { path: "/home/u/.ssh/id_rsa" } }, expect: { verdict: "block", statementId: "st-ssh", layer: "floor", ruleKey: "files" } },
726
+ { id: "VE-4b", name: "floor capability rule does not fire outside its path glob", bound: { floor: { schemaVersion: "armor.policy.v2", policyId: "p-floor", target: { org: "*" }, layer: "floor", defaults: { tools: "allow", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [{ id: "st-ssh", subject: null, conditions: [{ field: "path", op: "glob", value: "**/.ssh/**" }], expiresAt: "never", provenance: { ruleKey: "files", variant: 0, source: "yaml", layer: "floor" }, match: { capability: "files" }, effect: "block" }] }, agent: { schemaVersion: "armor.policy.v2", policyId: "p-agent", target: { agent: "aaaaaaaa-0000-4000-8000-000000000001" }, layer: "agent", defaults: { tools: "hold", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [{ id: "st-read", subject: null, conditions: [], expiresAt: "never", provenance: { ruleKey: "Read", variant: 0, source: "yaml", layer: "agent" }, match: { tool: "Read", keyTier: "exact", order: 0 }, effect: "allow" }] } }, input: { tool: "Read", arguments: { file_path: "/home/u/notes.md" }, timestamp: "2026-09-18T12:00:00Z", capabilities: ["files"], derived: { path: "/home/u/notes.md" } }, expect: { verdict: "allow", statementId: "st-read", layer: "agent", ruleKey: "Read" } },
727
+ { id: "VE-5", name: "member overlay loosens the base for alice only", bound: { agent: { schemaVersion: "armor.policy.v2", policyId: "p-agent", target: { agent: "aaaaaaaa-0000-4000-8000-000000000001" }, layer: "agent", defaults: { tools: "hold", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [{ id: "st-base", subject: null, conditions: [], expiresAt: "never", provenance: { ruleKey: "create_payment", variant: 0, source: "yaml", layer: "agent" }, match: { tool: "create_payment", keyTier: "exact", order: 0 }, effect: "block" }, { id: "st-alice", subject: { membershipId: "m-alice" }, conditions: [], expiresAt: "never", provenance: { ruleKey: "create_payment", variant: 0, source: "yaml", layer: "agent" }, match: { tool: "create_payment", keyTier: "exact", order: 0 }, effect: "allow" }] } }, input: { tool: "create_payment", arguments: { amount: 10 }, timestamp: "2026-09-18T12:00:00Z", member: { membershipId: "m-alice" } }, expect: { verdict: "allow", statementId: "st-alice", layer: "member", ruleKey: "create_payment" } },
728
+ { id: "VE-5a", name: "everyone else keeps the base verdict", bound: { agent: { schemaVersion: "armor.policy.v2", policyId: "p-agent", target: { agent: "aaaaaaaa-0000-4000-8000-000000000001" }, layer: "agent", defaults: { tools: "hold", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [{ id: "st-base", subject: null, conditions: [], expiresAt: "never", provenance: { ruleKey: "create_payment", variant: 0, source: "yaml", layer: "agent" }, match: { tool: "create_payment", keyTier: "exact", order: 0 }, effect: "block" }, { id: "st-alice", subject: { membershipId: "m-alice" }, conditions: [], expiresAt: "never", provenance: { ruleKey: "create_payment", variant: 0, source: "yaml", layer: "agent" }, match: { tool: "create_payment", keyTier: "exact", order: 0 }, effect: "allow" }] } }, input: { tool: "create_payment", arguments: { amount: 10 }, timestamp: "2026-09-18T12:00:00Z", member: { membershipId: "m-carol" } }, expect: { verdict: "block", statementId: "st-base", layer: "agent", ruleKey: "create_payment" } },
729
+ { id: "VE-5b", name: "member overlay tightens the base for bob", bound: { agent: { schemaVersion: "armor.policy.v2", policyId: "p-agent", target: { agent: "aaaaaaaa-0000-4000-8000-000000000001" }, layer: "agent", defaults: { tools: "hold", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [{ id: "st-base", subject: null, conditions: [], expiresAt: "never", provenance: { ruleKey: "search_transactions", variant: 0, source: "yaml", layer: "agent" }, match: { tool: "search_transactions", keyTier: "exact", order: 0 }, effect: "allow" }, { id: "st-bob", subject: { email: "Bob@Example.com" }, conditions: [], expiresAt: "never", provenance: { ruleKey: "search_transactions", variant: 0, source: "yaml", layer: "agent" }, match: { tool: "search_transactions", keyTier: "exact", order: 0 }, effect: "block" }] } }, input: { tool: "search_transactions", arguments: {}, timestamp: "2026-09-18T12:00:00Z", member: { email: "bob@example.com" } }, expect: { verdict: "block", statementId: "st-bob", layer: "member", ruleKey: "search_transactions" } },
730
+ { id: "VE-5c", name: "org floor beats any member grant", bound: { floor: { schemaVersion: "armor.policy.v2", policyId: "p-floor", target: { org: "*" }, layer: "floor", defaults: { tools: "allow", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [{ id: "st-floor", subject: null, conditions: [], expiresAt: "never", provenance: { ruleKey: "delete_all", variant: 0, source: "yaml", layer: "floor" }, match: { tool: "delete_all", keyTier: "exact", order: 0 }, effect: "block" }] }, agent: { schemaVersion: "armor.policy.v2", policyId: "p-agent", target: { agent: "aaaaaaaa-0000-4000-8000-000000000001" }, layer: "agent", defaults: { tools: "hold", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [{ id: "st-alice", subject: { membershipId: "m-alice" }, conditions: [], expiresAt: "never", provenance: { ruleKey: "delete_all", variant: 0, source: "yaml", layer: "agent" }, match: { tool: "delete_all", keyTier: "exact", order: 0 }, effect: "allow" }] } }, input: { tool: "delete_all", arguments: {}, timestamp: "2026-09-18T12:00:00Z", member: { membershipId: "m-alice" } }, expect: { verdict: "block", statementId: "st-floor", layer: "floor", ruleKey: "delete_all" } },
731
+ { id: "VE-5d", name: "expired member rule is skipped", bound: { agent: { schemaVersion: "armor.policy.v2", policyId: "p-agent", target: { agent: "aaaaaaaa-0000-4000-8000-000000000001" }, layer: "agent", defaults: { tools: "hold", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [{ id: "st-base", subject: null, conditions: [], expiresAt: "never", provenance: { ruleKey: "create_payment", variant: 0, source: "yaml", layer: "agent" }, match: { tool: "create_payment", keyTier: "exact", order: 0 }, effect: "block" }, { id: "st-alice", subject: { membershipId: "m-alice" }, conditions: [], expiresAt: "2026-01-01T00:00:00Z", provenance: { ruleKey: "create_payment", variant: 0, source: "yaml", layer: "agent" }, match: { tool: "create_payment", keyTier: "exact", order: 0 }, effect: "allow" }] } }, input: { tool: "create_payment", arguments: {}, timestamp: "2026-09-18T12:00:00Z", member: { membershipId: "m-alice" } }, expect: { verdict: "block", statementId: "st-base", layer: "agent", ruleKey: "create_payment" } },
732
+ { id: "VE-5e", name: "member key specificity: membershipId beats email beats group", bound: { agent: { schemaVersion: "armor.policy.v2", policyId: "p-agent", target: { agent: "aaaaaaaa-0000-4000-8000-000000000001" }, layer: "agent", defaults: { tools: "hold", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [{ id: "st-group", subject: { group: "finance" }, conditions: [], expiresAt: "never", provenance: { ruleKey: "x", variant: 0, source: "yaml", layer: "agent" }, match: { tool: "x", keyTier: "exact", order: 0 }, effect: "block" }, { id: "st-email", subject: { email: "alice@example.com" }, conditions: [], expiresAt: "never", provenance: { ruleKey: "x", variant: 0, source: "yaml", layer: "agent" }, match: { tool: "x", keyTier: "exact", order: 0 }, effect: "hold" }, { id: "st-id", subject: { membershipId: "m-alice" }, conditions: [], expiresAt: "never", provenance: { ruleKey: "x", variant: 0, source: "yaml", layer: "agent" }, match: { tool: "x", keyTier: "exact", order: 0 }, effect: "allow" }] } }, input: { tool: "x", arguments: {}, timestamp: "2026-09-18T12:00:00Z", member: { membershipId: "m-alice", email: "alice@example.com", groups: ["finance"] } }, expect: { verdict: "allow", statementId: "st-id", layer: "member", ruleKey: "x" } },
733
+ { id: "VE-5f", name: "member key specificity: email beats group when no membershipId rule exists", bound: { agent: { schemaVersion: "armor.policy.v2", policyId: "p-agent", target: { agent: "aaaaaaaa-0000-4000-8000-000000000001" }, layer: "agent", defaults: { tools: "hold", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [{ id: "st-group", subject: { group: "finance" }, conditions: [], expiresAt: "never", provenance: { ruleKey: "x", variant: 0, source: "yaml", layer: "agent" }, match: { tool: "x", keyTier: "exact", order: 0 }, effect: "block" }, { id: "st-email", subject: { email: "alice@example.com" }, conditions: [], expiresAt: "never", provenance: { ruleKey: "x", variant: 0, source: "yaml", layer: "agent" }, match: { tool: "x", keyTier: "exact", order: 0 }, effect: "hold" }] } }, input: { tool: "x", arguments: {}, timestamp: "2026-09-18T12:00:00Z", member: { membershipId: "m-alice", email: "alice@example.com", groups: ["finance"] } }, expect: { verdict: "hold", statementId: "st-email", layer: "member", ruleKey: "x" } },
734
+ { id: "VE-6", name: "unknown tool goes to the most specific tools.default, never a wildcard", bound: { floor: { schemaVersion: "armor.policy.v2", policyId: "p-floor", target: { org: "*" }, layer: "floor", defaults: { tools: "allow", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [] }, agent: { schemaVersion: "armor.policy.v2", policyId: "p-agent", target: { agent: "aaaaaaaa-0000-4000-8000-000000000001" }, layer: "agent", defaults: { tools: "hold", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [{ id: "st-pay-hold", subject: null, conditions: [{ field: "args.amount", op: "gt", value: 5e3, schemaBinding: { schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" } }], expiresAt: "never", provenance: { ruleKey: "create_payment", variant: 0, source: "yaml", layer: "agent" }, match: { tool: "create_payment", keyTier: "exact", order: 0 }, effect: "hold", approval: { approvers: 2, roles: ["finance_lead"] } }, { id: "st-pay-allow", subject: null, conditions: [], expiresAt: "never", provenance: { ruleKey: "create_payment", variant: 1, source: "yaml", layer: "agent" }, match: { tool: "create_payment", keyTier: "exact", order: 1 }, effect: "allow" }] } }, input: { tool: "brand_new_tool", arguments: {}, timestamp: "2026-09-18T12:00:00Z" }, expect: { verdict: "hold", statementId: null, layer: "agent", ruleKey: "tools.default" } },
735
+ { id: "VE-7", name: "variant order: first match wins", bound: { agent: { schemaVersion: "armor.policy.v2", policyId: "p-agent", target: { agent: "aaaaaaaa-0000-4000-8000-000000000001" }, layer: "agent", defaults: { tools: "hold", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [{ id: "st-rm", subject: null, conditions: [{ field: "args.command", op: "regex", value: "\\brm\\s+-rf\\b" }], expiresAt: "never", provenance: { ruleKey: "Bash", variant: 0, source: "yaml", layer: "agent" }, match: { tool: "Bash", keyTier: "exact", order: 0 }, effect: "block" }, { id: "st-safe", subject: null, conditions: [{ field: "program", op: "in", value: ["git", "ls", "rm"] }], expiresAt: "never", provenance: { ruleKey: "Bash", variant: 1, source: "yaml", layer: "agent" }, match: { tool: "Bash", keyTier: "exact", order: 1 }, effect: "allow" }] } }, input: { tool: "Bash", arguments: { command: "rm -rf /tmp/x" }, timestamp: "2026-09-18T12:00:00Z", derived: { program: "rm" } }, expect: { verdict: "block", statementId: "st-rm", layer: "agent", ruleKey: "Bash" } },
736
+ { id: "VE-9", name: "provenance names the deciding statement, key and variant", bound: { agent: { schemaVersion: "armor.policy.v2", policyId: "p-agent", target: { agent: "aaaaaaaa-0000-4000-8000-000000000001" }, layer: "agent", defaults: { tools: "hold", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [{ id: "st-pay-hold", subject: null, conditions: [{ field: "args.amount", op: "gt", value: 5e3, schemaBinding: { schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" } }], expiresAt: "never", provenance: { ruleKey: "create_payment", variant: 0, source: "yaml", layer: "agent" }, match: { tool: "create_payment", keyTier: "exact", order: 0 }, effect: "hold", approval: { approvers: 2, roles: ["finance_lead"] } }, { id: "st-pay-allow", subject: null, conditions: [], expiresAt: "never", provenance: { ruleKey: "create_payment", variant: 1, source: "yaml", layer: "agent" }, match: { tool: "create_payment", keyTier: "exact", order: 1 }, effect: "allow" }] } }, input: { tool: "create_payment", arguments: { amount: 1 }, timestamp: "2026-09-18T12:00:00Z" }, expect: { verdict: "allow", statementId: "st-pay-allow", layer: "agent", ruleKey: "create_payment" } },
737
+ { id: "VE-11", name: "agent policy overrides group policy, loosening", bound: { group: { schemaVersion: "armor.policy.v2", policyId: "p-group", target: { group: "payments" }, layer: "group", defaults: { tools: "hold", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [{ id: "st-g", subject: null, conditions: [], expiresAt: "never", provenance: { ruleKey: "create_payment", variant: 0, source: "yaml", layer: "group" }, match: { tool: "create_payment", keyTier: "exact", order: 0 }, effect: "hold" }] }, agent: { schemaVersion: "armor.policy.v2", policyId: "p-agent", target: { agent: "aaaaaaaa-0000-4000-8000-000000000001" }, layer: "agent", defaults: { tools: "hold", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [{ id: "st-a", subject: null, conditions: [], expiresAt: "never", provenance: { ruleKey: "create_payment", variant: 0, source: "yaml", layer: "agent" }, match: { tool: "create_payment", keyTier: "exact", order: 0 }, effect: "allow" }] } }, input: { tool: "create_payment", arguments: {}, timestamp: "2026-09-18T12:00:00Z" }, expect: { verdict: "allow", statementId: "st-a", layer: "agent", ruleKey: "create_payment" } },
738
+ { id: "VE-11b", name: "agent policy overrides group policy, tightening", bound: { group: { schemaVersion: "armor.policy.v2", policyId: "p-group", target: { group: "payments" }, layer: "group", defaults: { tools: "hold", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [{ id: "st-g", subject: null, conditions: [], expiresAt: "never", provenance: { ruleKey: "Read", variant: 0, source: "yaml", layer: "group" }, match: { tool: "Read", keyTier: "exact", order: 0 }, effect: "allow" }] }, agent: { schemaVersion: "armor.policy.v2", policyId: "p-agent", target: { agent: "aaaaaaaa-0000-4000-8000-000000000001" }, layer: "agent", defaults: { tools: "hold", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [{ id: "st-a", subject: null, conditions: [], expiresAt: "never", provenance: { ruleKey: "Read", variant: 0, source: "yaml", layer: "agent" }, match: { tool: "Read", keyTier: "exact", order: 0 }, effect: "block" }] } }, input: { tool: "Read", arguments: {}, timestamp: "2026-09-18T12:00:00Z" }, expect: { verdict: "block", statementId: "st-a", layer: "agent", ruleKey: "Read" } },
739
+ { id: "VE-12", name: "group policy applies when the agent policy is silent", bound: { group: { schemaVersion: "armor.policy.v2", policyId: "p-group", target: { group: "payments" }, layer: "group", defaults: { tools: "hold", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [{ id: "st-g", subject: null, conditions: [], expiresAt: "never", provenance: { ruleKey: "search_transactions", variant: 0, source: "yaml", layer: "group" }, match: { tool: "search_transactions", keyTier: "exact", order: 0 }, effect: "hold" }] }, agent: { schemaVersion: "armor.policy.v2", policyId: "p-agent", target: { agent: "aaaaaaaa-0000-4000-8000-000000000001" }, layer: "agent", defaults: { tools: "hold", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [{ id: "st-a", subject: null, conditions: [], expiresAt: "never", provenance: { ruleKey: "Read", variant: 0, source: "yaml", layer: "agent" }, match: { tool: "Read", keyTier: "exact", order: 0 }, effect: "allow" }] } }, input: { tool: "search_transactions", arguments: {}, timestamp: "2026-09-18T12:00:00Z" }, expect: { verdict: "hold", statementId: "st-g", layer: "group", ruleKey: "search_transactions" } },
740
+ { id: "VE-13", name: "floor beats both group and agent", bound: { floor: { schemaVersion: "armor.policy.v2", policyId: "p-floor", target: { org: "*" }, layer: "floor", defaults: { tools: "allow", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [{ id: "st-f", subject: null, conditions: [], expiresAt: "never", provenance: { ruleKey: "delete_all", variant: 0, source: "yaml", layer: "floor" }, match: { tool: "delete_all", keyTier: "exact", order: 0 }, effect: "block" }] }, group: { schemaVersion: "armor.policy.v2", policyId: "p-group", target: { group: "payments" }, layer: "group", defaults: { tools: "hold", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [{ id: "st-g", subject: null, conditions: [], expiresAt: "never", provenance: { ruleKey: "delete_all", variant: 0, source: "yaml", layer: "group" }, match: { tool: "delete_all", keyTier: "exact", order: 0 }, effect: "allow" }] }, agent: { schemaVersion: "armor.policy.v2", policyId: "p-agent", target: { agent: "aaaaaaaa-0000-4000-8000-000000000001" }, layer: "agent", defaults: { tools: "hold", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [{ id: "st-a", subject: null, conditions: [], expiresAt: "never", provenance: { ruleKey: "delete_all", variant: 0, source: "yaml", layer: "agent" }, match: { tool: "delete_all", keyTier: "exact", order: 0 }, effect: "allow" }] } }, input: { tool: "delete_all", arguments: {}, timestamp: "2026-09-18T12:00:00Z" }, expect: { verdict: "block", statementId: "st-f", layer: "floor", ruleKey: "delete_all" } },
741
+ { id: "VE-13b", name: "a floor hold tightens an agent allow but yields to an agent block", bound: { floor: { schemaVersion: "armor.policy.v2", policyId: "p-floor", target: { org: "*" }, layer: "floor", defaults: { tools: "allow", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [{ id: "st-f", subject: null, conditions: [], expiresAt: "never", provenance: { ruleKey: "deploy", variant: 0, source: "yaml", layer: "floor" }, match: { tool: "deploy", keyTier: "exact", order: 0 }, effect: "hold" }] }, agent: { schemaVersion: "armor.policy.v2", policyId: "p-agent", target: { agent: "aaaaaaaa-0000-4000-8000-000000000001" }, layer: "agent", defaults: { tools: "hold", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [{ id: "st-a", subject: null, conditions: [], expiresAt: "never", provenance: { ruleKey: "deploy", variant: 0, source: "yaml", layer: "agent" }, match: { tool: "deploy", keyTier: "exact", order: 0 }, effect: "allow" }] } }, input: { tool: "deploy", arguments: {}, timestamp: "2026-09-18T12:00:00Z" }, expect: { verdict: "hold", statementId: "st-f", layer: "floor", ruleKey: "deploy" } },
742
+ { id: "VE-14", name: "capability rule binds by tag only: tagged tool holds", bound: { agent: { schemaVersion: "armor.policy.v2", policyId: "p-agent", target: { agent: "aaaaaaaa-0000-4000-8000-000000000001" }, layer: "agent", defaults: { tools: "allow", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [{ id: "st-destructive", subject: null, conditions: [], expiresAt: "never", provenance: { ruleKey: "destructive", variant: 0, source: "yaml", layer: "agent" }, match: { capability: "destructive" }, effect: "hold" }] } }, input: { tool: "mcp__jira__delete_issue", arguments: {}, timestamp: "2026-09-18T12:00:00Z", capabilities: ["destructive"] }, expect: { verdict: "hold", statementId: "st-destructive", layer: "agent", ruleKey: "destructive" } },
743
+ { id: "VE-14b", name: "capability rule binds by tag only: untagged tool on the same server gets tools.default", bound: { agent: { schemaVersion: "armor.policy.v2", policyId: "p-agent", target: { agent: "aaaaaaaa-0000-4000-8000-000000000001" }, layer: "agent", defaults: { tools: "allow", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [{ id: "st-destructive", subject: null, conditions: [], expiresAt: "never", provenance: { ruleKey: "destructive", variant: 0, source: "yaml", layer: "agent" }, match: { capability: "destructive" }, effect: "hold" }] } }, input: { tool: "mcp__jira__list_issues", arguments: {}, timestamp: "2026-09-18T12:00:00Z", capabilities: [] }, expect: { verdict: "allow", statementId: null, layer: "agent", ruleKey: "tools.default" } },
744
+ { id: "VE-15", name: "an expired document contributes nothing", bound: { group: { schemaVersion: "armor.policy.v2", policyId: "p-group", target: { group: "payments" }, layer: "group", defaults: { tools: "hold", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "2026-01-01T00:00:00Z", statements: [{ id: "st-g", subject: null, conditions: [], expiresAt: "never", provenance: { ruleKey: "x", variant: 0, source: "yaml", layer: "group" }, match: { tool: "x", keyTier: "exact", order: 0 }, effect: "block" }] }, agent: { schemaVersion: "armor.policy.v2", policyId: "p-agent", target: { agent: "aaaaaaaa-0000-4000-8000-000000000001" }, layer: "agent", defaults: { tools: "allow", network: "block", files: "allow", skills: "allow" }, capture: { arguments: true, redact: ["*token*"], maxBytesPerCall: 16384, sample: 1 }, expiresAt: "never", statements: [] } }, input: { tool: "x", arguments: {}, timestamp: "2026-09-18T12:00:00Z" }, expect: { verdict: "allow", statementId: null, layer: "agent", ruleKey: "tools.default" } }
745
+ ];
746
+
747
+ // vectors/document.json
748
+ var document_default = [
749
+ { id: "VC-1", name: "the full v2 document parses and validates", yaml: `apiVersion: armor.io/v2
750
+ kind: Policy
751
+ metadata:
752
+ name: vector
753
+ orgId: 11111111-1111-4111-8111-111111111111
754
+ target:
755
+ agent: aaaaaaaa-0000-4000-8000-000000000001
756
+ mcpServers: [github]
757
+ spec:
758
+ tools:
759
+ default: hold
760
+ rules:
761
+ Read: allow
762
+ "mcp__github__*": allow
763
+ destructive: hold
764
+ file.write:
765
+ - when: {path: {glob: "**/*.tf"}}
766
+ action: hold
767
+ controls: [SOC2-CC8.1]
768
+ - action: allow
769
+ Bash:
770
+ - when: {command: {matches: '(^|\\s)rm\\s+-[a-zA-Z]*[rf]'}}
771
+ action: block
772
+ reason: recursive force delete
773
+ controls: [SOC2-CC6.1]
774
+ - when: {program: {in: [ls, grep, cat, git]}, writeRedirection: {eq: false}}
775
+ action: allow
776
+ - action: hold
777
+ create_payment:
778
+ - when: {args.amount: {gt: 5000}}
779
+ action: hold
780
+ approval: {approvers: 2, roles: [finance_lead]}
781
+ controls: [SOC2-CC6.1, SOC2-CC7.2]
782
+ - action: allow
783
+ files:
784
+ deny: ["~/.ssh/**", "**/.env*", "**/*.pem"]
785
+ allowOutsideWorkspace: false
786
+ network:
787
+ default: block
788
+ allow: ["*.github.com", {host: api.stripe.com, reason: payments}]
789
+ deny: [{host: 169.254.169.254, reason: AWS IMDS credentials endpoint}]
790
+ skills:
791
+ default: allow
792
+ hold: ["*:deploy*"]
793
+ members:
794
+ "alice@armoriq.io":
795
+ tools:
796
+ rules:
797
+ create_payment:
798
+ - action: allow
799
+ expiresAt: 2026-12-31T00:00:00Z
800
+ expiresAt: never
801
+ "bob@armoriq.io":
802
+ tools: {rules: {search_transactions: block}}
803
+ "team:interns":
804
+ tools: {default: block}
805
+ capture:
806
+ arguments: true
807
+ redact: ["*token*", "*secret*", "authorization"]
808
+ maxBytesPerCall: 16384
809
+ sample: 1.0
810
+ approvalDefaults: {approvers: 1, roles: [admin]}
811
+ `, expect: { errors: [], warnings: ["loosening_grant"] } },
812
+ { id: "VC-2", name: "an unknown key is a compile error", yaml: "apiVersion: armor.io/v2\nkind: Policy\nmetadata:\n name: vector\n orgId: 11111111-1111-4111-8111-111111111111\ntarget:\n agent: aaaaaaaa-0000-4000-8000-000000000001\n mcpServers: [github]\nspec:\n tools:\n default: hold\n rules:\n Read: allow\n denyTools: [rm]\n", expect: { errors: ["unknown_key"], warnings: [] } },
813
+ { id: "VC-2b", name: "a v1 status field is an unknown key", yaml: "apiVersion: armor.io/v2\nkind: Policy\nmetadata:\n name: vector\n orgId: 11111111-1111-4111-8111-111111111111\ntarget:\n agent: aaaaaaaa-0000-4000-8000-000000000001\n mcpServers: [github]\nspec:\n tools:\n default: hold\n rules:\n Read: allow\n status: active\n", expect: { errors: ["unknown_key"], warnings: [] } },
814
+ { id: "VC-5", name: "a variant after an unconditional one is unreachable", yaml: "apiVersion: armor.io/v2\nkind: Policy\nmetadata:\n name: vector\n orgId: 11111111-1111-4111-8111-111111111111\ntarget:\n agent: aaaaaaaa-0000-4000-8000-000000000001\n mcpServers: [github]\nspec:\n tools:\n default: hold\n rules:\n Bash:\n - action: allow\n - when: {args.command: {matches: 'rm'}}\n action: block\n", expect: { errors: ["unreachable_variant"], warnings: [] } },
815
+ { id: "VC-6", name: "a hold with no approver and no approvalDefaults is an error", yaml: "apiVersion: armor.io/v2\nkind: Policy\nmetadata:\n name: vector\n orgId: 11111111-1111-4111-8111-111111111111\ntarget:\n agent: aaaaaaaa-0000-4000-8000-000000000001\n mcpServers: [github]\nspec:\n tools:\n default: hold\n rules:\n create_payment: hold\n", expect: { errors: ["hold_without_approver"], warnings: [] } },
816
+ { id: "VC-6b", name: "a hold resolved by approvalDefaults is clean", yaml: "apiVersion: armor.io/v2\nkind: Policy\nmetadata:\n name: vector\n orgId: 11111111-1111-4111-8111-111111111111\ntarget:\n agent: aaaaaaaa-0000-4000-8000-000000000001\n mcpServers: [github]\nspec:\n tools:\n default: hold\n rules:\n create_payment: hold\n approvalDefaults: {approvers: 1, roles: [admin]}\n", expect: { errors: [], warnings: [] } },
817
+ { id: "VC-6c", name: "an approval that names nobody is unresolvable", yaml: "apiVersion: armor.io/v2\nkind: Policy\nmetadata:\n name: vector\n orgId: 11111111-1111-4111-8111-111111111111\ntarget:\n agent: aaaaaaaa-0000-4000-8000-000000000001\n mcpServers: [github]\nspec:\n tools:\n default: hold\n rules:\n create_payment:\n - action: hold\n approval: {approvers: 2}\n", expect: { errors: ["approval_unresolvable"], warnings: [] } },
818
+ { id: "VC-7", name: "a member grant that loosens the base is flagged for review", yaml: 'apiVersion: armor.io/v2\nkind: Policy\nmetadata:\n name: vector\n orgId: 11111111-1111-4111-8111-111111111111\ntarget:\n agent: aaaaaaaa-0000-4000-8000-000000000001\n mcpServers: [github]\nspec:\n tools:\n default: hold\n rules:\n create_payment: block\n members:\n "alice@armoriq.io":\n tools: {rules: {create_payment: allow}}\n', expect: { errors: [], warnings: ["loosening_grant"] } },
819
+ { id: "VC-7t", name: "a member rule that tightens the base is not flagged", yaml: 'apiVersion: armor.io/v2\nkind: Policy\nmetadata:\n name: vector\n orgId: 11111111-1111-4111-8111-111111111111\ntarget:\n agent: aaaaaaaa-0000-4000-8000-000000000001\n mcpServers: [github]\nspec:\n tools:\n default: hold\n rules:\n search_transactions: allow\n members:\n "bob@armoriq.io":\n tools: {rules: {search_transactions: block}}\n', expect: { errors: [], warnings: [] } },
820
+ { id: "VC-17", name: "device: local is accepted", yaml: `apiVersion: armor.io/v2
821
+ kind: Policy
822
+ metadata:
823
+ name: vector
824
+ target: {device: local}
825
+ spec:
826
+ tools:
827
+ default: hold
828
+ rules:
829
+ Read: allow
830
+ "mcp__github__*": allow
831
+ destructive: hold
832
+ file.write:
833
+ - when: {path: {glob: "**/*.tf"}}
834
+ action: hold
835
+ controls: [SOC2-CC8.1]
836
+ - action: allow
837
+ Bash:
838
+ - when: {command: {matches: '(^|\\s)rm\\s+-[a-zA-Z]*[rf]'}}
839
+ action: block
840
+ reason: recursive force delete
841
+ controls: [SOC2-CC6.1]
842
+ - when: {program: {in: [ls, grep, cat, git]}, writeRedirection: {eq: false}}
843
+ action: allow
844
+ - action: hold
845
+ create_payment:
846
+ - when: {args.amount: {gt: 5000}}
847
+ action: hold
848
+ approval: {approvers: 2, roles: [finance_lead]}
849
+ controls: [SOC2-CC6.1, SOC2-CC7.2]
850
+ - action: allow
851
+ files:
852
+ deny: ["~/.ssh/**", "**/.env*", "**/*.pem"]
853
+ allowOutsideWorkspace: false
854
+ network:
855
+ default: block
856
+ allow: ["*.github.com", {host: api.stripe.com, reason: payments}]
857
+ deny: [{host: 169.254.169.254, reason: AWS IMDS credentials endpoint}]
858
+ skills:
859
+ default: allow
860
+ hold: ["*:deploy*"]
861
+ capture:
862
+ arguments: true
863
+ redact: ["*token*", "*secret*", "authorization"]
864
+ maxBytesPerCall: 16384
865
+ sample: 1.0
866
+ approvalDefaults: {approvers: 1, roles: [admin]}
867
+ `, expect: { errors: [], warnings: [] } },
868
+ { id: "VC-17b", name: "target product is an unknown key", yaml: `apiVersion: armor.io/v2
869
+ kind: Policy
870
+ metadata:
871
+ name: vector
872
+ orgId: 11111111-1111-4111-8111-111111111111
873
+ target: {product: armorclaude}
874
+ spec:
875
+ tools:
876
+ default: hold
877
+ rules:
878
+ Read: allow
879
+ "mcp__github__*": allow
880
+ destructive: hold
881
+ file.write:
882
+ - when: {path: {glob: "**/*.tf"}}
883
+ action: hold
884
+ controls: [SOC2-CC8.1]
885
+ - action: allow
886
+ Bash:
887
+ - when: {command: {matches: '(^|\\s)rm\\s+-[a-zA-Z]*[rf]'}}
888
+ action: block
889
+ reason: recursive force delete
890
+ controls: [SOC2-CC6.1]
891
+ - when: {program: {in: [ls, grep, cat, git]}, writeRedirection: {eq: false}}
892
+ action: allow
893
+ - action: hold
894
+ create_payment:
895
+ - when: {args.amount: {gt: 5000}}
896
+ action: hold
897
+ approval: {approvers: 2, roles: [finance_lead]}
898
+ controls: [SOC2-CC6.1, SOC2-CC7.2]
899
+ - action: allow
900
+ files:
901
+ deny: ["~/.ssh/**", "**/.env*", "**/*.pem"]
902
+ allowOutsideWorkspace: false
903
+ network:
904
+ default: block
905
+ allow: ["*.github.com", {host: api.stripe.com, reason: payments}]
906
+ deny: [{host: 169.254.169.254, reason: AWS IMDS credentials endpoint}]
907
+ skills:
908
+ default: allow
909
+ hold: ["*:deploy*"]
910
+ members:
911
+ "alice@armoriq.io":
912
+ tools:
913
+ rules:
914
+ create_payment:
915
+ - action: allow
916
+ expiresAt: 2026-12-31T00:00:00Z
917
+ expiresAt: never
918
+ "bob@armoriq.io":
919
+ tools: {rules: {search_transactions: block}}
920
+ "team:interns":
921
+ tools: {default: block}
922
+ capture:
923
+ arguments: true
924
+ redact: ["*token*", "*secret*", "authorization"]
925
+ maxBytesPerCall: 16384
926
+ sample: 1.0
927
+ approvalDefaults: {approvers: 1, roles: [admin]}
928
+ `, expect: { errors: ["target_form", "unknown_key"], warnings: [] } },
929
+ { id: "VC-18", name: "products and precedence are local only", yaml: "apiVersion: armor.io/v2\nkind: Policy\nmetadata:\n name: vector\n orgId: 11111111-1111-4111-8111-111111111111\nprecedence: device-first\ntarget:\n agent: aaaaaaaa-0000-4000-8000-000000000001\n mcpServers: [github]\nspec:\n tools:\n default: hold\n rules:\n Read: allow\n products:\n claude-code: {tools: {rules: {Bash: block}}}\n", expect: { errors: ["local_only_section", "local_only_section"], warnings: [] } },
930
+ { id: "VC-18b", name: "members is enterprise only", yaml: 'apiVersion: armor.io/v2\nkind: Policy\nmetadata:\n name: vector\ntarget: {device: local}\nspec:\n tools:\n default: hold\n rules:\n Read: allow\n members:\n "alice@armoriq.io": {tools: {rules: {Read: block}}}\n', expect: { errors: ["enterprise_only_section"], warnings: [] } },
931
+ { id: "VC-11c", name: "a condition takes exactly one operator", yaml: "apiVersion: armor.io/v2\nkind: Policy\nmetadata:\n name: vector\n orgId: 11111111-1111-4111-8111-111111111111\ntarget:\n agent: aaaaaaaa-0000-4000-8000-000000000001\n mcpServers: [github]\nspec:\n tools:\n default: hold\n rules:\n create_payment:\n - when: {args.amount: {gt: 5000, lt: 9000}}\n action: block\n", expect: { errors: ["condition_operator"], warnings: [] } },
932
+ { id: "VC-11d", name: "a numeric operator rejects a string operand", yaml: 'apiVersion: armor.io/v2\nkind: Policy\nmetadata:\n name: vector\n orgId: 11111111-1111-4111-8111-111111111111\ntarget:\n agent: aaaaaaaa-0000-4000-8000-000000000001\n mcpServers: [github]\nspec:\n tools:\n default: hold\n rules:\n create_payment:\n - when: {args.amount: {gt: "5000"}}\n action: block\n', expect: { errors: ["condition_operand"], warnings: [] } },
933
+ { id: "VC-11e", name: "matches rejects a lookaround the Rego evaluator cannot run", yaml: "apiVersion: armor.io/v2\nkind: Policy\nmetadata:\n name: vector\n orgId: 11111111-1111-4111-8111-111111111111\ntarget:\n agent: aaaaaaaa-0000-4000-8000-000000000001\n mcpServers: [github]\nspec:\n tools:\n default: hold\n rules:\n Bash:\n - when: {command: {matches: '(?=rm)'}}\n action: block\n", expect: { errors: ["condition_operand"], warnings: [] } },
934
+ { id: "VC-1b", name: "tools.default is required", yaml: "apiVersion: armor.io/v2\nkind: Policy\nmetadata:\n name: vector\n orgId: 11111111-1111-4111-8111-111111111111\ntarget:\n agent: aaaaaaaa-0000-4000-8000-000000000001\n mcpServers: [github]\nspec:\n tools:\n rules:\n Read: allow\n", expect: { errors: ["expected_verdict"], warnings: [] } }
935
+ ];
936
+
937
+ // vectors/compile.json
938
+ var compile_default = [
939
+ { id: "VC-14", name: "schemaHash of the declared tool is bound on every args condition (FR-14)", yaml: "apiVersion: armor.io/v2\nkind: Policy\nmetadata:\n name: vector\n orgId: 11111111-1111-4111-8111-111111111111\ntarget:\n agent: aaaaaaaa-0000-4000-8000-000000000001\nspec:\n tools:\n default: hold\n rules:\n create_payment:\n - when: {args.amount: {gt: 5000}}\n action: hold\n approval: {approvers: 2, roles: [finance_lead]}\n - action: allow\n approvalDefaults: {approvers: 1, roles: [admin]}\n", inventory: [{ name: "create_payment", owner: { type: "agent", id: "agent-1", name: "support-agent" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true }, { name: "Read", owner: { type: "agent", id: "agent-1", name: "support-agent" }, schemaHash: "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", inputSchema: { type: "object", properties: { file_path: { type: "string" } } }, declared: true }, { name: "create_issue", owner: { type: "mcp_server", id: "srv-github", name: "github" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true, qualifiedName: "mcp__github__create_issue", capabilities: ["destructive"] }, { name: "list_issues", owner: { type: "mcp_server", id: "srv-github", name: "github" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true, qualifiedName: "mcp__github__list_issues", capabilities: [] }, { name: "delete_repo", owner: { type: "mcp_server", id: "srv-github", name: "github" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true, qualifiedName: "mcp__github__delete_repo", capabilities: ["destructive"] }, { name: "observed_only", owner: { type: "agent", id: "agent-1", name: "support-agent" }, schemaHash: null, declared: false }], expect: { errors: [], warnings: [], statementIds: ["st-create-payment-0", "st-create-payment-1"], bindings: { "st-create-payment-0": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" } } },
940
+ { id: "VC-15", name: "an unknown control identifier compiles with a warning naming it", yaml: "apiVersion: armor.io/v2\nkind: Policy\nmetadata:\n name: vector\n orgId: 11111111-1111-4111-8111-111111111111\ntarget:\n agent: aaaaaaaa-0000-4000-8000-000000000001\nspec:\n tools:\n default: hold\n rules:\n Read:\n - action: allow\n controls: [SOC2-CC6.1, NOT-A-CONTROL]\n approvalDefaults: {approvers: 1, roles: [admin]}\n", inventory: [{ name: "create_payment", owner: { type: "agent", id: "agent-1", name: "support-agent" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true }, { name: "Read", owner: { type: "agent", id: "agent-1", name: "support-agent" }, schemaHash: "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", inputSchema: { type: "object", properties: { file_path: { type: "string" } } }, declared: true }, { name: "create_issue", owner: { type: "mcp_server", id: "srv-github", name: "github" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true, qualifiedName: "mcp__github__create_issue", capabilities: ["destructive"] }, { name: "list_issues", owner: { type: "mcp_server", id: "srv-github", name: "github" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true, qualifiedName: "mcp__github__list_issues", capabilities: [] }, { name: "delete_repo", owner: { type: "mcp_server", id: "srv-github", name: "github" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true, qualifiedName: "mcp__github__delete_repo", capabilities: ["destructive"] }, { name: "observed_only", owner: { type: "agent", id: "agent-1", name: "support-agent" }, schemaHash: null, declared: false }], expect: { errors: [], warnings: ["unknown_control"], statementIds: ["st-read-0"] } },
941
+ { id: "VC-8", name: "a rule key not in the inventory compiles with a warning", yaml: "apiVersion: armor.io/v2\nkind: Policy\nmetadata:\n name: vector\n orgId: 11111111-1111-4111-8111-111111111111\ntarget:\n agent: aaaaaaaa-0000-4000-8000-000000000001\nspec:\n tools:\n default: hold\n rules:\n nonexistent_tool: block\n approvalDefaults: {approvers: 1, roles: [admin]}\n", inventory: [{ name: "create_payment", owner: { type: "agent", id: "agent-1", name: "support-agent" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true }, { name: "Read", owner: { type: "agent", id: "agent-1", name: "support-agent" }, schemaHash: "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", inputSchema: { type: "object", properties: { file_path: { type: "string" } } }, declared: true }, { name: "create_issue", owner: { type: "mcp_server", id: "srv-github", name: "github" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true, qualifiedName: "mcp__github__create_issue", capabilities: ["destructive"] }, { name: "list_issues", owner: { type: "mcp_server", id: "srv-github", name: "github" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true, qualifiedName: "mcp__github__list_issues", capabilities: [] }, { name: "delete_repo", owner: { type: "mcp_server", id: "srv-github", name: "github" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true, qualifiedName: "mcp__github__delete_repo", capabilities: ["destructive"] }, { name: "observed_only", owner: { type: "agent", id: "agent-1", name: "support-agent" }, schemaHash: null, declared: false }], expect: { errors: [], warnings: ["unknown_tool_key"], statementIds: ["st-nonexistent-tool-0"] } },
942
+ { id: "VC-8b", name: "an observed-only tool compiles without a binding and says so", yaml: "apiVersion: armor.io/v2\nkind: Policy\nmetadata:\n name: vector\n orgId: 11111111-1111-4111-8111-111111111111\ntarget:\n agent: aaaaaaaa-0000-4000-8000-000000000001\nspec:\n tools:\n default: hold\n rules:\n observed_only:\n - when: {args.x: {exists: true}}\n action: block\n approvalDefaults: {approvers: 1, roles: [admin]}\n", inventory: [{ name: "create_payment", owner: { type: "agent", id: "agent-1", name: "support-agent" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true }, { name: "Read", owner: { type: "agent", id: "agent-1", name: "support-agent" }, schemaHash: "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", inputSchema: { type: "object", properties: { file_path: { type: "string" } } }, declared: true }, { name: "create_issue", owner: { type: "mcp_server", id: "srv-github", name: "github" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true, qualifiedName: "mcp__github__create_issue", capabilities: ["destructive"] }, { name: "list_issues", owner: { type: "mcp_server", id: "srv-github", name: "github" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true, qualifiedName: "mcp__github__list_issues", capabilities: [] }, { name: "delete_repo", owner: { type: "mcp_server", id: "srv-github", name: "github" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true, qualifiedName: "mcp__github__delete_repo", capabilities: ["destructive"] }, { name: "observed_only", owner: { type: "agent", id: "agent-1", name: "support-agent" }, schemaHash: null, declared: false }], expect: { errors: [], warnings: ["observed_only_tool"], bindings: { "st-observed-only-0": null } } },
943
+ { id: "VC-9", name: "an args key the schema does not declare compiles with a warning", yaml: "apiVersion: armor.io/v2\nkind: Policy\nmetadata:\n name: vector\n orgId: 11111111-1111-4111-8111-111111111111\ntarget:\n agent: aaaaaaaa-0000-4000-8000-000000000001\nspec:\n tools:\n default: hold\n rules:\n create_payment:\n - when: {args.nonexistent: {gt: 5}}\n action: block\n approvalDefaults: {approvers: 1, roles: [admin]}\n", inventory: [{ name: "create_payment", owner: { type: "agent", id: "agent-1", name: "support-agent" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true }, { name: "Read", owner: { type: "agent", id: "agent-1", name: "support-agent" }, schemaHash: "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", inputSchema: { type: "object", properties: { file_path: { type: "string" } } }, declared: true }, { name: "create_issue", owner: { type: "mcp_server", id: "srv-github", name: "github" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true, qualifiedName: "mcp__github__create_issue", capabilities: ["destructive"] }, { name: "list_issues", owner: { type: "mcp_server", id: "srv-github", name: "github" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true, qualifiedName: "mcp__github__list_issues", capabilities: [] }, { name: "delete_repo", owner: { type: "mcp_server", id: "srv-github", name: "github" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true, qualifiedName: "mcp__github__delete_repo", capabilities: ["destructive"] }, { name: "observed_only", owner: { type: "agent", id: "agent-1", name: "support-agent" }, schemaHash: null, declared: false }], expect: { errors: [], warnings: ["unknown_argument"] } },
944
+ { id: "VC-3", name: "exact and glob keys lower with their tier and the exact key binds", yaml: 'apiVersion: armor.io/v2\nkind: Policy\nmetadata:\n name: vector\n orgId: 11111111-1111-4111-8111-111111111111\ntarget:\n agent: aaaaaaaa-0000-4000-8000-000000000001\nspec:\n tools:\n default: hold\n rules:\n mcp__github__create_issue: hold\n "mcp__github__*": allow\n approvalDefaults: {approvers: 1, roles: [admin]}\n', inventory: [{ name: "create_payment", owner: { type: "agent", id: "agent-1", name: "support-agent" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true }, { name: "Read", owner: { type: "agent", id: "agent-1", name: "support-agent" }, schemaHash: "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", inputSchema: { type: "object", properties: { file_path: { type: "string" } } }, declared: true }, { name: "create_issue", owner: { type: "mcp_server", id: "srv-github", name: "github" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true, qualifiedName: "mcp__github__create_issue", capabilities: ["destructive"] }, { name: "list_issues", owner: { type: "mcp_server", id: "srv-github", name: "github" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true, qualifiedName: "mcp__github__list_issues", capabilities: [] }, { name: "delete_repo", owner: { type: "mcp_server", id: "srv-github", name: "github" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true, qualifiedName: "mcp__github__delete_repo", capabilities: ["destructive"] }, { name: "observed_only", owner: { type: "agent", id: "agent-1", name: "support-agent" }, schemaHash: null, declared: false }], expect: { errors: [], warnings: [], statementIds: ["st-mcp-github-create-issue-0", "st-mcp-github-0"] } },
945
+ { id: "VC-4", name: "two same-length globs matching one real tool is a compile error", yaml: 'apiVersion: armor.io/v2\nkind: Policy\nmetadata:\n name: vector\n orgId: 11111111-1111-4111-8111-111111111111\ntarget:\n agent: aaaaaaaa-0000-4000-8000-000000000001\nspec:\n tools:\n default: hold\n rules:\n "mcp__github__*": allow\n "*_create_issue": block\n approvalDefaults: {approvers: 1, roles: [admin]}\n', inventory: [{ name: "create_payment", owner: { type: "agent", id: "agent-1", name: "support-agent" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true }, { name: "Read", owner: { type: "agent", id: "agent-1", name: "support-agent" }, schemaHash: "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", inputSchema: { type: "object", properties: { file_path: { type: "string" } } }, declared: true }, { name: "create_issue", owner: { type: "mcp_server", id: "srv-github", name: "github" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true, qualifiedName: "mcp__github__create_issue", capabilities: ["destructive"] }, { name: "list_issues", owner: { type: "mcp_server", id: "srv-github", name: "github" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true, qualifiedName: "mcp__github__list_issues", capabilities: [] }, { name: "delete_repo", owner: { type: "mcp_server", id: "srv-github", name: "github" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true, qualifiedName: "mcp__github__delete_repo", capabilities: ["destructive"] }, { name: "observed_only", owner: { type: "agent", id: "agent-1", name: "support-agent" }, schemaHash: null, declared: false }], expect: { errors: ["ambiguous_glob"], warnings: [] } },
946
+ { id: "VC-3c", name: "a bare name declared on two owners asks for the qualified form", yaml: "apiVersion: armor.io/v2\nkind: Policy\nmetadata:\n name: vector\n orgId: 11111111-1111-4111-8111-111111111111\ntarget:\n agent: aaaaaaaa-0000-4000-8000-000000000001\nspec:\n tools:\n default: hold\n rules:\n shared_tool: allow\n approvalDefaults: {approvers: 1, roles: [admin]}\n", inventory: [{ name: "shared_tool", owner: { type: "mcp_server", id: "srv-a", name: "a" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true }, { name: "shared_tool", owner: { type: "mcp_server", id: "srv-b", name: "b" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true }], expect: { errors: ["ambiguous_tool_key"], warnings: [] } },
947
+ { id: "VC-14c", name: "a capability key compiles as a capability statement and the report lists uncovered tools", yaml: "apiVersion: armor.io/v2\nkind: Policy\nmetadata:\n name: vector\n orgId: 11111111-1111-4111-8111-111111111111\ntarget:\n agent: aaaaaaaa-0000-4000-8000-000000000001\nspec:\n tools:\n default: hold\n rules:\n destructive: hold\n approvalDefaults: {approvers: 1, roles: [admin]}\n", inventory: [{ name: "create_payment", owner: { type: "agent", id: "agent-1", name: "support-agent" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true }, { name: "Read", owner: { type: "agent", id: "agent-1", name: "support-agent" }, schemaHash: "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", inputSchema: { type: "object", properties: { file_path: { type: "string" } } }, declared: true }, { name: "create_issue", owner: { type: "mcp_server", id: "srv-github", name: "github" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true, qualifiedName: "mcp__github__create_issue", capabilities: ["destructive"] }, { name: "list_issues", owner: { type: "mcp_server", id: "srv-github", name: "github" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true, qualifiedName: "mcp__github__list_issues", capabilities: [] }, { name: "delete_repo", owner: { type: "mcp_server", id: "srv-github", name: "github" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true, qualifiedName: "mcp__github__delete_repo", capabilities: ["destructive"] }, { name: "observed_only", owner: { type: "agent", id: "agent-1", name: "support-agent" }, schemaHash: null, declared: false }], expect: { errors: [], warnings: [], statementIds: ["st-destructive-0"], report: { sections: { tools: "enforced" }, notCoveredByCapabilityRules: ["Read", "create_payment", "mcp__github__list_issues", "observed_only"] } } },
948
+ { id: "VC-11", name: "enforceability on an enterprise target: files and network argument-only, skills and secrets inert", yaml: 'apiVersion: armor.io/v2\nkind: Policy\nmetadata:\n name: vector\n orgId: 11111111-1111-4111-8111-111111111111\ntarget:\n agent: aaaaaaaa-0000-4000-8000-000000000001\nspec:\n tools:\n default: hold\n rules:\n Read: allow\n approvalDefaults: {approvers: 1, roles: [admin]}\n files: {deny: ["~/.ssh/**"]}\n network: {default: block, allow: ["*.github.com"]}\n skills: {hold: ["*:deploy*"]}\n secrets: {envBlocklist: [AWS_SECRET_ACCESS_KEY]}\n', inventory: [{ name: "create_payment", owner: { type: "agent", id: "agent-1", name: "support-agent" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true }, { name: "Read", owner: { type: "agent", id: "agent-1", name: "support-agent" }, schemaHash: "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", inputSchema: { type: "object", properties: { file_path: { type: "string" } } }, declared: true }, { name: "create_issue", owner: { type: "mcp_server", id: "srv-github", name: "github" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true, qualifiedName: "mcp__github__create_issue", capabilities: ["destructive"] }, { name: "list_issues", owner: { type: "mcp_server", id: "srv-github", name: "github" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true, qualifiedName: "mcp__github__list_issues", capabilities: [] }, { name: "delete_repo", owner: { type: "mcp_server", id: "srv-github", name: "github" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true, qualifiedName: "mcp__github__delete_repo", capabilities: ["destructive"] }, { name: "observed_only", owner: { type: "agent", id: "agent-1", name: "support-agent" }, schemaHash: null, declared: false }], expect: { errors: [], warnings: [], statementIds: ["st-read-0", "st-files-block-0", "st-network-allow-0", "st-skills-hold-0", "st-secrets-block-0"], report: { sections: { tools: "enforced", files: "argument-only", network: "argument-only", skills: "inert", secrets: "inert" }, notCoveredByCapabilityRules: [] } } },
949
+ { id: "VC-11b", name: "enforceability on a local device: every section enforced", yaml: 'apiVersion: armor.io/v2\nkind: Policy\nmetadata:\n name: vector\ntarget: {device: local}\nspec:\n tools:\n default: hold\n rules:\n Read: allow\n approvalDefaults: {approvers: 1, roles: [admin]}\n files: {deny: ["~/.ssh/**"], allowOutsideWorkspace: false}\n secrets: {envBlocklist: [GITHUB_TOKEN]}\n', inventory: [], expect: { errors: [], warnings: ["unknown_tool_key"], statementIds: ["st-read-0", "st-files-block-0", "st-files-block-1", "st-secrets-block-0"], report: { sections: { tools: "enforced", files: "enforced", secrets: "enforced" }, notCoveredByCapabilityRules: [] } } },
950
+ { id: "VC-12", name: "a group target compiles with layer group", yaml: "apiVersion: armor.io/v2\nkind: Policy\nmetadata:\n name: vector\n orgId: 11111111-1111-4111-8111-111111111111\ntarget:\n group: payments\nspec:\n tools:\n default: hold\n rules:\n Read: allow\n approvalDefaults: {approvers: 1, roles: [admin]}\n", inventory: [{ name: "create_payment", owner: { type: "agent", id: "agent-1", name: "support-agent" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true }, { name: "Read", owner: { type: "agent", id: "agent-1", name: "support-agent" }, schemaHash: "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", inputSchema: { type: "object", properties: { file_path: { type: "string" } } }, declared: true }, { name: "create_issue", owner: { type: "mcp_server", id: "srv-github", name: "github" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true, qualifiedName: "mcp__github__create_issue", capabilities: ["destructive"] }, { name: "list_issues", owner: { type: "mcp_server", id: "srv-github", name: "github" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true, qualifiedName: "mcp__github__list_issues", capabilities: [] }, { name: "delete_repo", owner: { type: "mcp_server", id: "srv-github", name: "github" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true, qualifiedName: "mcp__github__delete_repo", capabilities: ["destructive"] }, { name: "observed_only", owner: { type: "agent", id: "agent-1", name: "support-agent" }, schemaHash: null, declared: false }], expect: { errors: [], warnings: [], statementIds: ["st-read-0"] } },
951
+ { id: "VC-16", name: "member rule expiry earlier than its scope wins; scope expiry bounds a rule with none", yaml: 'apiVersion: armor.io/v2\nkind: Policy\nmetadata:\n name: vector\n orgId: 11111111-1111-4111-8111-111111111111\ntarget:\n agent: aaaaaaaa-0000-4000-8000-000000000001\nspec:\n tools:\n default: hold\n rules:\n create_payment: block\n approvalDefaults: {approvers: 1, roles: [admin]}\n members:\n "alice@armoriq.io":\n tools:\n rules:\n create_payment:\n - action: allow\n expiresAt: 2026-06-01T00:00:00Z\n Read: allow\n expiresAt: 2026-12-31T00:00:00Z\n', inventory: [{ name: "create_payment", owner: { type: "agent", id: "agent-1", name: "support-agent" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true }, { name: "Read", owner: { type: "agent", id: "agent-1", name: "support-agent" }, schemaHash: "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", inputSchema: { type: "object", properties: { file_path: { type: "string" } } }, declared: true }, { name: "create_issue", owner: { type: "mcp_server", id: "srv-github", name: "github" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true, qualifiedName: "mcp__github__create_issue", capabilities: ["destructive"] }, { name: "list_issues", owner: { type: "mcp_server", id: "srv-github", name: "github" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true, qualifiedName: "mcp__github__list_issues", capabilities: [] }, { name: "delete_repo", owner: { type: "mcp_server", id: "srv-github", name: "github" }, schemaHash: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", inputSchema: { type: "object", properties: { amount: { type: "number" }, recipient: { type: "string" } } }, declared: true, qualifiedName: "mcp__github__delete_repo", capabilities: ["destructive"] }, { name: "observed_only", owner: { type: "agent", id: "agent-1", name: "support-agent" }, schemaHash: null, declared: false }], expect: { errors: [], warnings: ["loosening_grant", "loosening_grant"], statementIds: ["st-create-payment-0", "st-create-payment-alice-armoriq-io-0", "st-read-alice-armoriq-io-0"], expiries: { "st-create-payment-alice-armoriq-io-0": "2026-06-01T00:00:00.000Z", "st-read-alice-armoriq-io-0": "2026-12-31T00:00:00.000Z" } } },
952
+ { id: "VC-18c", name: "under device-first a products overlay may only tighten", yaml: "apiVersion: armor.io/v2\nkind: Policy\nmetadata:\n name: vector\ntarget: {device: local}\nspec:\n tools:\n default: hold\n rules:\n Bash: hold\n approvalDefaults: {approvers: 1, roles: [admin]}\n products:\n claude-code: {tools: {rules: {Bash: allow}}}\n", inventory: [], expect: { errors: ["device_first_loosening"], warnings: ["loosening_grant", "unknown_tool_key", "unknown_tool_key"] } },
953
+ { id: "VC-18d", name: "under agent-first a products overlay may loosen, flagged for review", yaml: "apiVersion: armor.io/v2\nkind: Policy\nmetadata:\n name: vector\nprecedence: agent-first\ntarget: {device: local}\nspec:\n tools:\n default: hold\n rules:\n Bash: hold\n approvalDefaults: {approvers: 1, roles: [admin]}\n products:\n claude-code: {tools: {rules: {Bash: allow}}}\n", inventory: [], expect: { errors: [], warnings: ["loosening_grant", "unknown_tool_key", "unknown_tool_key"], statementIds: ["st-bash-0", "st-bash-claude-code-0"] } }
954
+ ];
955
+
956
+ // src/vectors.ts
957
+ var vectors = {
958
+ canonical: canonical_default,
959
+ hash: hash_default,
960
+ schemaHash: schema_hash_vectors_default,
961
+ evaluate: evaluate_default,
962
+ document: document_default,
963
+ compile: compile_default
964
+ };
965
+ // Annotate the CommonJS export names for ESM import in node:
966
+ 0 && (module.exports = {
967
+ vectors
968
+ });
969
+ //# sourceMappingURL=vectors.cjs.map