@wrongstack/core 0.285.0 → 0.286.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.
Files changed (145) hide show
  1. package/dist/autophase/phase-orchestrator.d.ts.map +1 -1
  2. package/dist/boot.d.ts.map +1 -1
  3. package/dist/coordination/agent-monitor.d.ts +29 -0
  4. package/dist/coordination/agent-monitor.d.ts.map +1 -1
  5. package/dist/coordination/autonomous-brain.d.ts +0 -2
  6. package/dist/coordination/autonomous-brain.d.ts.map +1 -1
  7. package/dist/coordination/autonomous-coordinator.d.ts +4 -0
  8. package/dist/coordination/autonomous-coordinator.d.ts.map +1 -1
  9. package/dist/coordination/brain-ledger.d.ts +142 -0
  10. package/dist/coordination/brain-ledger.d.ts.map +1 -0
  11. package/dist/coordination/brain-monitor.d.ts +31 -2
  12. package/dist/coordination/brain-monitor.d.ts.map +1 -1
  13. package/dist/coordination/brain.d.ts +43 -0
  14. package/dist/coordination/brain.d.ts.map +1 -1
  15. package/dist/coordination/delegate-tool.d.ts.map +1 -1
  16. package/dist/coordination/director-construction.d.ts.map +1 -1
  17. package/dist/coordination/director.d.ts +1 -1
  18. package/dist/coordination/director.d.ts.map +1 -1
  19. package/dist/coordination/fleet.d.ts +4 -4
  20. package/dist/coordination/fleet.d.ts.map +1 -1
  21. package/dist/coordination/global-mailbox.d.ts +63 -2
  22. package/dist/coordination/global-mailbox.d.ts.map +1 -1
  23. package/dist/coordination/index.d.ts +2 -1
  24. package/dist/coordination/index.d.ts.map +1 -1
  25. package/dist/coordination/index.js +1566 -462
  26. package/dist/coordination/index.js.map +4 -4
  27. package/dist/coordination/knowledge-graph.d.ts +13 -1
  28. package/dist/coordination/knowledge-graph.d.ts.map +1 -1
  29. package/dist/coordination/mailbox-actions.d.ts +12 -13
  30. package/dist/coordination/mailbox-actions.d.ts.map +1 -1
  31. package/dist/coordination/mailbox-constants.d.ts +64 -0
  32. package/dist/coordination/mailbox-constants.d.ts.map +1 -0
  33. package/dist/coordination/mailbox-events.d.ts +32 -0
  34. package/dist/coordination/mailbox-events.d.ts.map +1 -0
  35. package/dist/coordination/mailbox-message-codec.d.ts +8 -0
  36. package/dist/coordination/mailbox-message-codec.d.ts.map +1 -0
  37. package/dist/coordination/mailbox-types.d.ts +88 -4
  38. package/dist/coordination/mailbox-types.d.ts.map +1 -1
  39. package/dist/coordination/mailbox.d.ts +21 -2
  40. package/dist/coordination/mailbox.d.ts.map +1 -1
  41. package/dist/coordination/package-author-tracker.d.ts.map +1 -1
  42. package/dist/coordination/subagent-result-tool.d.ts.map +1 -1
  43. package/dist/defaults/index.js +846 -523
  44. package/dist/defaults/index.js.map +4 -4
  45. package/dist/execution/autonomous-runner.d.ts +7 -1
  46. package/dist/execution/autonomous-runner.d.ts.map +1 -1
  47. package/dist/execution/autonomy-brain.d.ts +72 -11
  48. package/dist/execution/autonomy-brain.d.ts.map +1 -1
  49. package/dist/execution/brain-chain.d.ts +53 -0
  50. package/dist/execution/brain-chain.d.ts.map +1 -0
  51. package/dist/execution/brain-evaluation.d.ts +66 -0
  52. package/dist/execution/brain-evaluation.d.ts.map +1 -0
  53. package/dist/execution/brain-runtime.d.ts +171 -0
  54. package/dist/execution/brain-runtime.d.ts.map +1 -0
  55. package/dist/execution/council-brain.d.ts +79 -0
  56. package/dist/execution/council-brain.d.ts.map +1 -0
  57. package/dist/execution/eternal-autonomy.d.ts +12 -0
  58. package/dist/execution/eternal-autonomy.d.ts.map +1 -1
  59. package/dist/execution/index.d.ts +5 -1
  60. package/dist/execution/index.d.ts.map +1 -1
  61. package/dist/execution/index.js +1350 -377
  62. package/dist/execution/index.js.map +4 -4
  63. package/dist/execution/parallel-eternal-engine.d.ts +12 -0
  64. package/dist/execution/parallel-eternal-engine.d.ts.map +1 -1
  65. package/dist/execution/tool-executor.d.ts.map +1 -1
  66. package/dist/hq/auth-store.d.ts +21 -3
  67. package/dist/hq/auth-store.d.ts.map +1 -1
  68. package/dist/hq/factory.d.ts +3 -0
  69. package/dist/hq/factory.d.ts.map +1 -1
  70. package/dist/hq/index.js +628 -72
  71. package/dist/hq/index.js.map +4 -4
  72. package/dist/hq/protocol.d.ts +54 -2
  73. package/dist/hq/protocol.d.ts.map +1 -1
  74. package/dist/hq/publisher.d.ts +4 -0
  75. package/dist/hq/publisher.d.ts.map +1 -1
  76. package/dist/index.d.ts +12 -6
  77. package/dist/index.d.ts.map +1 -1
  78. package/dist/index.js +3482 -1495
  79. package/dist/index.js.map +4 -4
  80. package/dist/kernel/events.d.ts +22 -4
  81. package/dist/kernel/events.d.ts.map +1 -1
  82. package/dist/kernel/index.js.map +2 -2
  83. package/dist/mailbox-attach.d.ts.map +1 -1
  84. package/dist/observability/index.js +16 -15
  85. package/dist/observability/index.js.map +2 -2
  86. package/dist/security/index.d.ts +1 -0
  87. package/dist/security/index.d.ts.map +1 -1
  88. package/dist/security/index.js +253 -21
  89. package/dist/security/index.js.map +4 -4
  90. package/dist/security/permission-policy-schema.d.ts +77 -0
  91. package/dist/security/permission-policy-schema.d.ts.map +1 -0
  92. package/dist/security/permission-policy.d.ts +5 -0
  93. package/dist/security/permission-policy.d.ts.map +1 -1
  94. package/dist/security/secret-vault.d.ts +9 -0
  95. package/dist/security/secret-vault.d.ts.map +1 -1
  96. package/dist/session-registry.d.ts.map +1 -1
  97. package/dist/storage/config-loader.d.ts +10 -0
  98. package/dist/storage/config-loader.d.ts.map +1 -1
  99. package/dist/storage/goal-store.d.ts +1 -1
  100. package/dist/storage/goal-store.d.ts.map +1 -1
  101. package/dist/storage/index.js +147 -162
  102. package/dist/storage/index.js.map +2 -2
  103. package/dist/storage/plan-store.d.ts +1 -1
  104. package/dist/storage/plan-store.d.ts.map +1 -1
  105. package/dist/storage/queue-store.d.ts +4 -0
  106. package/dist/storage/queue-store.d.ts.map +1 -1
  107. package/dist/storage/session-store.d.ts +9 -0
  108. package/dist/storage/session-store.d.ts.map +1 -1
  109. package/dist/storage/task-store.d.ts +1 -1
  110. package/dist/storage/task-store.d.ts.map +1 -1
  111. package/dist/storage/todos-checkpoint.d.ts +2 -2
  112. package/dist/storage/todos-checkpoint.d.ts.map +1 -1
  113. package/dist/types/config.d.ts +209 -1
  114. package/dist/types/config.d.ts.map +1 -1
  115. package/dist/types/index.js +11 -0
  116. package/dist/types/index.js.map +2 -2
  117. package/dist/types/multi-agent.d.ts +8 -0
  118. package/dist/types/multi-agent.d.ts.map +1 -1
  119. package/dist/types/observability.d.ts +5 -0
  120. package/dist/types/observability.d.ts.map +1 -1
  121. package/dist/types/tool.d.ts +7 -0
  122. package/dist/types/tool.d.ts.map +1 -1
  123. package/dist/utils/glob-expand.d.ts.map +1 -1
  124. package/dist/utils/incoming-images.d.ts +39 -0
  125. package/dist/utils/incoming-images.d.ts.map +1 -0
  126. package/dist/utils/index.d.ts +1 -0
  127. package/dist/utils/index.d.ts.map +1 -1
  128. package/dist/utils/index.js +81 -3
  129. package/dist/utils/index.js.map +3 -3
  130. package/dist/worktree/worktree-manager.d.ts +13 -4
  131. package/dist/worktree/worktree-manager.d.ts.map +1 -1
  132. package/instructions/agents/browser.md +25 -16
  133. package/instructions/coordination/subagent-baseline.md +16 -2
  134. package/instructions/leader-after-task.md +3 -1
  135. package/instructions/sections/tool/common-patterns.md +7 -1
  136. package/instructions/system.md +47 -0
  137. package/package.json +2 -2
  138. package/skills/docker-deploy/SKILL.md +1 -1
  139. package/skills/wrongstack-mailbox/SKILL.md +51 -12
  140. package/dist/plugins/git-plugin.d.ts +0 -15
  141. package/dist/plugins/git-plugin.d.ts.map +0 -1
  142. package/dist/plugins/observability-plugin.d.ts +0 -19
  143. package/dist/plugins/observability-plugin.d.ts.map +0 -1
  144. package/dist/plugins/plan-plugin.d.ts +0 -16
  145. package/dist/plugins/plan-plugin.d.ts.map +0 -1
