funifier-mcp 0.3.17 → 0.3.18

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.
Files changed (40) hide show
  1. package/.cursor/rules/funifier.mdc +1 -0
  2. package/.github/copilot-instructions.md +1 -0
  3. package/AGENTS.md +1 -0
  4. package/datasource-funifier-docs/.coverage.json +12 -5
  5. package/datasource-funifier-docs/.search-index.json +10705 -10118
  6. package/datasource-funifier-docs/.skills-map.json +4 -0
  7. package/datasource-funifier-docs/.validation.json +72 -36
  8. package/datasource-funifier-docs/knowledge/guides/permission-audit.md +229 -0
  9. package/datasource-funifier-docs/knowledge/index.md +1 -0
  10. package/dist/mcp/bundle.js +108 -108
  11. package/dist/mcp/tools/_audit.d.ts +103 -0
  12. package/dist/mcp/tools/_audit.d.ts.map +1 -0
  13. package/dist/mcp/tools/_audit.js +241 -0
  14. package/dist/mcp/tools/_audit.js.map +1 -0
  15. package/dist/mcp/tools/_audit.test.d.ts +2 -0
  16. package/dist/mcp/tools/_audit.test.d.ts.map +1 -0
  17. package/dist/mcp/tools/_audit.test.js +412 -0
  18. package/dist/mcp/tools/_audit.test.js.map +1 -0
  19. package/dist/mcp/tools/_backup.d.ts +37 -3
  20. package/dist/mcp/tools/_backup.d.ts.map +1 -1
  21. package/dist/mcp/tools/_backup.js +137 -8
  22. package/dist/mcp/tools/_backup.js.map +1 -1
  23. package/dist/mcp/tools/_backup.test.js +195 -0
  24. package/dist/mcp/tools/_backup.test.js.map +1 -1
  25. package/dist/mcp/tools/_scope-engine.d.ts +40 -0
  26. package/dist/mcp/tools/_scope-engine.d.ts.map +1 -0
  27. package/dist/mcp/tools/_scope-engine.js +197 -0
  28. package/dist/mcp/tools/_scope-engine.js.map +1 -0
  29. package/dist/mcp/tools/_scope-engine.test.d.ts +2 -0
  30. package/dist/mcp/tools/_scope-engine.test.d.ts.map +1 -0
  31. package/dist/mcp/tools/_scope-engine.test.js +241 -0
  32. package/dist/mcp/tools/_scope-engine.test.js.map +1 -0
  33. package/dist/mcp/tools/permissions.d.ts.map +1 -1
  34. package/dist/mcp/tools/permissions.js +68 -11
  35. package/dist/mcp/tools/permissions.js.map +1 -1
  36. package/dist/mcp/tools/permissions.test.js +268 -4
  37. package/dist/mcp/tools/permissions.test.js.map +1 -1
  38. package/package.json +1 -1
  39. package/skills/funifier/SKILL.md +1 -0
  40. package/skills/funifier/references/audit-permissions.md +89 -0
