@theglitchking/hit-em-with-the-docs 2.7.1 → 2.8.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.
@@ -35,16 +35,16 @@ export declare const customDomainSchema: z.ZodObject<{
35
35
  id: string;
36
36
  name: string;
37
37
  description: string;
38
+ category: "features" | "development" | "core" | "advanced";
38
39
  keywords: string[];
39
40
  loadPriority: number;
40
- category: "features" | "core" | "development" | "advanced";
41
41
  }, {
42
42
  id: string;
43
43
  name: string;
44
44
  description: string;
45
+ category: "features" | "development" | "core" | "advanced";
45
46
  keywords: string[];
46
47
  loadPriority: number;
47
- category: "features" | "core" | "development" | "advanced";
48
48
  }>;
49
49
  export type CustomDomainConfig = z.infer<typeof customDomainSchema>;
50
50
  /**
@@ -88,6 +88,22 @@ declare const archiveConfigSchema: z.ZodDefault<z.ZodObject<{
88
88
  require_orphaned?: boolean | undefined;
89
89
  auto?: boolean | undefined;
90
90
  }>>;
91
+ /**
92
+ * Lifecycle enforcement (2.8.0). Governs the PreToolUse guard, which is what
93
+ * makes the policy binding on an agent rather than merely documented. Both
94
+ * rules default ON — but they are opt-out, because a guard nobody can disable
95
+ * is a guard people uninstall the plugin to escape.
96
+ */
97
+ declare const enforcementConfigSchema: z.ZodDefault<z.ZodObject<{
98
+ block_index_edits: z.ZodDefault<z.ZodBoolean>;
99
+ block_doc_deletion: z.ZodDefault<z.ZodBoolean>;
100
+ }, "strip", z.ZodTypeAny, {
101
+ block_index_edits: boolean;
102
+ block_doc_deletion: boolean;
103
+ }, {
104
+ block_index_edits?: boolean | undefined;
105
+ block_doc_deletion?: boolean | undefined;
106
+ }>>;
91
107
  declare const pluginConfigSchema: z.ZodObject<{
92
108
  vault: z.ZodDefault<z.ZodObject<{
93
109
  root: z.ZodDefault<z.ZodString>;
@@ -102,6 +118,16 @@ declare const pluginConfigSchema: z.ZodObject<{
102
118
  playbook_paths?: string[] | undefined;
103
119
  audit_window_days?: number | undefined;
104
120
  }>>;
121
+ enforcement: z.ZodDefault<z.ZodObject<{
122
+ block_index_edits: z.ZodDefault<z.ZodBoolean>;
123
+ block_doc_deletion: z.ZodDefault<z.ZodBoolean>;
124
+ }, "strip", z.ZodTypeAny, {
125
+ block_index_edits: boolean;
126
+ block_doc_deletion: boolean;
127
+ }, {
128
+ block_index_edits?: boolean | undefined;
129
+ block_doc_deletion?: boolean | undefined;
130
+ }>>;
105
131
  domains: z.ZodDefault<z.ZodEffects<z.ZodArray<z.ZodObject<{
106
132
  id: z.ZodString;
107
133
  name: z.ZodString;
@@ -113,23 +139,23 @@ declare const pluginConfigSchema: z.ZodObject<{
113
139
  id: string;
114
140
  name: string;
115
141
  description: string;
142
+ category: "features" | "development" | "core" | "advanced";
116
143
  keywords: string[];
117
144
  loadPriority: number;
118
- category: "features" | "core" | "development" | "advanced";
119
145
  }, {
120
146
  id: string;
121
147
  name: string;
122
148
  description: string;
149
+ category: "features" | "development" | "core" | "advanced";
123
150
  keywords: string[];
124
151
  loadPriority: number;
125
- category: "features" | "core" | "development" | "advanced";
126
152
  }>, "many">, {
127
153
  id: string;
128
154
  name: string;
129
155
  description: string;
156
+ category: "features" | "development" | "core" | "advanced";
130
157
  keywords: string[];
131
158
  loadPriority: number;
132
- category: "features" | "core" | "development" | "advanced";
133
159
  }[], unknown>>;
134
160
  archive: z.ZodDefault<z.ZodObject<{
135
161
  honor_status_deprecated: z.ZodDefault<z.ZodBoolean>;
@@ -161,6 +187,16 @@ declare const pluginConfigSchema: z.ZodObject<{
161
187
  playbook_paths?: string[] | undefined;
162
188
  audit_window_days?: number | undefined;
163
189
  }>>;
190
+ enforcement: z.ZodDefault<z.ZodObject<{
191
+ block_index_edits: z.ZodDefault<z.ZodBoolean>;
192
+ block_doc_deletion: z.ZodDefault<z.ZodBoolean>;
193
+ }, "strip", z.ZodTypeAny, {
194
+ block_index_edits: boolean;
195
+ block_doc_deletion: boolean;
196
+ }, {
197
+ block_index_edits?: boolean | undefined;
198
+ block_doc_deletion?: boolean | undefined;
199
+ }>>;
164
200
  domains: z.ZodDefault<z.ZodEffects<z.ZodArray<z.ZodObject<{
165
201
  id: z.ZodString;
166
202
  name: z.ZodString;
@@ -172,23 +208,23 @@ declare const pluginConfigSchema: z.ZodObject<{
172
208
  id: string;
173
209
  name: string;
174
210
  description: string;
211
+ category: "features" | "development" | "core" | "advanced";
175
212
  keywords: string[];
176
213
  loadPriority: number;
177
- category: "features" | "core" | "development" | "advanced";
178
214
  }, {
179
215
  id: string;
180
216
  name: string;
181
217
  description: string;
218
+ category: "features" | "development" | "core" | "advanced";
182
219
  keywords: string[];
183
220
  loadPriority: number;
184
- category: "features" | "core" | "development" | "advanced";
185
221
  }>, "many">, {
186
222
  id: string;
187
223
  name: string;
188
224
  description: string;
225
+ category: "features" | "development" | "core" | "advanced";
189
226
  keywords: string[];
190
227
  loadPriority: number;
191
- category: "features" | "core" | "development" | "advanced";
192
228
  }[], unknown>>;
193
229
  archive: z.ZodDefault<z.ZodObject<{
194
230
  honor_status_deprecated: z.ZodDefault<z.ZodBoolean>;
@@ -220,6 +256,16 @@ declare const pluginConfigSchema: z.ZodObject<{
220
256
  playbook_paths?: string[] | undefined;
221
257
  audit_window_days?: number | undefined;
222
258
  }>>;
259
+ enforcement: z.ZodDefault<z.ZodObject<{
260
+ block_index_edits: z.ZodDefault<z.ZodBoolean>;
261
+ block_doc_deletion: z.ZodDefault<z.ZodBoolean>;
262
+ }, "strip", z.ZodTypeAny, {
263
+ block_index_edits: boolean;
264
+ block_doc_deletion: boolean;
265
+ }, {
266
+ block_index_edits?: boolean | undefined;
267
+ block_doc_deletion?: boolean | undefined;
268
+ }>>;
223
269
  domains: z.ZodDefault<z.ZodEffects<z.ZodArray<z.ZodObject<{
224
270
  id: z.ZodString;
225
271
  name: z.ZodString;
@@ -231,23 +277,23 @@ declare const pluginConfigSchema: z.ZodObject<{
231
277
  id: string;
232
278
  name: string;
233
279
  description: string;
280
+ category: "features" | "development" | "core" | "advanced";
234
281
  keywords: string[];
235
282
  loadPriority: number;
236
- category: "features" | "core" | "development" | "advanced";
237
283
  }, {
238
284
  id: string;
239
285
  name: string;
240
286
  description: string;
287
+ category: "features" | "development" | "core" | "advanced";
241
288
  keywords: string[];
242
289
  loadPriority: number;
243
- category: "features" | "core" | "development" | "advanced";
244
290
  }>, "many">, {
245
291
  id: string;
246
292
  name: string;
247
293
  description: string;
294
+ category: "features" | "development" | "core" | "advanced";
248
295
  keywords: string[];
249
296
  loadPriority: number;
250
- category: "features" | "core" | "development" | "advanced";
251
297
  }[], unknown>>;
252
298
  archive: z.ZodDefault<z.ZodObject<{
253
299
  honor_status_deprecated: z.ZodDefault<z.ZodBoolean>;
@@ -267,6 +313,7 @@ declare const pluginConfigSchema: z.ZodObject<{
267
313
  }>>;
268
314
  }, z.ZodTypeAny, "passthrough">>;
269
315
  export type VaultConfig = z.infer<typeof vaultConfigSchema>;
316
+ export type EnforcementConfig = z.infer<typeof enforcementConfigSchema>;
270
317
  export type ArchiveConfig = z.infer<typeof archiveConfigSchema>;
271
318
  export type PluginConfig = z.infer<typeof pluginConfigSchema>;
272
319
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["file:///home/tmarlette/workspace/the-glitch-kingdom/hit-em-with-the-docs/src/utils/config.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,kBAAkB,mCAAmC,CAAC;AACnE,eAAO,MAAM,sBAAsB,UAA6B,CAAC;AACjE,eAAO,MAAM,yBAAyB,KAAK,CAAC;AAK5C;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,0DAKzB,CAAC;AAEX;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;EAO7B,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAgBpE;;;;GAIG;AACH,QAAA,MAAM,iBAAiB;;;;;;;;;;;;GAMT,CAAC;AAEf,eAAO,MAAM,8BAA8B,MAAM,CAAC;AAElD;;;;;GAKG;AACH,QAAA,MAAM,mBAAmB;;;;;;;;;;;;;;;GAWX,CAAC;AAEf,QAAA,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAMR,CAAC;AAEjB,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC5D,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAChE,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAI9D;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAkBlF;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,YAAY,CAiBvE;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAYlC;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,MAAM,CAAC,CAKjB;AAED,2EAA2E;AAC3E,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,MAAM,CAElF;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,YAAY,GACnB,MAAM,EAAE,CAEV"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["file:///home/tmarlette/workspace/the-glitch-kingdom/hit-em-with-the-docs/src/utils/config.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,kBAAkB,mCAAmC,CAAC;AACnE,eAAO,MAAM,sBAAsB,UAA6B,CAAC;AACjE,eAAO,MAAM,yBAAyB,KAAK,CAAC;AAK5C;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,0DAKzB,CAAC;AAEX;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;EAO7B,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAgBpE;;;;GAIG;AACH,QAAA,MAAM,iBAAiB;;;;;;;;;;;;GAMT,CAAC;AAEf,eAAO,MAAM,8BAA8B,MAAM,CAAC;AAElD;;;;;GAKG;AACH,QAAA,MAAM,mBAAmB;;;;;;;;;;;;;;;GAWX,CAAC;AAEf;;;;;GAKG;AACH,QAAA,MAAM,uBAAuB;;;;;;;;;GAKf,CAAC;AAEf,QAAA,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAOR,CAAC;AAEjB,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC5D,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AACxE,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAChE,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAI9D;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAkBlF;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,YAAY,CAiBvE;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAYlC;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,MAAM,CAAC,CAKjB;AAED,2EAA2E;AAC3E,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,MAAM,CAElF;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,YAAY,GACnB,MAAM,EAAE,CAEV"}
@@ -9,10 +9,21 @@ export interface GlobOptions {
9
9
  */
10
10
  export declare function glob(pattern: string, options?: GlobOptions): Promise<string[]>;
11
11
  /**
12
- * Reserved documentation subdirectory for DEPRECATED docs. Anything under
13
- * `<docs>/archive/` is intentionally excluded from every hewtd scan (audit,
14
- * link-check, metadata-sync, integrate dup-detection, link graph, search) —
15
- * it's a parking lot for retired docs, not part of the active corpus.
12
+ * Reserved documentation subdirectory for DEPRECATED docs.
13
+ *
14
+ * **Archived content is referenceable, never concrete.** A link *into* the
15
+ * archive still resolves link-check validates targets by file existence, so
16
+ * history stays reachable. But nothing under an `archive/` folder is part of
17
+ * the active corpus: it is not indexed, not audited, not metadata-validated,
18
+ * not dup-checked, and never counted. It is what the docs *used* to say, and it
19
+ * is never evidence of what is true now.
20
+ *
21
+ * The exclusion applies at **any depth** — `<docs>/archive/` and
22
+ * `<docs>/features/archive/` alike. Before 2.8.0 the ignore glob was anchored
23
+ * at the docs root, so a nested `archive/` was still scanned and validated
24
+ * (while 2.7.1's indexer correctly skipped it) — archived docs could raise
25
+ * audit errors and stale-metadata warnings for content nobody was supposed to
26
+ * be reading.
16
27
  */
17
28
  export declare const ARCHIVE_DIR = "archive";
18
29
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"glob.d.ts","sourceRoot":"","sources":["file:///home/tmarlette/workspace/the-glitch-kingdom/hit-em-with-the-docs/src/utils/glob.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED;;GAEG;AACH,wBAAsB,IAAI,CACxB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,MAAM,EAAE,CAAC,CAiBnB;AAED;;;;;GAKG;AACH,eAAO,MAAM,WAAW,YAAY,CAAC;AAUrC;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,WAAW,EAAE,UAAU,CAAM,GAC1C,OAAO,CAAC,MAAM,EAAE,CAAC,CAQnB;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO/D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOhE;AAED;;GAEG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO3D;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAStE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEpE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGpD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD"}
1
+ {"version":3,"file":"glob.d.ts","sourceRoot":"","sources":["file:///home/tmarlette/workspace/the-glitch-kingdom/hit-em-with-the-docs/src/utils/glob.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED;;GAEG;AACH,wBAAsB,IAAI,CACxB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,MAAM,EAAE,CAAC,CAiBnB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,WAAW,YAAY,CAAC;AAWrC;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,WAAW,EAAE,UAAU,CAAM,GAC1C,OAAO,CAAC,MAAM,EAAE,CAAC,CAQnB;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO/D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOhE;AAED;;GAEG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO3D;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAStE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEpE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGpD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Lifecycle enforcement — the decision function behind the PreToolUse hook.
3
+ *
4
+ * hewtd's lifecycle policy has always been enforced at the CLI boundary (the
5
+ * archive link guard, `auto: false`, the frontmatter schema). None of that
6
+ * binds an *agent*, which will happily `rm` a doc, hand-edit a generated
7
+ * INDEX.md, or invent its own `docs/` folder. This is the part the model
8
+ * cannot reason its way past: the harness runs it, and a `deny` is final.
9
+ *
10
+ * Two rules deny, because they destroy work or corrupt a generated artifact.
11
+ * Everything else at most warns. Anything unrecognized is allowed — this runs
12
+ * in every session the plugin is installed in, including repos that have
13
+ * nothing to do with hewtd, so the cost of a false positive is far higher
14
+ * than the cost of a miss.
15
+ */
16
+ export type GuardDecision = {
17
+ action: 'allow';
18
+ } | {
19
+ action: 'warn';
20
+ context: string;
21
+ } | {
22
+ action: 'deny';
23
+ reason: string;
24
+ };
25
+ export interface GuardInput {
26
+ toolName: string;
27
+ /** `file_path` for Write/Edit. */
28
+ filePath?: string;
29
+ /** `command` for Bash. */
30
+ command?: string;
31
+ /** `content` (Write) or `new_string` (Edit) — used to spot lifecycle changes. */
32
+ text?: string;
33
+ /** Docs root relative to the project, e.g. `.documentation`. */
34
+ docsDir: string;
35
+ }
36
+ /** Which enforcement rules are active. Both default on; users can opt out. */
37
+ export interface EnforcementPolicy {
38
+ blockIndexEdits: boolean;
39
+ blockDocDeletion: boolean;
40
+ }
41
+ export declare const DEFAULT_ENFORCEMENT: EnforcementPolicy;
42
+ /**
43
+ * Is this path inside an `archive/` folder, at any depth?
44
+ *
45
+ * Archived docs are **referenceable but never concrete** — history you may cite,
46
+ * never evidence of what is true now. Nothing under an `archive/` folder is
47
+ * indexed, audited, link-checked, or validated.
48
+ */
49
+ export declare function isArchived(path: string): boolean;
50
+ /**
51
+ * Decide what to do about one tool call. Pure — all I/O lives in the hook.
52
+ */
53
+ export declare function evaluate(input: GuardInput, policy?: EnforcementPolicy): GuardDecision;
54
+ //# sourceMappingURL=guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../../../src/core/enforce/guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAOH,MAAM,MAAM,aAAa,GACrB;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,GACnB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvC,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,kCAAkC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0BAA0B;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,8EAA8E;AAC9E,MAAM,WAAW,iBAAiB;IAChC,eAAe,EAAE,OAAO,CAAC;IACzB,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED,eAAO,MAAM,mBAAmB,EAAE,iBAGjC,CAAC;AAOF;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAIhD;AA4BD;;GAEG;AACH,wBAAgB,QAAQ,CACtB,KAAK,EAAE,UAAU,EACjB,MAAM,GAAE,iBAAuC,GAC9C,aAAa,CA4Gf"}
@@ -0,0 +1,201 @@
1
+ /**
2
+ * Lifecycle enforcement — the decision function behind the PreToolUse hook.
3
+ *
4
+ * hewtd's lifecycle policy has always been enforced at the CLI boundary (the
5
+ * archive link guard, `auto: false`, the frontmatter schema). None of that
6
+ * binds an *agent*, which will happily `rm` a doc, hand-edit a generated
7
+ * INDEX.md, or invent its own `docs/` folder. This is the part the model
8
+ * cannot reason its way past: the harness runs it, and a `deny` is final.
9
+ *
10
+ * Two rules deny, because they destroy work or corrupt a generated artifact.
11
+ * Everything else at most warns. Anything unrecognized is allowed — this runs
12
+ * in every session the plugin is installed in, including repos that have
13
+ * nothing to do with hewtd, so the cost of a false positive is far higher
14
+ * than the cost of a miss.
15
+ */
16
+ import { basename } from 'path';
17
+ /** Files hewtd generates and owns. Hand-editing them is always wrong. */
18
+ const GENERATED_FILES = new Set(['INDEX.md', 'REGISTRY.md']);
19
+ export const DEFAULT_ENFORCEMENT = {
20
+ blockIndexEdits: true,
21
+ blockDocDeletion: true,
22
+ };
23
+ /** Posix-normalized, leading-`./`-stripped path for matching. */
24
+ function normalize(p) {
25
+ return p.replace(/\\/g, '/').replace(/^\.\//, '');
26
+ }
27
+ /**
28
+ * Is this path inside an `archive/` folder, at any depth?
29
+ *
30
+ * Archived docs are **referenceable but never concrete** — history you may cite,
31
+ * never evidence of what is true now. Nothing under an `archive/` folder is
32
+ * indexed, audited, link-checked, or validated.
33
+ */
34
+ export function isArchived(path) {
35
+ return normalize(path)
36
+ .split('/')
37
+ .some((segment) => segment === 'archive');
38
+ }
39
+ /** Is this path inside the documentation tree? */
40
+ function inDocsTree(path, docsDir) {
41
+ const p = normalize(path);
42
+ const d = normalize(docsDir);
43
+ return p === d || p.includes(`/${d}/`) || p.startsWith(`${d}/`);
44
+ }
45
+ /**
46
+ * Shell commands that destroy a file. `mv` is deliberately absent: moving a
47
+ * doc is how `archive` itself works (via `git mv`), and a hand-rolled move is
48
+ * a warn, not a denial — it loses the frontmatter stamping, but loses nothing.
49
+ */
50
+ const DESTRUCTIVE_RE = /(^|[\s;&|(])(rm|unlink|shred)\s|(^|[\s;&|(])git\s+rm\s/;
51
+ /** Markdown paths a shell command names. */
52
+ function markdownTargets(command, docsDir) {
53
+ const d = normalize(docsDir);
54
+ const re = new RegExp(`[^\\s'"\`;&|]*${d}/[^\\s'"\`;&|]*\\.md`, 'g');
55
+ return command.match(re) ?? [];
56
+ }
57
+ /** Does this text set `status: deprecated` in frontmatter? */
58
+ function setsDeprecated(text) {
59
+ return /^\s*status:\s*['"]?deprecated['"]?\s*$/m.test(text);
60
+ }
61
+ /**
62
+ * Decide what to do about one tool call. Pure — all I/O lives in the hook.
63
+ */
64
+ export function evaluate(input, policy = DEFAULT_ENFORCEMENT) {
65
+ const { toolName, filePath, command, text, docsDir } = input;
66
+ // ---- Write / Edit -------------------------------------------------------
67
+ if ((toolName === 'Write' || toolName === 'Edit') && filePath) {
68
+ const inTree = inDocsTree(filePath, docsDir);
69
+ // DENY: a generated index is not a document. Editing it by hand is either
70
+ // pointless (the next `hewtd index` overwrites it) or actively harmful
71
+ // (it is how people ended up hand-curating rows the indexer then deleted
72
+ // — see issue #12).
73
+ if (policy.blockIndexEdits && inTree && GENERATED_FILES.has(basename(filePath))) {
74
+ return {
75
+ action: 'deny',
76
+ reason: `${basename(filePath)} is a generated artifact, rebuilt from the documents ` +
77
+ `on disk. Hand-edits are overwritten by the next \`hewtd index\` or ` +
78
+ `\`hewtd maintain\`. To change what it lists, change the documents — then ` +
79
+ `run \`hewtd index\`.`,
80
+ };
81
+ }
82
+ // WARN: a doc outside the tree is invisible to every hewtd scan. Scoped to
83
+ // markdown that is plausibly *documentation* — a rival `docs/` folder, or a
84
+ // loose doc at the repo root. Warning on every .md anywhere (a fixture, a
85
+ // subpackage README, a website's own docs) would be noise, and a noisy
86
+ // guard is one people switch off.
87
+ if (!inTree && looksLikeStrayDoc(filePath)) {
88
+ return {
89
+ action: 'warn',
90
+ context: `This project manages its documentation with hit-em-with-the-docs, under ` +
91
+ `\`${docsDir}/\`. A markdown file outside that tree is not indexed, ` +
92
+ `link-checked, or metadata-validated. \`hewtd integrate <file>\` classifies ` +
93
+ `a doc into a domain and registers it.`,
94
+ };
95
+ }
96
+ // WARN: archived content is historical. Editing it is not destructive —
97
+ // hence a warn, not a denial — but it is almost always a mistake: the edit
98
+ // lands in a subtree that no scan reads and no index lists, so it changes
99
+ // nothing anyone will see.
100
+ if (inTree && isArchived(filePath)) {
101
+ return {
102
+ action: 'warn',
103
+ context: `This file is under an \`archive/\` folder. Archived documentation is ` +
104
+ `historical: it is excluded from every hewtd scan — not indexed, not ` +
105
+ `audited, not link-checked, not validated — and describes what the docs ` +
106
+ `used to say, not what is true now. It can be referenced, but it is never ` +
107
+ `evidence of current behavior. \`hewtd unarchive <file>\` restores it to ` +
108
+ `its domain as an active document.`,
109
+ };
110
+ }
111
+ // WARN: `status: deprecated` flags intent but leaves the doc live and
112
+ // indexed. Archiving is the separate step that actually retires it.
113
+ if (inTree && text && setsDeprecated(text)) {
114
+ return {
115
+ action: 'warn',
116
+ context: `\`status: deprecated\` marks intent but leaves the document in its domain ` +
117
+ `folder, still indexed and still scanned. \`hewtd archive <file>\` retires ` +
118
+ `it: the move is reversible (\`archived_from\` records the origin) and ` +
119
+ `link-safe (it refuses if active docs still link to it).`,
120
+ };
121
+ }
122
+ return { action: 'allow' };
123
+ }
124
+ // ---- Bash ---------------------------------------------------------------
125
+ if (toolName === 'Bash' && command) {
126
+ const targets = markdownTargets(command, docsDir);
127
+ if (targets.length === 0)
128
+ return { action: 'allow' };
129
+ // DENY: deleting a doc is the one truly irreversible act, and hewtd has a
130
+ // purpose-built, reversible, link-safe alternative. This is the whole
131
+ // reason the plugin never calls rm/unlink anywhere in its own source.
132
+ if (policy.blockDocDeletion && DESTRUCTIVE_RE.test(command)) {
133
+ return {
134
+ action: 'deny',
135
+ reason: `Deleting documentation is destructive and hewtd never does it. ` +
136
+ `\`hewtd archive ${targets[0]}\` retires a doc instead: it moves the file ` +
137
+ `under \`archive/\` (preserving git history), stamps \`archived_from\` so ` +
138
+ `\`hewtd unarchive\` can restore it exactly, and refuses if active docs ` +
139
+ `still link to it. Use \`--force\` there to override the link guard.`,
140
+ };
141
+ }
142
+ // WARN: a hand-rolled move into archive/ skips the frontmatter stamping,
143
+ // so `unarchive` has no `archived_from` to restore from.
144
+ if (/(^|[\s;&|(])(mv|git\s+mv)\s/.test(command) && /archive\//.test(command)) {
145
+ return {
146
+ action: 'warn',
147
+ context: `Moving a doc into \`archive/\` by hand skips the lifecycle stamping. ` +
148
+ `\`hewtd archive <file>\` records \`archived_on\`, \`archived_from\`, and ` +
149
+ `\`archived_reason\`, which is what makes \`hewtd unarchive\` lossless; a ` +
150
+ `plain move leaves nothing to restore from.`,
151
+ };
152
+ }
153
+ return { action: 'allow' };
154
+ }
155
+ return { action: 'allow' };
156
+ }
157
+ /** A repo's own top-level markdown — never documentation-tree content. */
158
+ const PROJECT_FILES = new Set([
159
+ 'README.MD',
160
+ 'CHANGELOG.MD',
161
+ 'CONTRIBUTING.MD',
162
+ 'LICENSE.MD',
163
+ 'CLAUDE.MD',
164
+ 'AGENTS.MD',
165
+ 'SECURITY.MD',
166
+ 'CODE_OF_CONDUCT.MD',
167
+ ]);
168
+ /** Folder names that mean "somebody is starting a rival documentation tree". */
169
+ const RIVAL_DOC_DIRS = new Set(['docs', 'doc', 'documentation', 'wiki', 'guides']);
170
+ /**
171
+ * Is this markdown a *stray document* — something that ought to have gone
172
+ * through `integrate`?
173
+ *
174
+ * Deliberately narrow. It catches the real failure mode (an agent creating
175
+ * `docs/how-it-works.md` in a repo that already has a managed tree, or dropping
176
+ * a loose doc at the root) and stays silent on markdown that is obviously not
177
+ * documentation: source fixtures, subpackage READMEs, a website's own content,
178
+ * agent scaffolding. Anything it misses is merely un-nagged; anything it
179
+ * over-claims is a papercut on every unrelated file the user writes.
180
+ */
181
+ function looksLikeStrayDoc(filePath) {
182
+ const p = normalize(filePath);
183
+ if (!p.endsWith('.md'))
184
+ return false;
185
+ const segments = p.split('/');
186
+ const name = basename(p).toUpperCase();
187
+ // Agent/tooling scaffolding and dependencies are never docs.
188
+ if (segments.some((s) => s === 'node_modules' || s === '.planning' || s === '.claude')) {
189
+ return false;
190
+ }
191
+ // A rival docs folder anywhere in the path.
192
+ if (segments.slice(0, -1).some((s) => RIVAL_DOC_DIRS.has(s.toLowerCase()))) {
193
+ return true;
194
+ }
195
+ // A loose doc sitting at the repo root that isn't one of the standard
196
+ // project files.
197
+ if (segments.length === 1 && !PROJECT_FILES.has(name))
198
+ return true;
199
+ return false;
200
+ }
201
+ //# sourceMappingURL=guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guard.js","sourceRoot":"","sources":["../../../src/core/enforce/guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAEhC,yEAAyE;AACzE,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC,CAAC;AAyB7D,MAAM,CAAC,MAAM,mBAAmB,GAAsB;IACpD,eAAe,EAAE,IAAI;IACrB,gBAAgB,EAAE,IAAI;CACvB,CAAC;AAEF,iEAAiE;AACjE,SAAS,SAAS,CAAC,CAAS;IAC1B,OAAO,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AACpD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,OAAO,SAAS,CAAC,IAAI,CAAC;SACnB,KAAK,CAAC,GAAG,CAAC;SACV,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC;AAC9C,CAAC;AAED,kDAAkD;AAClD,SAAS,UAAU,CAAC,IAAY,EAAE,OAAe;IAC/C,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAC1B,MAAM,CAAC,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IAC7B,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAClE,CAAC;AAED;;;;GAIG;AACH,MAAM,cAAc,GAAG,wDAAwD,CAAC;AAEhF,4CAA4C;AAC5C,SAAS,eAAe,CAAC,OAAe,EAAE,OAAe;IACvD,MAAM,CAAC,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IAC7B,MAAM,EAAE,GAAG,IAAI,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,GAAG,CAAC,CAAC;IACrE,OAAO,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;AACjC,CAAC;AAED,8DAA8D;AAC9D,SAAS,cAAc,CAAC,IAAY;IAClC,OAAO,yCAAyC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC9D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,QAAQ,CACtB,KAAiB,EACjB,SAA4B,mBAAmB;IAE/C,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;IAE7D,4EAA4E;IAC5E,IAAI,CAAC,QAAQ,KAAK,OAAO,IAAI,QAAQ,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QAC9D,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAE7C,0EAA0E;QAC1E,uEAAuE;QACvE,yEAAyE;QACzE,oBAAoB;QACpB,IAAI,MAAM,CAAC,eAAe,IAAI,MAAM,IAAI,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;YAChF,OAAO;gBACL,MAAM,EAAE,MAAM;gBACd,MAAM,EACJ,GAAG,QAAQ,CAAC,QAAQ,CAAC,uDAAuD;oBAC5E,qEAAqE;oBACrE,2EAA2E;oBAC3E,sBAAsB;aACzB,CAAC;QACJ,CAAC;QAED,2EAA2E;QAC3E,4EAA4E;QAC5E,0EAA0E;QAC1E,uEAAuE;QACvE,kCAAkC;QAClC,IAAI,CAAC,MAAM,IAAI,iBAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC3C,OAAO;gBACL,MAAM,EAAE,MAAM;gBACd,OAAO,EACL,0EAA0E;oBAC1E,KAAK,OAAO,yDAAyD;oBACrE,6EAA6E;oBAC7E,uCAAuC;aAC1C,CAAC;QACJ,CAAC;QAED,wEAAwE;QACxE,2EAA2E;QAC3E,0EAA0E;QAC1E,2BAA2B;QAC3B,IAAI,MAAM,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACnC,OAAO;gBACL,MAAM,EAAE,MAAM;gBACd,OAAO,EACL,uEAAuE;oBACvE,sEAAsE;oBACtE,yEAAyE;oBACzE,2EAA2E;oBAC3E,0EAA0E;oBAC1E,mCAAmC;aACtC,CAAC;QACJ,CAAC;QAED,sEAAsE;QACtE,oEAAoE;QACpE,IAAI,MAAM,IAAI,IAAI,IAAI,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3C,OAAO;gBACL,MAAM,EAAE,MAAM;gBACd,OAAO,EACL,4EAA4E;oBAC5E,4EAA4E;oBAC5E,wEAAwE;oBACxE,yDAAyD;aAC5D,CAAC;QACJ,CAAC;QAED,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IAC7B,CAAC;IAED,4EAA4E;IAC5E,IAAI,QAAQ,KAAK,MAAM,IAAI,OAAO,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAClD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;QAErD,0EAA0E;QAC1E,sEAAsE;QACtE,sEAAsE;QACtE,IAAI,MAAM,CAAC,gBAAgB,IAAI,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5D,OAAO;gBACL,MAAM,EAAE,MAAM;gBACd,MAAM,EACJ,iEAAiE;oBACjE,mBAAmB,OAAO,CAAC,CAAC,CAAC,8CAA8C;oBAC3E,2EAA2E;oBAC3E,yEAAyE;oBACzE,qEAAqE;aACxE,CAAC;QACJ,CAAC;QAED,yEAAyE;QACzE,yDAAyD;QACzD,IAAI,6BAA6B,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAC7E,OAAO;gBACL,MAAM,EAAE,MAAM;gBACd,OAAO,EACL,uEAAuE;oBACvE,2EAA2E;oBAC3E,2EAA2E;oBAC3E,4CAA4C;aAC/C,CAAC;QACJ,CAAC;QAED,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IAC7B,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AAC7B,CAAC;AAED,0EAA0E;AAC1E,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC;IAC5B,WAAW;IACX,cAAc;IACd,iBAAiB;IACjB,YAAY;IACZ,WAAW;IACX,WAAW;IACX,aAAa;IACb,oBAAoB;CACrB,CAAC,CAAC;AAEH,gFAAgF;AAChF,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;AAEnF;;;;;;;;;;GAUG;AACH,SAAS,iBAAiB,CAAC,QAAgB;IACzC,MAAM,CAAC,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IAC9B,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAErC,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9B,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAEvC,6DAA6D;IAC7D,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,cAAc,IAAI,CAAC,KAAK,WAAW,IAAI,CAAC,KAAK,SAAS,CAAC,EAAE,CAAC;QACvF,OAAO,KAAK,CAAC;IACf,CAAC;IAED,4CAA4C;IAC5C,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,CAAC;QAC3E,OAAO,IAAI,CAAC;IACd,CAAC;IAED,sEAAsE;IACtE,iBAAiB;IACjB,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAEnE,OAAO,KAAK,CAAC;AACf,CAAC"}
package/dist/index.d.ts CHANGED
@@ -34,6 +34,7 @@ export * from './reports/link-report.js';
34
34
  export * from './core/archive/manage.js';
35
35
  export * from './core/archive/candidates.js';
36
36
  export * from './core/archive/links.js';
37
+ export * from './core/enforce/guard.js';
37
38
  export * from './core/metadata/errors.js';
38
39
  export * from './core/knowledge-base/citers.js';
39
40
  export * from './generators/facts-index.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,8BAA8B,CAAC;AAG7C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,8BAA8B,CAAC;AAG7C,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AAGpC,cAAc,0BAA0B,CAAC;AACzC,cAAc,iCAAiC,CAAC;AAChD,cAAc,oCAAoC,CAAC;AACnD,cAAc,4BAA4B,CAAC;AAG3C,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,iCAAiC,CAAC;AAGhD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iCAAiC,CAAC;AAChD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,iCAAiC,CAAC;AAGhD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AAGzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yBAAyB,CAAC;AAGxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iCAAiC,CAAC;AAChD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iCAAiC,CAAC;AAChD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,8BAA8B,CAAC;AAG7C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,8BAA8B,CAAC;AAG7C,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AAGpC,cAAc,0BAA0B,CAAC;AACzC,cAAc,iCAAiC,CAAC;AAChD,cAAc,oCAAoC,CAAC;AACnD,cAAc,4BAA4B,CAAC;AAG3C,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,iCAAiC,CAAC;AAGhD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iCAAiC,CAAC;AAChD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,iCAAiC,CAAC;AAGhD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AAGzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yBAAyB,CAAC;AAGxC,cAAc,yBAAyB,CAAC;AAGxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iCAAiC,CAAC;AAChD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iCAAiC,CAAC;AAChD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC"}
package/dist/index.js CHANGED
@@ -42,6 +42,8 @@ export * from './reports/link-report.js';
42
42
  export * from './core/archive/manage.js';
43
43
  export * from './core/archive/candidates.js';
44
44
  export * from './core/archive/links.js';
45
+ // Lifecycle enforcement (2.8.0+)
46
+ export * from './core/enforce/guard.js';
45
47
  // Knowledge-base primitives (2.3.0+)
46
48
  export * from './core/metadata/errors.js';
47
49
  export * from './core/knowledge-base/citers.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,qBAAqB;AACrB,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,8BAA8B,CAAC;AAE7C,kBAAkB;AAClB,cAAc,2BAA2B,CAAC;AAC1C,cAAc,8BAA8B,CAAC;AAE7C,YAAY;AACZ,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AAEpC,aAAa;AACb,cAAc,0BAA0B,CAAC;AACzC,cAAc,iCAAiC,CAAC;AAChD,cAAc,oCAAoC,CAAC;AACnD,cAAc,4BAA4B,CAAC;AAE3C,kBAAkB;AAClB,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,iCAAiC,CAAC;AAEhD,mBAAmB;AACnB,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iCAAiC,CAAC;AAChD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,iCAAiC,CAAC;AAEhD,UAAU;AACV,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AAEzC,4BAA4B;AAC5B,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yBAAyB,CAAC;AAExC,qCAAqC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iCAAiC,CAAC;AAChD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iCAAiC,CAAC;AAChD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,qBAAqB;AACrB,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,8BAA8B,CAAC;AAE7C,kBAAkB;AAClB,cAAc,2BAA2B,CAAC;AAC1C,cAAc,8BAA8B,CAAC;AAE7C,YAAY;AACZ,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AAEpC,aAAa;AACb,cAAc,0BAA0B,CAAC;AACzC,cAAc,iCAAiC,CAAC;AAChD,cAAc,oCAAoC,CAAC;AACnD,cAAc,4BAA4B,CAAC;AAE3C,kBAAkB;AAClB,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,iCAAiC,CAAC;AAEhD,mBAAmB;AACnB,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iCAAiC,CAAC;AAChD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,iCAAiC,CAAC;AAEhD,UAAU;AACV,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AAEzC,4BAA4B;AAC5B,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yBAAyB,CAAC;AAExC,iCAAiC;AACjC,cAAc,yBAAyB,CAAC;AAExC,qCAAqC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iCAAiC,CAAC;AAChD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iCAAiC,CAAC;AAChD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC"}
@@ -88,6 +88,22 @@ declare const archiveConfigSchema: z.ZodDefault<z.ZodObject<{
88
88
  require_orphaned?: boolean | undefined;
89
89
  auto?: boolean | undefined;
90
90
  }>>;
91
+ /**
92
+ * Lifecycle enforcement (2.8.0). Governs the PreToolUse guard, which is what
93
+ * makes the policy binding on an agent rather than merely documented. Both
94
+ * rules default ON — but they are opt-out, because a guard nobody can disable
95
+ * is a guard people uninstall the plugin to escape.
96
+ */
97
+ declare const enforcementConfigSchema: z.ZodDefault<z.ZodObject<{
98
+ block_index_edits: z.ZodDefault<z.ZodBoolean>;
99
+ block_doc_deletion: z.ZodDefault<z.ZodBoolean>;
100
+ }, "strip", z.ZodTypeAny, {
101
+ block_index_edits: boolean;
102
+ block_doc_deletion: boolean;
103
+ }, {
104
+ block_index_edits?: boolean | undefined;
105
+ block_doc_deletion?: boolean | undefined;
106
+ }>>;
91
107
  declare const pluginConfigSchema: z.ZodObject<{
92
108
  vault: z.ZodDefault<z.ZodObject<{
93
109
  root: z.ZodDefault<z.ZodString>;
@@ -102,6 +118,16 @@ declare const pluginConfigSchema: z.ZodObject<{
102
118
  playbook_paths?: string[] | undefined;
103
119
  audit_window_days?: number | undefined;
104
120
  }>>;
121
+ enforcement: z.ZodDefault<z.ZodObject<{
122
+ block_index_edits: z.ZodDefault<z.ZodBoolean>;
123
+ block_doc_deletion: z.ZodDefault<z.ZodBoolean>;
124
+ }, "strip", z.ZodTypeAny, {
125
+ block_index_edits: boolean;
126
+ block_doc_deletion: boolean;
127
+ }, {
128
+ block_index_edits?: boolean | undefined;
129
+ block_doc_deletion?: boolean | undefined;
130
+ }>>;
105
131
  domains: z.ZodDefault<z.ZodEffects<z.ZodArray<z.ZodObject<{
106
132
  id: z.ZodString;
107
133
  name: z.ZodString;
@@ -161,6 +187,16 @@ declare const pluginConfigSchema: z.ZodObject<{
161
187
  playbook_paths?: string[] | undefined;
162
188
  audit_window_days?: number | undefined;
163
189
  }>>;
190
+ enforcement: z.ZodDefault<z.ZodObject<{
191
+ block_index_edits: z.ZodDefault<z.ZodBoolean>;
192
+ block_doc_deletion: z.ZodDefault<z.ZodBoolean>;
193
+ }, "strip", z.ZodTypeAny, {
194
+ block_index_edits: boolean;
195
+ block_doc_deletion: boolean;
196
+ }, {
197
+ block_index_edits?: boolean | undefined;
198
+ block_doc_deletion?: boolean | undefined;
199
+ }>>;
164
200
  domains: z.ZodDefault<z.ZodEffects<z.ZodArray<z.ZodObject<{
165
201
  id: z.ZodString;
166
202
  name: z.ZodString;
@@ -220,6 +256,16 @@ declare const pluginConfigSchema: z.ZodObject<{
220
256
  playbook_paths?: string[] | undefined;
221
257
  audit_window_days?: number | undefined;
222
258
  }>>;
259
+ enforcement: z.ZodDefault<z.ZodObject<{
260
+ block_index_edits: z.ZodDefault<z.ZodBoolean>;
261
+ block_doc_deletion: z.ZodDefault<z.ZodBoolean>;
262
+ }, "strip", z.ZodTypeAny, {
263
+ block_index_edits: boolean;
264
+ block_doc_deletion: boolean;
265
+ }, {
266
+ block_index_edits?: boolean | undefined;
267
+ block_doc_deletion?: boolean | undefined;
268
+ }>>;
223
269
  domains: z.ZodDefault<z.ZodEffects<z.ZodArray<z.ZodObject<{
224
270
  id: z.ZodString;
225
271
  name: z.ZodString;
@@ -267,6 +313,7 @@ declare const pluginConfigSchema: z.ZodObject<{
267
313
  }>>;
268
314
  }, z.ZodTypeAny, "passthrough">>;
269
315
  export type VaultConfig = z.infer<typeof vaultConfigSchema>;
316
+ export type EnforcementConfig = z.infer<typeof enforcementConfigSchema>;
270
317
  export type ArchiveConfig = z.infer<typeof archiveConfigSchema>;
271
318
  export type PluginConfig = z.infer<typeof pluginConfigSchema>;
272
319
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,kBAAkB,mCAAmC,CAAC;AACnE,eAAO,MAAM,sBAAsB,UAA6B,CAAC;AACjE,eAAO,MAAM,yBAAyB,KAAK,CAAC;AAK5C;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,0DAKzB,CAAC;AAEX;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;EAO7B,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAgBpE;;;;GAIG;AACH,QAAA,MAAM,iBAAiB;;;;;;;;;;;;GAMT,CAAC;AAEf,eAAO,MAAM,8BAA8B,MAAM,CAAC;AAElD;;;;;GAKG;AACH,QAAA,MAAM,mBAAmB;;;;;;;;;;;;;;;GAWX,CAAC;AAEf,QAAA,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAMR,CAAC;AAEjB,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC5D,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAChE,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAI9D;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAkBlF;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,YAAY,CAiBvE;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAYlC;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,MAAM,CAAC,CAKjB;AAED,2EAA2E;AAC3E,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,MAAM,CAElF;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,YAAY,GACnB,MAAM,EAAE,CAEV"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,kBAAkB,mCAAmC,CAAC;AACnE,eAAO,MAAM,sBAAsB,UAA6B,CAAC;AACjE,eAAO,MAAM,yBAAyB,KAAK,CAAC;AAK5C;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,0DAKzB,CAAC;AAEX;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;EAO7B,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAgBpE;;;;GAIG;AACH,QAAA,MAAM,iBAAiB;;;;;;;;;;;;GAMT,CAAC;AAEf,eAAO,MAAM,8BAA8B,MAAM,CAAC;AAElD;;;;;GAKG;AACH,QAAA,MAAM,mBAAmB;;;;;;;;;;;;;;;GAWX,CAAC;AAEf;;;;;GAKG;AACH,QAAA,MAAM,uBAAuB;;;;;;;;;GAKf,CAAC;AAEf,QAAA,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAOR,CAAC;AAEjB,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC5D,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AACxE,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAChE,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAI9D;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAkBlF;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,YAAY,CAiBvE;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAYlC;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,MAAM,CAAC,CAKjB;AAED,2EAA2E;AAC3E,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,MAAM,CAElF;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,YAAY,GACnB,MAAM,EAAE,CAEV"}
@@ -87,9 +87,22 @@ const archiveConfigSchema = z
87
87
  auto: z.boolean().default(false),
88
88
  })
89
89
  .default({});
90
+ /**
91
+ * Lifecycle enforcement (2.8.0). Governs the PreToolUse guard, which is what
92
+ * makes the policy binding on an agent rather than merely documented. Both
93
+ * rules default ON — but they are opt-out, because a guard nobody can disable
94
+ * is a guard people uninstall the plugin to escape.
95
+ */
96
+ const enforcementConfigSchema = z
97
+ .object({
98
+ block_index_edits: z.boolean().default(true),
99
+ block_doc_deletion: z.boolean().default(true),
100
+ })
101
+ .default({});
90
102
  const pluginConfigSchema = z
91
103
  .object({
92
104
  vault: vaultConfigSchema,
105
+ enforcement: enforcementConfigSchema,
93
106
  domains: lenientDomainsArray,
94
107
  archive: archiveConfigSchema,
95
108
  })