@@ -705,31 +705,40 @@ function unwrapDataKey(buf, keyFile) {
705
705
  });
706
706
  }
707
707
  }
708
- function checkKeyFilePermissions(keyFile) {
708
+ function checkKeyFilePermissions(keyFile, opts) {
709
709
  if (process.platform === "win32") return;
710
+ const warn = opts?.warn ?? ((msg) => console.warn(msg));
710
711
  try {
711
712
  const stat2 = fs2.statSync(keyFile);
712
713
  const actualMode = stat2.mode & 511;
713
714
  if (actualMode !== KEY_FILE_MODE) {
714
- console.warn(JSON.stringify({
715
- level: "warn",
716
- event: "vault.key_file_wrong_permissions",
717
- message: `Key file ${keyFile} has mode ${actualMode.toString(8)} \u2014 expected ${KEY_FILE_MODE.toString(8)}. Run: chmod ${KEY_FILE_MODE.toString(8)} ${keyFile}`,
718
- keyFile,
719
- expectedMode: KEY_FILE_MODE,
720
- actualMode,
721
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
722
- }));
715
+ warn(
716
+ `Key file ${keyFile} has mode ${actualMode.toString(8)} \u2014 expected ${KEY_FILE_MODE.toString(8)}. Run: chmod ${KEY_FILE_MODE.toString(8)} ${keyFile}`
717
+ );
723
718
  }
724
719
  } catch {
725
720
  }
726
721
  }
727
722
  var DefaultSecretVault = class {
728
723
  keyFile;
724
+ logger;
729
725
  key;
730
726
  _keyVersion = 1;
731
727
  constructor(opts) {
732
728
  this.keyFile = opts.keyFile;
729
+ this.logger = opts.logger;
730
+ }
731
+ /**
732
+ * Emit a structured warning. Uses the configured Logger when available;
733
+ * falls back to console.warn(JSON) so warnings are never silently dropped
734
+ * during early boot.
735
+ */
736
+ logWarn(msg, ctx) {
737
+ if (this.logger) {
738
+ this.logger.warn(msg, ctx);
739
+ } else {
740
+ console.warn(JSON.stringify({ ...ctx, message: msg, timestamp: (/* @__PURE__ */ new Date()).toISOString() }));
741
+ }
733
742
  }
734
743
  /** Current key version. Starts at 1; incremented by rotateKey(). */
735
744
  get keyVersion() {
@@ -808,7 +817,7 @@ var DefaultSecretVault = class {
808
817
  newKey.copy(keyFileBuf, KEY_FILE_MAGIC.length + 1);
809
818
  fs2.writeFileSync(this.keyFile, keyFileBuf, { mode: 384 });
810
819
  }
811
- checkKeyFilePermissions(this.keyFile);
820
+ checkKeyFilePermissions(this.keyFile, { warn: (msg) => this.logWarn(msg) });
812
821
  this.key = newKey;
813
822
  this._keyVersion = newVersion;
814
823
  return { oldVersion, newVersion };
@@ -827,7 +836,7 @@ var DefaultSecretVault = class {
827
836
  fs2.writeFileSync(this.keyFile, wrapDataKey(this.key, this._keyVersion, passphrase), {
828
837
  mode: 384
829
838
  });
830
- checkKeyFilePermissions(this.keyFile);
839
+ checkKeyFilePermissions(this.keyFile, { warn: (msg) => this.logWarn(msg) });
831
840
  } catch {
832
841
  }
833
842
  }
@@ -839,13 +848,13 @@ var DefaultSecretVault = class {
839
848
  const { key: key2, version } = unwrapDataKey(buf, this.keyFile);
840
849
  this.key = key2;
841
850
  this._keyVersion = version;
842
- checkKeyFilePermissions(this.keyFile);
851
+ checkKeyFilePermissions(this.keyFile, { warn: (msg) => this.logWarn(msg) });
843
852
  return this.key;
844
853
  }
845
854
  if (buf.length === KEY_BYTES) {
846
855
  this.key = buf;
847
856
  this._keyVersion = 1;
848
- checkKeyFilePermissions(this.keyFile);
857
+ checkKeyFilePermissions(this.keyFile, { warn: (msg) => this.logWarn(msg) });
849
858
  this.migrateToWrappedIfPassphrase();
850
859
  return this.key;
851
860
  }
@@ -869,7 +878,7 @@ var DefaultSecretVault = class {
869
878
  }
870
879
  this.key = Buffer.from(key2);
871
880
  this._keyVersion = version;
872
- checkKeyFilePermissions(this.keyFile);
881
+ checkKeyFilePermissions(this.keyFile, { warn: (msg) => this.logWarn(msg) });
873
882
  this.migrateToWrappedIfPassphrase();
874
883
  return this.key;
875
884
  }
@@ -894,13 +903,13 @@ var DefaultSecretVault = class {
894
903
  const { key: winnerKey, version } = unwrapDataKey(buf, this.keyFile);
895
904
  this.key = winnerKey;
896
905
  this._keyVersion = version;
897
- checkKeyFilePermissions(this.keyFile);
906
+ checkKeyFilePermissions(this.keyFile, { warn: (msg) => this.logWarn(msg) });
898
907
  return this.key;
899
908
  }
900
909
  if (buf.length === KEY_BYTES) {
901
910
  this.key = buf;
902
911
  this._keyVersion = 1;
903
- checkKeyFilePermissions(this.keyFile);
912
+ checkKeyFilePermissions(this.keyFile, { warn: (msg) => this.logWarn(msg) });
904
913
  return this.key;
905
914
  }
906
915
  if (buf.length === VERSIONED_KEY_FILE_SIZE) {
@@ -916,7 +925,7 @@ var DefaultSecretVault = class {
916
925
  const winnerKey = buf.subarray(KEY_FILE_MAGIC.length + 1);
917
926
  this.key = Buffer.from(winnerKey);
918
927
  this._keyVersion = version;
919
- checkKeyFilePermissions(this.keyFile);
928
+ checkKeyFilePermissions(this.keyFile, { warn: (msg) => this.logWarn(msg) });
920
929
  return this.key;
921
930
  }
922
931
  throw new ConfigError({
@@ -1207,6 +1216,173 @@ function getDangerousCapabilities(toolOrCaps) {
1207
1216
  );
1208
1217
  }
1209
1218
 
1219
+ // src/security/permission-policy-schema.ts
1220
+ var TRUST_POLICY_SCHEMA_VERSION = 1;
1221
+ var TRUST_POLICY_LIMITS = Object.freeze({
1222
+ maxTools: 1e3,
1223
+ maxPatternsPerRule: 1e3,
1224
+ maxToolNameChars: 256,
1225
+ maxPatternChars: 4096
1226
+ });
1227
+ var TRUST_POLICY_JSON_SCHEMA = Object.freeze({
1228
+ $schema: "https://json-schema.org/draft/2020-12/schema",
1229
+ $id: "https://wrongstack.dev/schemas/trust-policy-v1.json",
1230
+ title: "WrongStack Trust Policy",
1231
+ type: "object",
1232
+ maxProperties: TRUST_POLICY_LIMITS.maxTools,
1233
+ propertyNames: {
1234
+ minLength: 1,
1235
+ maxLength: TRUST_POLICY_LIMITS.maxToolNameChars,
1236
+ not: { enum: ["__proto__", "prototype", "constructor"] }
1237
+ },
1238
+ additionalProperties: {
1239
+ type: "object",
1240
+ additionalProperties: false,
1241
+ properties: {
1242
+ allow: {
1243
+ type: "array",
1244
+ maxItems: TRUST_POLICY_LIMITS.maxPatternsPerRule,
1245
+ items: { type: "string", minLength: 1, maxLength: TRUST_POLICY_LIMITS.maxPatternChars }
1246
+ },
1247
+ deny: {
1248
+ type: "array",
1249
+ maxItems: TRUST_POLICY_LIMITS.maxPatternsPerRule,
1250
+ items: { type: "string", minLength: 1, maxLength: TRUST_POLICY_LIMITS.maxPatternChars }
1251
+ },
1252
+ auto: { type: "boolean" },
1253
+ trustWorkdir: { type: "boolean" },
1254
+ denyPrivate: { type: "boolean" }
1255
+ }
1256
+ }
1257
+ });
1258
+ var RULE_FIELDS = /* @__PURE__ */ new Set(["allow", "deny", "auto", "trustWorkdir", "denyPrivate"]);
1259
+ var UNSAFE_PROPERTY_NAMES = /* @__PURE__ */ new Set(["__proto__", "prototype", "constructor"]);
1260
+ function isRecord(value) {
1261
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1262
+ }
1263
+ function error(diagnostics, code, path3, message) {
1264
+ diagnostics.push({ severity: "error", code, path: path3, message });
1265
+ }
1266
+ function validatePatterns(value, path3, diagnostics) {
1267
+ if (!Array.isArray(value)) {
1268
+ error(diagnostics, "invalid_pattern_list", path3, "must be an array of strings");
1269
+ return void 0;
1270
+ }
1271
+ if (value.length > TRUST_POLICY_LIMITS.maxPatternsPerRule) {
1272
+ error(
1273
+ diagnostics,
1274
+ "too_many_patterns",
1275
+ path3,
1276
+ `must contain at most ${TRUST_POLICY_LIMITS.maxPatternsPerRule} patterns`
1277
+ );
1278
+ return void 0;
1279
+ }
1280
+ const patterns = [];
1281
+ const seen = /* @__PURE__ */ new Set();
1282
+ for (const [index, pattern] of value.entries()) {
1283
+ const itemPath = `${path3}[${index}]`;
1284
+ if (typeof pattern !== "string" || pattern.length === 0 || pattern.length > TRUST_POLICY_LIMITS.maxPatternChars) {
1285
+ error(
1286
+ diagnostics,
1287
+ "invalid_pattern",
1288
+ itemPath,
1289
+ `must be a non-empty string up to ${TRUST_POLICY_LIMITS.maxPatternChars} characters`
1290
+ );
1291
+ continue;
1292
+ }
1293
+ if (seen.has(pattern)) {
1294
+ diagnostics.push({
1295
+ severity: "warning",
1296
+ code: "duplicate_pattern",
1297
+ path: itemPath,
1298
+ message: "duplicates an earlier pattern and was normalized away"
1299
+ });
1300
+ continue;
1301
+ }
1302
+ seen.add(pattern);
1303
+ patterns.push(pattern);
1304
+ }
1305
+ return patterns;
1306
+ }
1307
+ function validateTrustPolicy(value) {
1308
+ const diagnostics = [];
1309
+ if (!isRecord(value)) {
1310
+ return {
1311
+ ok: false,
1312
+ diagnostics: [
1313
+ {
1314
+ severity: "error",
1315
+ code: "invalid_root",
1316
+ path: "$",
1317
+ message: "trust policy must be an object"
1318
+ }
1319
+ ]
1320
+ };
1321
+ }
1322
+ const entries = Object.entries(value);
1323
+ if (entries.length > TRUST_POLICY_LIMITS.maxTools) {
1324
+ error(
1325
+ diagnostics,
1326
+ "too_many_tools",
1327
+ "$",
1328
+ `must contain at most ${TRUST_POLICY_LIMITS.maxTools} tool rules`
1329
+ );
1330
+ }
1331
+ const policy = {};
1332
+ for (const [toolName, rawRule] of entries.slice(0, TRUST_POLICY_LIMITS.maxTools)) {
1333
+ const toolPath = `$[${JSON.stringify(toolName)}]`;
1334
+ if (toolName.length === 0 || toolName.length > TRUST_POLICY_LIMITS.maxToolNameChars) {
1335
+ error(
1336
+ diagnostics,
1337
+ "invalid_tool_name",
1338
+ toolPath,
1339
+ `tool name must be 1-${TRUST_POLICY_LIMITS.maxToolNameChars} characters`
1340
+ );
1341
+ continue;
1342
+ }
1343
+ if (UNSAFE_PROPERTY_NAMES.has(toolName)) {
1344
+ error(
1345
+ diagnostics,
1346
+ "unsafe_tool_name",
1347
+ toolPath,
1348
+ "reserved object property names are not valid tool rules"
1349
+ );
1350
+ continue;
1351
+ }
1352
+ if (!isRecord(rawRule)) {
1353
+ error(diagnostics, "invalid_rule", toolPath, "tool rule must be an object");
1354
+ continue;
1355
+ }
1356
+ for (const field of Object.keys(rawRule)) {
1357
+ if (!RULE_FIELDS.has(field)) {
1358
+ error(
1359
+ diagnostics,
1360
+ "unknown_field",
1361
+ `${toolPath}.${field}`,
1362
+ `unknown policy field "${field}"`
1363
+ );
1364
+ }
1365
+ }
1366
+ const rule = {};
1367
+ for (const field of ["allow", "deny"]) {
1368
+ if (rawRule[field] === void 0) continue;
1369
+ const patterns = validatePatterns(rawRule[field], `${toolPath}.${field}`, diagnostics);
1370
+ if (patterns) rule[field] = patterns;
1371
+ }
1372
+ for (const field of ["auto", "trustWorkdir", "denyPrivate"]) {
1373
+ const setting = rawRule[field];
1374
+ if (setting === void 0) continue;
1375
+ if (typeof setting !== "boolean") {
1376
+ error(diagnostics, "invalid_boolean", `${toolPath}.${field}`, "must be a boolean");
1377
+ } else {
1378
+ rule[field] = setting;
1379
+ }
1380
+ }
1381
+ policy[toolName] = rule;
1382
+ }
1383
+ return diagnostics.some((diagnostic) => diagnostic.severity === "error") ? { ok: false, diagnostics } : { ok: true, policy, diagnostics };
1384
+ }
1385
+
1210
1386
  // src/utils/lru-cache.ts
1211
1387
  var LruCache = class {
1212
1388
  store = /* @__PURE__ */ new Map();
@@ -1375,6 +1551,8 @@ var DefaultPermissionPolicy = class {
1375
1551
  * the LRU evicts the least-recently-used entries first.
1376
1552
  */
1377
1553
  _evalCache = new LruCache(500);
1554
+ policyDiagnostics = [];
1555
+ policyInvalid = false;
1378
1556
  constructor(opts) {
1379
1557
  this.trustFile = opts.trustFile;
1380
1558
  this.yolo = opts.yolo ?? false;
@@ -1418,13 +1596,50 @@ var DefaultPermissionPolicy = class {
1418
1596
  getConfirmDestructive() {
1419
1597
  return this.confirmDestructive;
1420
1598
  }
1599
+ /** Read-only diagnostics for policy inspector/editor surfaces. */
1600
+ getPolicyDiagnostics() {
1601
+ return this.policyDiagnostics.map((diagnostic) => ({ ...diagnostic }));
1602
+ }
1421
1603
  async reload() {
1604
+ this.policyDiagnostics = [];
1605
+ this.policyInvalid = false;
1422
1606
  try {
1423
1607
  const raw = await fs3.readFile(this.trustFile, "utf8");
1424
1608
  const parsed = safeParse(raw);
1425
- if (parsed.ok && parsed.value) this.policy = parsed.value;
1426
- } catch {
1609
+ if (!parsed.ok) {
1610
+ this.policy = {};
1611
+ this.policyInvalid = true;
1612
+ this.policyDiagnostics = [
1613
+ {
1614
+ severity: "error",
1615
+ code: "invalid_json",
1616
+ path: "$",
1617
+ message: parsed.error ?? "trust policy is not valid JSON"
1618
+ }
1619
+ ];
1620
+ } else {
1621
+ const validation = validateTrustPolicy(parsed.value);
1622
+ this.policyDiagnostics = validation.diagnostics;
1623
+ if (validation.ok) {
1624
+ this.policy = validation.policy;
1625
+ } else {
1626
+ this.policy = {};
1627
+ this.policyInvalid = true;
1628
+ }
1629
+ }
1630
+ } catch (err) {
1427
1631
  this.policy = {};
1632
+ if (err.code !== "ENOENT") {
1633
+ this.policyInvalid = true;
1634
+ this.policyDiagnostics = [
1635
+ {
1636
+ severity: "error",
1637
+ code: "read_error",
1638
+ path: "$",
1639
+ message: err instanceof Error ? err.message : String(err)
1640
+ }
1641
+ ];
1642
+ }
1428
1643
  }
1429
1644
  this.wildcardEntries = [];
1430
1645
  for (const [key, val] of Object.entries(this.policy)) {
@@ -1437,6 +1652,13 @@ var DefaultPermissionPolicy = class {
1437
1652
  }
1438
1653
  async evaluate(tool, input, ctx) {
1439
1654
  if (!this.loaded) await this.reload();
1655
+ if (this.policyInvalid) {
1656
+ return {
1657
+ permission: "deny",
1658
+ source: "deny",
1659
+ reason: "trust policy is invalid; refusing tool execution until it is repaired"
1660
+ };
1661
+ }
1440
1662
  const namespaceEntry = this.findNamespaceEntry(tool.name);
1441
1663
  const entry = this.policy[tool.name] ?? namespaceEntry;
1442
1664
  const subject = subjectForToolInput(tool.name, input, tool.subjectKey);
@@ -1566,6 +1788,9 @@ var DefaultPermissionPolicy = class {
1566
1788
  }
1567
1789
  async trust(rule) {
1568
1790
  if (!this.loaded) await this.reload();
1791
+ if (this.policyInvalid) {
1792
+ throw new Error("Cannot update trust rules while trust.json is invalid; repair it first.");
1793
+ }
1569
1794
  const entry = this.policy[rule.tool] ?? {};
1570
1795
  entry.allow = Array.from(/* @__PURE__ */ new Set([...entry.allow ?? [], rule.pattern]));
1571
1796
  this.policy[rule.tool] = entry;
@@ -1584,6 +1809,9 @@ var DefaultPermissionPolicy = class {
1584
1809
  /** Persist a deny rule — this tool+pattern pair is permanently blocked. */
1585
1810
  async deny(rule) {
1586
1811
  if (!this.loaded) await this.reload();
1812
+ if (this.policyInvalid) {
1813
+ throw new Error("Cannot update deny rules while trust.json is invalid; repair it first.");
1814
+ }
1587
1815
  const entry = this.policy[rule.tool] ?? {};
1588
1816
  entry.deny = Array.from(/* @__PURE__ */ new Set([...entry.deny ?? [], rule.pattern]));
1589
1817
  this.policy[rule.tool] = entry;
@@ -1663,6 +1891,9 @@ export {
1663
1891
  DefaultPermissionPolicy,
1664
1892
  DefaultSecretScrubber,
1665
1893
  DefaultSecretVault,
1894
+ TRUST_POLICY_JSON_SCHEMA,
1895
+ TRUST_POLICY_LIMITS,
1896
+ TRUST_POLICY_SCHEMA_VERSION,
1666
1897
  ToolCapabilities,
1667
1898
  decryptConfigSecrets,
1668
1899
  encryptConfigSecrets,
@@ -1672,6 +1903,7 @@ export {
1672
1903
  isSecretField,
1673
1904
  migratePlaintextSecrets,
1674
1905
  rewriteConfigEncrypted,
1675
- rotateConfigKeys
1906
+ rotateConfigKeys,
1907
+ validateTrustPolicy
1676
1908
  };
1677
1909
  //# sourceMappingURL=index.js.map