@@ -0,0 +1,412 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const _audit_1 = require("./_audit");
5
+ // ─── Shared fixtures ──────────────────────────────────────────────────────────
6
+ const validEntry = {
7
+ method: "GET",
8
+ path: "/v3/game",
9
+ auth: "player",
10
+ evidence: "src/api.ts:42",
11
+ };
12
+ const minimalSecurity = {
13
+ apps: [{ name: "front", app_secret: "s3cr3t", scope: "read_player" }],
14
+ roles: [
15
+ { name: "public", scope: "read_game" },
16
+ { name: "player", scope: "read_player,write_action" },
17
+ ],
18
+ };
19
+ // ─── auditManifestSchema (T7 — schema validation) ────────────────────────────
20
+ (0, vitest_1.describe)("auditManifestSchema (T7)", () => {
21
+ (0, vitest_1.it)("accepts a valid version-1 manifest", () => {
22
+ const result = _audit_1.auditManifestSchema.safeParse({ version: 1, entries: [validEntry] });
23
+ (0, vitest_1.expect)(result.success).toBe(true);
24
+ });
25
+ (0, vitest_1.it)("normalizes method to uppercase", () => {
26
+ const result = _audit_1.auditManifestSchema.safeParse({
27
+ version: 1,
28
+ entries: [{ ...validEntry, method: "get" }],
29
+ });
30
+ (0, vitest_1.expect)(result.success).toBe(true);
31
+ if (result.success)
32
+ (0, vitest_1.expect)(result.data.entries[0].method).toBe("GET");
33
+ });
34
+ (0, vitest_1.it)("normalizes path without /v3 prefix by prepending /v3", () => {
35
+ const result = _audit_1.auditManifestSchema.safeParse({
36
+ version: 1,
37
+ entries: [{ ...validEntry, path: "/game" }],
38
+ });
39
+ (0, vitest_1.expect)(result.success).toBe(true);
40
+ if (result.success)
41
+ (0, vitest_1.expect)(result.data.entries[0].path).toBe("/v3/game");
42
+ });
43
+ (0, vitest_1.it)("normalizes bare path (no leading slash) by prepending /v3/", () => {
44
+ const result = _audit_1.auditManifestSchema.safeParse({
45
+ version: 1,
46
+ entries: [{ ...validEntry, path: "game" }],
47
+ });
48
+ (0, vitest_1.expect)(result.success).toBe(true);
49
+ if (result.success)
50
+ (0, vitest_1.expect)(result.data.entries[0].path).toBe("/v3/game");
51
+ });
52
+ (0, vitest_1.it)("defaults confidence to 'high'", () => {
53
+ const result = _audit_1.auditManifestSchema.safeParse({ version: 1, entries: [validEntry] });
54
+ (0, vitest_1.expect)(result.success).toBe(true);
55
+ if (result.success)
56
+ (0, vitest_1.expect)(result.data.entries[0].confidence).toBe("high");
57
+ });
58
+ (0, vitest_1.it)("accepts explicit confidence 'low'", () => {
59
+ const result = _audit_1.auditManifestSchema.safeParse({
60
+ version: 1,
61
+ entries: [{ ...validEntry, confidence: "low" }],
62
+ });
63
+ (0, vitest_1.expect)(result.success).toBe(true);
64
+ if (result.success)
65
+ (0, vitest_1.expect)(result.data.entries[0].confidence).toBe("low");
66
+ });
67
+ (0, vitest_1.it)("rejects manifest with more than 500 entries", () => {
68
+ const entries = Array.from({ length: 501 }, (_, i) => ({
69
+ ...validEntry,
70
+ path: `/v3/game/${i}`,
71
+ }));
72
+ const result = _audit_1.auditManifestSchema.safeParse({ version: 1, entries });
73
+ (0, vitest_1.expect)(result.success).toBe(false);
74
+ if (!result.success) {
75
+ (0, vitest_1.expect)(result.error.issues[0].message).toMatch(/500/);
76
+ }
77
+ });
78
+ (0, vitest_1.it)("rejects entry with empty auth (mandatory field)", () => {
79
+ const result = _audit_1.auditManifestSchema.safeParse({
80
+ version: 1,
81
+ entries: [{ ...validEntry, auth: "" }],
82
+ });
83
+ (0, vitest_1.expect)(result.success).toBe(false);
84
+ if (!result.success) {
85
+ const authIssue = result.error.issues.find((i) => i.path.includes("auth"));
86
+ (0, vitest_1.expect)(authIssue).toBeDefined();
87
+ }
88
+ });
89
+ (0, vitest_1.it)("rejects entry with missing evidence", () => {
90
+ const result = _audit_1.auditManifestSchema.safeParse({
91
+ version: 1,
92
+ entries: [{ method: "GET", path: "/v3/game", auth: "player" }],
93
+ });
94
+ (0, vitest_1.expect)(result.success).toBe(false);
95
+ });
96
+ (0, vitest_1.it)("rejects version other than 1", () => {
97
+ const result = _audit_1.auditManifestSchema.safeParse({ version: 2, entries: [] });
98
+ (0, vitest_1.expect)(result.success).toBe(false);
99
+ });
100
+ });
101
+ // ─── resolvePrincipal (T7 — principal resolution) ────────────────────────────
102
+ (0, vitest_1.describe)("resolvePrincipal (T7)", () => {
103
+ (0, vitest_1.it)("'public' → role:public scope", () => {
104
+ const p = (0, _audit_1.resolvePrincipal)("public", minimalSecurity);
105
+ (0, vitest_1.expect)(p.kind).toBe("role");
106
+ (0, vitest_1.expect)(p.label).toBe("role:public");
107
+ (0, vitest_1.expect)(p.scope).toBe("read_game");
108
+ });
109
+ (0, vitest_1.it)("'player' is an alias for role:player", () => {
110
+ const p = (0, _audit_1.resolvePrincipal)("player", minimalSecurity);
111
+ (0, vitest_1.expect)(p.kind).toBe("role");
112
+ (0, vitest_1.expect)(p.label).toBe("role:player");
113
+ (0, vitest_1.expect)(p.scope).toBe("read_player,write_action");
114
+ });
115
+ (0, vitest_1.it)("'role:player' (explicit form) resolves correctly", () => {
116
+ const p = (0, _audit_1.resolvePrincipal)("role:player", minimalSecurity);
117
+ (0, vitest_1.expect)(p.kind).toBe("role");
118
+ (0, vitest_1.expect)(p.label).toBe("role:player");
119
+ });
120
+ (0, vitest_1.it)("'role:<name>' resolves a named role", () => {
121
+ const sec = {
122
+ roles: [{ name: "premium", scope: "read_all" }],
123
+ };
124
+ const p = (0, _audit_1.resolvePrincipal)("role:premium", sec);
125
+ (0, vitest_1.expect)(p.kind).toBe("role");
126
+ (0, vitest_1.expect)(p.scope).toBe("read_all");
127
+ });
128
+ (0, vitest_1.it)("'app:<name>' resolves by app name", () => {
129
+ const p = (0, _audit_1.resolvePrincipal)("app:front", minimalSecurity);
130
+ (0, vitest_1.expect)(p.kind).toBe("app");
131
+ (0, vitest_1.expect)(p.label).toBe("app:front");
132
+ (0, vitest_1.expect)(p.scope).toBe("read_player");
133
+ });
134
+ (0, vitest_1.it)("'role:<name>' where role is absent → missing-principal", () => {
135
+ const p = (0, _audit_1.resolvePrincipal)("role:vip", minimalSecurity);
136
+ (0, vitest_1.expect)(p.kind).toBe("missing-principal");
137
+ (0, vitest_1.expect)(p.label).toBe("role:vip");
138
+ });
139
+ (0, vitest_1.it)("'app:<name>' where app is absent → missing-principal", () => {
140
+ const p = (0, _audit_1.resolvePrincipal)("app:unknown", minimalSecurity);
141
+ (0, vitest_1.expect)(p.kind).toBe("missing-principal");
142
+ });
143
+ (0, vitest_1.it)("unknown auth format → missing-principal", () => {
144
+ const p = (0, _audit_1.resolvePrincipal)("Bearer xyz", minimalSecurity);
145
+ (0, vitest_1.expect)(p.kind).toBe("missing-principal");
146
+ });
147
+ (0, vitest_1.it)("'public' when role:public absent in doc → missing-principal", () => {
148
+ const sec = { roles: [] };
149
+ const p = (0, _audit_1.resolvePrincipal)("public", sec);
150
+ (0, vitest_1.expect)(p.kind).toBe("missing-principal");
151
+ (0, vitest_1.expect)(p.label).toBe("role:public");
152
+ });
153
+ });
154
+ // ─── runAudit — per-principal diff (T8) ──────────────────────────────────────
155
+ (0, vitest_1.describe)("runAudit (T8 — per-principal diff)", () => {
156
+ (0, vitest_1.it)("produces a missing finding when an entry would be denied", () => {
157
+ const manifest = _audit_1.auditManifestSchema.parse({
158
+ version: 1,
159
+ entries: [{ method: "DELETE", path: "/v3/player", auth: "player", evidence: "src/api.ts:1" }],
160
+ });
161
+ // player scope has no delete token
162
+ const report = (0, _audit_1.runAudit)(manifest, minimalSecurity);
163
+ const missing = report.findings.filter((f) => f.severity === "missing");
164
+ (0, vitest_1.expect)(missing).toHaveLength(1);
165
+ (0, vitest_1.expect)(missing[0].principal).toBe("role:player");
166
+ (0, vitest_1.expect)(missing[0].requiredTokens).toContain("delete_player");
167
+ });
168
+ (0, vitest_1.it)("produces no missing finding when entry is allowed", () => {
169
+ const manifest = _audit_1.auditManifestSchema.parse({
170
+ version: 1,
171
+ entries: [{ method: "GET", path: "/v3/player", auth: "player", evidence: "src/api.ts:1" }],
172
+ });
173
+ const report = (0, _audit_1.runAudit)(manifest, minimalSecurity);
174
+ const missing = report.findings.filter((f) => f.severity === "missing" && f.principal === "role:player");
175
+ (0, vitest_1.expect)(missing).toHaveLength(0);
176
+ });
177
+ (0, vitest_1.it)("marks unused scope tokens as excess", () => {
178
+ const sec = {
179
+ roles: [{ name: "player", scope: "read_player,write_action,delete_player" }],
180
+ };
181
+ const manifest = _audit_1.auditManifestSchema.parse({
182
+ version: 1,
183
+ entries: [{ method: "GET", path: "/v3/player", auth: "player", evidence: "src/api.ts:1" }],
184
+ });
185
+ const report = (0, _audit_1.runAudit)(manifest, sec);
186
+ const excess = report.findings.filter((f) => f.severity === "excess");
187
+ const excessTokens = excess.flatMap((f) => f.excessTokens ?? []);
188
+ (0, vitest_1.expect)(excessTokens).toContain("write_action");
189
+ (0, vitest_1.expect)(excessTokens).toContain("delete_player");
190
+ (0, vitest_1.expect)(excessTokens).not.toContain("read_player");
191
+ });
192
+ (0, vitest_1.it)("write_all used-but-coverable → excess with narrowing suggestion", () => {
193
+ const sec = {
194
+ roles: [{ name: "player", scope: "write_all" }],
195
+ };
196
+ const manifest = _audit_1.auditManifestSchema.parse({
197
+ version: 1,
198
+ entries: [
199
+ { method: "POST", path: "/v3/game", auth: "player", evidence: "src/api.ts:10" },
200
+ { method: "POST", path: "/v3/player", auth: "player", evidence: "src/api.ts:11" },
201
+ ],
202
+ });
203
+ const report = (0, _audit_1.runAudit)(manifest, sec);
204
+ const narrowable = report.findings.filter((f) => f.rule === "broad-token-narrowable");
205
+ (0, vitest_1.expect)(narrowable).toHaveLength(1);
206
+ (0, vitest_1.expect)(narrowable[0].excessTokens).toContain("write_all");
207
+ (0, vitest_1.expect)(narrowable[0].narrowingSuggestion).toContain("write_game");
208
+ (0, vitest_1.expect)(narrowable[0].narrowingSuggestion).toContain("write_player");
209
+ });
210
+ (0, vitest_1.it)("exact token that IS used → no excess finding for that token", () => {
211
+ const sec = {
212
+ roles: [{ name: "player", scope: "write_game" }],
213
+ };
214
+ const manifest = _audit_1.auditManifestSchema.parse({
215
+ version: 1,
216
+ entries: [{ method: "POST", path: "/v3/game", auth: "player", evidence: "src/api.ts:1" }],
217
+ });
218
+ const report = (0, _audit_1.runAudit)(manifest, sec);
219
+ const excess = report.findings.filter((f) => f.severity === "excess");
220
+ (0, vitest_1.expect)(excess.flatMap((f) => f.excessTokens ?? [])).not.toContain("write_game");
221
+ });
222
+ (0, vitest_1.it)("database token used for /v3/database entries → NOT excess (genuinely needed)", () => {
223
+ const sec = {
224
+ roles: [{ name: "player", scope: "write_all,database" }],
225
+ };
226
+ const manifest = _audit_1.auditManifestSchema.parse({
227
+ version: 1,
228
+ entries: [
229
+ { method: "POST", path: "/v3/database/players", auth: "player", evidence: "src/api.ts:1" },
230
+ ],
231
+ });
232
+ const report = (0, _audit_1.runAudit)(manifest, sec);
233
+ // database is required for the database path; it's genuinely needed
234
+ const excessTokens = report.findings
235
+ .filter((f) => f.severity === "excess")
236
+ .flatMap((f) => f.excessTokens ?? []);
237
+ (0, vitest_1.expect)(excessTokens).not.toContain("database");
238
+ });
239
+ (0, vitest_1.it)("scopes are never pooled across principals", () => {
240
+ const sec = {
241
+ apps: [{ name: "backend", app_secret: "x", scope: "delete_player" }],
242
+ roles: [{ name: "player", scope: "read_player" }],
243
+ };
244
+ const manifest = _audit_1.auditManifestSchema.parse({
245
+ version: 1,
246
+ entries: [
247
+ { method: "DELETE", path: "/v3/player", auth: "player", evidence: "src/api.ts:1" },
248
+ { method: "GET", path: "/v3/player", auth: "app:backend", evidence: "src/api.ts:2" },
249
+ ],
250
+ });
251
+ const report = (0, _audit_1.runAudit)(manifest, sec);
252
+ // player trying DELETE must be denied (player scope has no delete)
253
+ const playerMissing = report.findings.filter((f) => f.severity === "missing" && f.principal === "role:player");
254
+ (0, vitest_1.expect)(playerMissing).toHaveLength(1);
255
+ // app:backend trying GET must be denied (backend scope has no read token)
256
+ const backendMissing = report.findings.filter((f) => f.severity === "missing" && f.principal === "app:backend");
257
+ (0, vitest_1.expect)(backendMissing).toHaveLength(1);
258
+ });
259
+ (0, vitest_1.it)("public paths → public-no-scope-needed, excluded from missing/excess math", () => {
260
+ const sec = {
261
+ roles: [{ name: "player", scope: "" }],
262
+ };
263
+ const manifest = _audit_1.auditManifestSchema.parse({
264
+ version: 1,
265
+ entries: [
266
+ { method: "GET", path: "/v3/widget/foo", auth: "player", evidence: "src/api.ts:1" },
267
+ ],
268
+ });
269
+ const report = (0, _audit_1.runAudit)(manifest, sec);
270
+ const publicFindings = report.findings.filter((f) => f.severity === "public-no-scope-needed");
271
+ (0, vitest_1.expect)(publicFindings).toHaveLength(1);
272
+ // No missing finding for a public path
273
+ const missing = report.findings.filter((f) => f.severity === "missing");
274
+ (0, vitest_1.expect)(missing).toHaveLength(0);
275
+ });
276
+ (0, vitest_1.it)("missing-principal entry produces a finding and does not crash the audit", () => {
277
+ const manifest = _audit_1.auditManifestSchema.parse({
278
+ version: 1,
279
+ entries: [
280
+ { method: "GET", path: "/v3/game", auth: "role:nonexistent", evidence: "src/api.ts:1" },
281
+ ],
282
+ });
283
+ const report = (0, _audit_1.runAudit)(manifest, minimalSecurity);
284
+ const mp = report.findings.filter((f) => f.severity === "missing-principal");
285
+ (0, vitest_1.expect)(mp).toHaveLength(1);
286
+ (0, vitest_1.expect)(mp[0].principal).toBe("role:nonexistent");
287
+ });
288
+ (0, vitest_1.it)("low-confidence entry note appears in the missing finding detail", () => {
289
+ const sec = {
290
+ roles: [{ name: "player", scope: "" }],
291
+ };
292
+ const manifest = _audit_1.auditManifestSchema.parse({
293
+ version: 1,
294
+ entries: [
295
+ {
296
+ method: "DELETE",
297
+ path: "/v3/player",
298
+ auth: "player",
299
+ evidence: "dynamic URL — best guess",
300
+ confidence: "low",
301
+ },
302
+ ],
303
+ });
304
+ const report = (0, _audit_1.runAudit)(manifest, sec);
305
+ const missing = report.findings.filter((f) => f.severity === "missing");
306
+ (0, vitest_1.expect)(missing[0].detail).toMatch(/low-confidence/);
307
+ });
308
+ });
309
+ // ─── runAudit — danger rules + notes (T9) ────────────────────────────────────
310
+ (0, vitest_1.describe)("runAudit (T9 — danger rules + completeness notes)", () => {
311
+ (0, vitest_1.it)("write_all on public role fires as danger with empty manifest", () => {
312
+ const sec = {
313
+ roles: [{ name: "public", scope: "write_all" }],
314
+ };
315
+ const manifest = _audit_1.auditManifestSchema.parse({ version: 1, entries: [] });
316
+ const report = (0, _audit_1.runAudit)(manifest, sec);
317
+ const danger = report.findings.filter((f) => f.severity === "danger" && f.principal === "role:public");
318
+ (0, vitest_1.expect)(danger.length).toBeGreaterThanOrEqual(1);
319
+ (0, vitest_1.expect)(danger.some((f) => f.detail.includes("write_all"))).toBe(true);
320
+ });
321
+ (0, vitest_1.it)("delete_all on public role fires as danger", () => {
322
+ const sec = {
323
+ roles: [{ name: "public", scope: "delete_all" }],
324
+ };
325
+ const manifest = _audit_1.auditManifestSchema.parse({ version: 1, entries: [] });
326
+ const report = (0, _audit_1.runAudit)(manifest, sec);
327
+ const danger = report.findings.filter((f) => f.severity === "danger" && f.detail.includes("delete_all"));
328
+ (0, vitest_1.expect)(danger).toHaveLength(1);
329
+ });
330
+ (0, vitest_1.it)("database keyword on public role fires as danger", () => {
331
+ const sec = {
332
+ roles: [{ name: "public", scope: "read_all,database" }],
333
+ };
334
+ const manifest = _audit_1.auditManifestSchema.parse({ version: 1, entries: [] });
335
+ const report = (0, _audit_1.runAudit)(manifest, sec);
336
+ const danger = report.findings.filter((f) => f.severity === "danger" && f.detail.includes("'database'"));
337
+ (0, vitest_1.expect)(danger).toHaveLength(1);
338
+ });
339
+ (0, vitest_1.it)("read_encrypted_field_values on public role fires as danger", () => {
340
+ const sec = {
341
+ roles: [{ name: "public", scope: "read_all,read_encrypted_field_values" }],
342
+ };
343
+ const manifest = _audit_1.auditManifestSchema.parse({ version: 1, entries: [] });
344
+ const report = (0, _audit_1.runAudit)(manifest, sec);
345
+ (0, vitest_1.expect)(report.findings.some((f) => f.severity === "danger" && f.detail.includes("read_encrypted_field_values"))).toBe(true);
346
+ });
347
+ (0, vitest_1.it)("read_encrypted_player_password on player role fires as danger", () => {
348
+ const sec = {
349
+ roles: [
350
+ { name: "public", scope: "read_game" },
351
+ { name: "player", scope: "read_player,read_encrypted_player_password" },
352
+ ],
353
+ };
354
+ const manifest = _audit_1.auditManifestSchema.parse({ version: 1, entries: [] });
355
+ const report = (0, _audit_1.runAudit)(manifest, sec);
356
+ const danger = report.findings.filter((f) => f.severity === "danger" &&
357
+ f.principal === "role:player" &&
358
+ f.detail.includes("read_encrypted_player_password"));
359
+ (0, vitest_1.expect)(danger).toHaveLength(1);
360
+ });
361
+ (0, vitest_1.it)("app with empty scope fires as danger", () => {
362
+ const sec = {
363
+ apps: [{ name: "broken-app", app_secret: "x", scope: "" }],
364
+ roles: [],
365
+ };
366
+ const manifest = _audit_1.auditManifestSchema.parse({ version: 1, entries: [] });
367
+ const report = (0, _audit_1.runAudit)(manifest, sec);
368
+ const danger = report.findings.filter((f) => f.severity === "danger" && f.rule === "empty-scope-app");
369
+ (0, vitest_1.expect)(danger).toHaveLength(1);
370
+ (0, vitest_1.expect)(danger[0].detail).toContain("broken-app");
371
+ });
372
+ (0, vitest_1.it)("empty manifest → completeness warning in notes (never empty success)", () => {
373
+ const manifest = _audit_1.auditManifestSchema.parse({ version: 1, entries: [] });
374
+ const report = (0, _audit_1.runAudit)(manifest, { roles: [], apps: [] });
375
+ (0, vitest_1.expect)(report.notes.some((n) => n.includes("No manifest entries"))).toBe(true);
376
+ (0, vitest_1.expect)(report.notes.length).toBeGreaterThanOrEqual(1);
377
+ });
378
+ (0, vitest_1.it)("Bearer freshness note is always present", () => {
379
+ const manifest = _audit_1.auditManifestSchema.parse({ version: 1, entries: [validEntry] });
380
+ const report = (0, _audit_1.runAudit)(manifest, minimalSecurity);
381
+ (0, vitest_1.expect)(report.notes.some((n) => n.includes("Bearer freshness"))).toBe(true);
382
+ });
383
+ (0, vitest_1.it)("MANUAL_REVIEW_TOKENS classified manual-review, never excess", () => {
384
+ const sec = {
385
+ roles: [{ name: "player", scope: "read_player,cross_domain,write_upload" }],
386
+ };
387
+ const manifest = _audit_1.auditManifestSchema.parse({
388
+ version: 1,
389
+ entries: [{ method: "GET", path: "/v3/player", auth: "player", evidence: "src/api.ts:1" }],
390
+ });
391
+ const report = (0, _audit_1.runAudit)(manifest, sec);
392
+ const manualReview = report.findings.filter((f) => f.severity === "manual-review");
393
+ const manualTokens = manualReview.map((f) => f.detail);
394
+ (0, vitest_1.expect)(manualTokens.some((d) => d.includes("cross_domain"))).toBe(true);
395
+ (0, vitest_1.expect)(manualTokens.some((d) => d.includes("write_upload"))).toBe(true);
396
+ // They must NOT appear as excess
397
+ const excessTokens = report.findings
398
+ .filter((f) => f.severity === "excess")
399
+ .flatMap((f) => f.excessTokens ?? []);
400
+ (0, vitest_1.expect)(excessTokens).not.toContain("cross_domain");
401
+ (0, vitest_1.expect)(excessTokens).not.toContain("write_upload");
402
+ });
403
+ (0, vitest_1.it)("danger findings from security doc plus completeness note makes report non-empty for blank manifest", () => {
404
+ const sec = {
405
+ roles: [{ name: "public", scope: "write_all" }],
406
+ };
407
+ const manifest = _audit_1.auditManifestSchema.parse({ version: 1, entries: [] });
408
+ const report = (0, _audit_1.runAudit)(manifest, sec);
409
+ (0, vitest_1.expect)(report.findings.length + report.notes.length).toBeGreaterThan(0);
410
+ });
411
+ });
412
+ //# sourceMappingURL=_audit.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_audit.test.js","sourceRoot":"","sources":["../../../src/mcp/tools/_audit.test.ts"],"names":[],"mappings":"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"}
@@ -67,11 +67,45 @@ export declare function ensureSelfIgnore(dir: string): void;
67
67
  * serialization failure — this throw is the abort signal that prevents the remote mutation.
