@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.
- package/dist/autophase/phase-orchestrator.d.ts.map +1 -1
- package/dist/boot.d.ts.map +1 -1
- package/dist/coordination/agent-monitor.d.ts +29 -0
- package/dist/coordination/agent-monitor.d.ts.map +1 -1
- package/dist/coordination/autonomous-brain.d.ts +0 -2
- package/dist/coordination/autonomous-brain.d.ts.map +1 -1
- package/dist/coordination/autonomous-coordinator.d.ts +4 -0
- package/dist/coordination/autonomous-coordinator.d.ts.map +1 -1
- package/dist/coordination/brain-ledger.d.ts +142 -0
- package/dist/coordination/brain-ledger.d.ts.map +1 -0
- package/dist/coordination/brain-monitor.d.ts +31 -2
- package/dist/coordination/brain-monitor.d.ts.map +1 -1
- package/dist/coordination/brain.d.ts +43 -0
- package/dist/coordination/brain.d.ts.map +1 -1
- package/dist/coordination/delegate-tool.d.ts.map +1 -1
- package/dist/coordination/director-construction.d.ts.map +1 -1
- package/dist/coordination/director.d.ts +1 -1
- package/dist/coordination/director.d.ts.map +1 -1
- package/dist/coordination/fleet.d.ts +4 -4
- package/dist/coordination/fleet.d.ts.map +1 -1
- package/dist/coordination/global-mailbox.d.ts +63 -2
- package/dist/coordination/global-mailbox.d.ts.map +1 -1
- package/dist/coordination/index.d.ts +2 -1
- package/dist/coordination/index.d.ts.map +1 -1
- package/dist/coordination/index.js +1566 -462
- package/dist/coordination/index.js.map +4 -4
- package/dist/coordination/knowledge-graph.d.ts +13 -1
- package/dist/coordination/knowledge-graph.d.ts.map +1 -1
- package/dist/coordination/mailbox-actions.d.ts +12 -13
- package/dist/coordination/mailbox-actions.d.ts.map +1 -1
- package/dist/coordination/mailbox-constants.d.ts +64 -0
- package/dist/coordination/mailbox-constants.d.ts.map +1 -0
- package/dist/coordination/mailbox-events.d.ts +32 -0
- package/dist/coordination/mailbox-events.d.ts.map +1 -0
- package/dist/coordination/mailbox-message-codec.d.ts +8 -0
- package/dist/coordination/mailbox-message-codec.d.ts.map +1 -0
- package/dist/coordination/mailbox-types.d.ts +88 -4
- package/dist/coordination/mailbox-types.d.ts.map +1 -1
- package/dist/coordination/mailbox.d.ts +21 -2
- package/dist/coordination/mailbox.d.ts.map +1 -1
- package/dist/coordination/package-author-tracker.d.ts.map +1 -1
- package/dist/coordination/subagent-result-tool.d.ts.map +1 -1
- package/dist/defaults/index.js +846 -523
- package/dist/defaults/index.js.map +4 -4
- package/dist/execution/autonomous-runner.d.ts +7 -1
- package/dist/execution/autonomous-runner.d.ts.map +1 -1
- package/dist/execution/autonomy-brain.d.ts +72 -11
- package/dist/execution/autonomy-brain.d.ts.map +1 -1
- package/dist/execution/brain-chain.d.ts +53 -0
- package/dist/execution/brain-chain.d.ts.map +1 -0
- package/dist/execution/brain-evaluation.d.ts +66 -0
- package/dist/execution/brain-evaluation.d.ts.map +1 -0
- package/dist/execution/brain-runtime.d.ts +171 -0
- package/dist/execution/brain-runtime.d.ts.map +1 -0
- package/dist/execution/council-brain.d.ts +79 -0
- package/dist/execution/council-brain.d.ts.map +1 -0
- package/dist/execution/eternal-autonomy.d.ts +12 -0
- package/dist/execution/eternal-autonomy.d.ts.map +1 -1
- package/dist/execution/index.d.ts +5 -1
- package/dist/execution/index.d.ts.map +1 -1
- package/dist/execution/index.js +1350 -377
- package/dist/execution/index.js.map +4 -4
- package/dist/execution/parallel-eternal-engine.d.ts +12 -0
- package/dist/execution/parallel-eternal-engine.d.ts.map +1 -1
- package/dist/execution/tool-executor.d.ts.map +1 -1
- package/dist/hq/auth-store.d.ts +21 -3
- package/dist/hq/auth-store.d.ts.map +1 -1
- package/dist/hq/factory.d.ts +3 -0
- package/dist/hq/factory.d.ts.map +1 -1
- package/dist/hq/index.js +628 -72
- package/dist/hq/index.js.map +4 -4
- package/dist/hq/protocol.d.ts +54 -2
- package/dist/hq/protocol.d.ts.map +1 -1
- package/dist/hq/publisher.d.ts +4 -0
- package/dist/hq/publisher.d.ts.map +1 -1
- package/dist/index.d.ts +12 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3482 -1495
- package/dist/index.js.map +4 -4
- package/dist/kernel/events.d.ts +22 -4
- package/dist/kernel/events.d.ts.map +1 -1
- package/dist/kernel/index.js.map +2 -2
- package/dist/mailbox-attach.d.ts.map +1 -1
- package/dist/observability/index.js +16 -15
- package/dist/observability/index.js.map +2 -2
- package/dist/security/index.d.ts +1 -0
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +253 -21
- package/dist/security/index.js.map +4 -4
- package/dist/security/permission-policy-schema.d.ts +77 -0
- package/dist/security/permission-policy-schema.d.ts.map +1 -0
- package/dist/security/permission-policy.d.ts +5 -0
- package/dist/security/permission-policy.d.ts.map +1 -1
- package/dist/security/secret-vault.d.ts +9 -0
- package/dist/security/secret-vault.d.ts.map +1 -1
- package/dist/session-registry.d.ts.map +1 -1
- package/dist/storage/config-loader.d.ts +10 -0
- package/dist/storage/config-loader.d.ts.map +1 -1
- package/dist/storage/goal-store.d.ts +1 -1
- package/dist/storage/goal-store.d.ts.map +1 -1
- package/dist/storage/index.js +147 -162
- package/dist/storage/index.js.map +2 -2
- package/dist/storage/plan-store.d.ts +1 -1
- package/dist/storage/plan-store.d.ts.map +1 -1
- package/dist/storage/queue-store.d.ts +4 -0
- package/dist/storage/queue-store.d.ts.map +1 -1
- package/dist/storage/session-store.d.ts +9 -0
- package/dist/storage/session-store.d.ts.map +1 -1
- package/dist/storage/task-store.d.ts +1 -1
- package/dist/storage/task-store.d.ts.map +1 -1
- package/dist/storage/todos-checkpoint.d.ts +2 -2
- package/dist/storage/todos-checkpoint.d.ts.map +1 -1
- package/dist/types/config.d.ts +209 -1
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/index.js +11 -0
- package/dist/types/index.js.map +2 -2
- package/dist/types/multi-agent.d.ts +8 -0
- package/dist/types/multi-agent.d.ts.map +1 -1
- package/dist/types/observability.d.ts +5 -0
- package/dist/types/observability.d.ts.map +1 -1
- package/dist/types/tool.d.ts +7 -0
- package/dist/types/tool.d.ts.map +1 -1
- package/dist/utils/glob-expand.d.ts.map +1 -1
- package/dist/utils/incoming-images.d.ts +39 -0
- package/dist/utils/incoming-images.d.ts.map +1 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +81 -3
- package/dist/utils/index.js.map +3 -3
- package/dist/worktree/worktree-manager.d.ts +13 -4
- package/dist/worktree/worktree-manager.d.ts.map +1 -1
- package/instructions/agents/browser.md +25 -16
- package/instructions/coordination/subagent-baseline.md +16 -2
- package/instructions/leader-after-task.md +3 -1
- package/instructions/sections/tool/common-patterns.md +7 -1
- package/instructions/system.md +47 -0
- package/package.json +2 -2
- package/skills/docker-deploy/SKILL.md +1 -1
- package/skills/wrongstack-mailbox/SKILL.md +51 -12
- package/dist/plugins/git-plugin.d.ts +0 -15
- package/dist/plugins/git-plugin.d.ts.map +0 -1
- package/dist/plugins/observability-plugin.d.ts +0 -19
- package/dist/plugins/observability-plugin.d.ts.map +0 -1
- package/dist/plugins/plan-plugin.d.ts +0 -16
- package/dist/plugins/plan-plugin.d.ts.map +0 -1
package/dist/security/index.js
CHANGED
|
@@ -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
|
-
|
|
715
|
-
|
|
716
|
-
|
|
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
|
|
1426
|
-
|
|
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
|