68
68
  */
69
69
  export declare function captureBackup(snapshot: BackupSnapshot, root?: string): string;
70
+ export interface RestorableCheck {
71
+ check: string;
72
+ ok: boolean;
73
+ detail?: string;
74
+ }
75
+ /**
76
+ * Validates a snapshot against every precondition that `restore_backup` applies,
77
+ * without any I/O or side effects. Returns a named check list — never throws.
78
+ *
79
+ * Mirrors `applySecuritySnapshot` / `applyStudioRoleSnapshot` / `applyStudioAssignmentSnapshot`
80
+ * guards so capture-time, restore-time, and on-demand verification all use the same rules.
81
+ */
82
+ export declare function validateSnapshotRestorable(snapshot: BackupSnapshot, opts?: {
83
+ skipContentCheck?: boolean;
84
+ }): RestorableCheck[];
85
+ /**
86
+ * Asserts the snapshot passes all restore preconditions, throwing on the first failure.
87
+ * Used at capture time and restore time so both paths share the same check logic (PSEC-04).
88
+ */
89
+ export declare function assertSnapshotRestorable(snapshot: BackupSnapshot, opts?: {
90
+ skipContentCheck?: boolean;
91
+ }): void;
92
+ /**
93
+ * Reads and parses a snapshot file without throwing on format/schema errors.
94
+ * Returns a discriminated union for `verify_backup`'s FAIL-not-crash behavior (PSEC-05).
95
+ */
96
+ export type SafeSnapshotResult = {
97
+ ok: true;
98
+ snapshot: BackupSnapshot;
99
+ } | {
100
+ ok: false;
101
+ check: string;
102
+ detail: string;
103
+ };
104
+ export declare function safeReadSnapshot(filePath: string): SafeSnapshotResult;
70
105
  /**
71
106
  * Writes the snapshot, re-reads it from disk, and asserts the persisted bytes match.
72
- * For security snapshots, also asserts `apps` and `roles` arrays are present unless
73
- * `skipContentCheck` is true used by restore's own pre-backup where the live
74
- * document may already be truncated and a content check would block recovery.
107
+ * Then runs the shared restore-precondition validator so capture-time and restore-time
108
+ * checks can never drift apart (PSEC-01, PSEC-04).
75
109
  * Throws on any write/read-back/validation failure — callers must abort the mutation.
76
110
  */
77
111
  export declare function captureBackupVerified(snapshot: BackupSnapshot, root?: string, { skipContentCheck }?: {
@@ -1 +1 @@
1
- {"version":3,"file":"_backup.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/_backup.ts"],"names":[],"mappings":"AAIA;;;;;;;;;GASG;AAEH,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,aAAa,GAAG,mBAAmB,CAAC;AAE9E,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,CAAC,CAAC;IACX,qDAAqD;IACrD,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,cAAc,CAAC;IACzB,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,gHAAgH;IAChH,UAAU,CAAC,EAAE,cAAc,GAAG,aAAa,CAAC;IAC5C,2EAA2E;IAC3E,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,mCAAmC;IACnC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,uDAAuD;IACvD,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,cAAc,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAGnC;AAED,oFAAoF;AACpF,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,MAAqB,GAAG,MAAM,CAOlF;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,OAAO,GAAG,MAAM,CAYvD;AAcD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAKlD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,cAAc,EAAE,IAAI,GAAE,MAAqB,GAAG,MAAM,CAgB3F;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,cAAc,EACxB,IAAI,GAAE,MAAqB,EAC3B,EAAE,gBAAwB,EAAE,GAAE;IAAE,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAAO,GAChE,MAAM,CAwBR;AA4CD,mGAAmG;AACnG,wBAAgB,aAAa,CAAC,IAAI,GAAE,MAAqB,GAAG,cAAc,EAAE,CAqB3E;AAED,6FAA6F;AAC7F,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CAI7D;AA4ID;;;GAGG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CAWxF"}
1
+ {"version":3,"file":"_backup.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/_backup.ts"],"names":[],"mappings":"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"}