@wrongstack/core 0.270.0 → 0.272.1
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/{agent-bridge-PcHQl_UQ.d.ts → agent-bridge-DFQYEeXf.d.ts} +1 -1
- package/dist/{agent-subagent-runner-SHJW7t8q.d.ts → agent-subagent-runner-BZa_IEcd.d.ts} +7 -7
- package/dist/{brain-BYcK__Ym.d.ts → brain-etbcbRwV.d.ts} +95 -2
- package/dist/{compactor-C2RKEBtC.d.ts → compactor-72ug-ZRB.d.ts} +1 -1
- package/dist/{config-C_ae2k86.d.ts → config-rRS8yorV.d.ts} +71 -2
- package/dist/{context-Dp87Bcaq.d.ts → context-Dw55zZ_Q.d.ts} +110 -1
- package/dist/coordination/index.d.ts +181 -17
- package/dist/coordination/index.js +1018 -166
- package/dist/coordination/index.js.map +1 -1
- package/dist/defaults/index.d.ts +25 -25
- package/dist/defaults/index.js +804 -222
- package/dist/defaults/index.js.map +1 -1
- package/dist/execution/index.d.ts +23 -18
- package/dist/execution/index.js +136 -41
- package/dist/execution/index.js.map +1 -1
- package/dist/execution/prompt-enhancer.d.ts +36 -6
- package/dist/execution/prompt-enhancer.js +35 -9
- package/dist/execution/prompt-enhancer.js.map +1 -1
- package/dist/extension/index.d.ts +6 -6
- package/dist/{global-mailbox-Bvrz1P3f.d.ts → global-mailbox-DJ4EoRr0.d.ts} +145 -5
- package/dist/{goal-preamble-CA_4yiGQ.d.ts → goal-preamble-hM8BH7TK.d.ts} +9 -9
- package/dist/{goal-store-DhuJoUNG.d.ts → goal-store-CWlbT0TO.d.ts} +1 -1
- package/dist/hq/index.d.ts +95 -6
- package/dist/hq/index.js +628 -50
- package/dist/hq/index.js.map +1 -1
- package/dist/{index-whDfTANu.d.ts → index-2Lhk5v0o.d.ts} +2 -2
- package/dist/{index-W4VJCzHa.d.ts → index-DWm_PE9L.d.ts} +5 -5
- package/dist/{index-CZQ6Pwbs.d.ts → index-DqW4o62H.d.ts} +8 -8
- package/dist/index.d.ts +96 -56
- package/dist/index.js +2464 -519
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/index.d.ts +6 -6
- package/dist/infrastructure/index.js +5 -3
- package/dist/infrastructure/index.js.map +1 -1
- package/dist/kernel/index.d.ts +9 -9
- package/dist/kernel/index.js.map +1 -1
- package/dist/{mcp-servers-DJdZiRcv.d.ts → mcp-servers-BpWHTKlE.d.ts} +3 -3
- package/dist/models/index.d.ts +5 -5
- package/dist/models/index.js +28 -5
- package/dist/models/index.js.map +1 -1
- package/dist/{models-registry-C3a-2-Yd.d.ts → models-registry-CXQFUn5t.d.ts} +1 -1
- package/dist/{multi-agent-coordinator-CJSpTe5O.d.ts → multi-agent-coordinator-jyimfo7D.d.ts} +1 -1
- package/dist/{null-fleet-bus-QVshIsDx.d.ts → null-fleet-bus-DOGQcvrY.d.ts} +6 -6
- package/dist/observability/index.d.ts +2 -2
- package/dist/{parallel-eternal-engine-D9y5Pkcc.d.ts → parallel-eternal-engine-rItJBYp9.d.ts} +9 -9
- package/dist/{path-resolver-CnQ8SIfh.d.ts → path-resolver-DrpF5MGK.d.ts} +3 -3
- package/dist/{permission-CvYQNUqZ.d.ts → permission-CC7XFYWG.d.ts} +1 -1
- package/dist/{permission-policy-D5Ss8j4B.d.ts → permission-policy-cYR4RJmw.d.ts} +2 -2
- package/dist/{pipeline-l_zzFRh3.d.ts → pipeline-Ckkn3AOA.d.ts} +2 -2
- package/dist/{plan-templates-NtPgyeJA.d.ts → plan-templates-BvHw5Znw.d.ts} +33 -9
- package/dist/{provider-model-resolve-d5poT5y0.d.ts → provider-model-resolve-nZqnCeaR.d.ts} +3 -3
- package/dist/{provider-runner-gkctlQV_.d.ts → provider-runner-zVOn1p67.d.ts} +3 -3
- package/dist/{retry-policy-CtFhfwa8.d.ts → retry-policy-BV7nzeAd.d.ts} +1 -1
- package/dist/sdd/index.d.ts +8 -8
- package/dist/sdd/index.js +2 -0
- package/dist/sdd/index.js.map +1 -1
- package/dist/{secret-vault-BLsVmTIK.d.ts → secret-vault-eMBKfheR.d.ts} +9 -1
- package/dist/security/index.d.ts +5 -5
- package/dist/security/index.js +137 -10
- package/dist/security/index.js.map +1 -1
- package/dist/{selector-CXl2_y9W.d.ts → selector-C4ORTOid.d.ts} +1 -1
- package/dist/{session-event-bridge-Ccud20CC.d.ts → session-event-bridge-CeNpUL9w.d.ts} +1 -1
- package/dist/{session-reader-ZeXQmsmE.d.ts → session-reader-BepLSnGL.d.ts} +1 -1
- package/dist/storage/index.d.ts +50 -13
- package/dist/storage/index.js +620 -220
- package/dist/storage/index.js.map +1 -1
- package/dist/tools/index.d.ts +2 -2
- package/dist/tools/index.js +9 -2
- package/dist/tools/index.js.map +1 -1
- package/dist/types/index.d.ts +19 -19
- package/dist/types/index.js +202 -41
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.d.ts +17 -4
- package/dist/utils/index.js +48 -9
- package/dist/utils/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { S as SecretScrubber } from './permission-
|
|
1
|
+
import { S as SecretScrubber } from './permission-CC7XFYWG.js';
|
|
2
2
|
import { L as Logger } from './logger-B63L5bTg.js';
|
|
3
3
|
import { R as RotatableSecretVault, S as SecretVault } from './secret-vault-BAKpgFw_.js';
|
|
4
4
|
|
|
@@ -51,6 +51,14 @@ declare class DefaultSecretVault implements RotatableSecretVault {
|
|
|
51
51
|
oldVersion: number;
|
|
52
52
|
newVersion: number;
|
|
53
53
|
};
|
|
54
|
+
/**
|
|
55
|
+
* If WRONGSTACK_VAULT_PASSPHRASE is set but the key on disk is still stored
|
|
56
|
+
* unwrapped (legacy v1 / versioned v2), re-write it in passphrase-wrapped (v3)
|
|
57
|
+
* form. The data key is preserved, so all existing ciphertext keeps
|
|
58
|
+
* decrypting. Best-effort: a write failure leaves the working unwrapped file
|
|
59
|
+
* in place and is not fatal to load.
|
|
60
|
+
*/
|
|
61
|
+
private migrateToWrappedIfPassphrase;
|
|
54
62
|
private loadOrCreateKey;
|
|
55
63
|
}
|
|
56
64
|
/**
|
package/dist/security/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export { a as DefaultSecretScrubber, D as DefaultSecretVault, S as SecretVaultOptions, d as decryptConfigSecrets, e as encryptConfigSecrets, i as isSecretField, m as migratePlaintextSecrets, r as rewriteConfigEncrypted, b as rotateConfigKeys } from '../secret-vault-
|
|
2
|
-
export { A as AutoApprovePermissionPolicy, D as DefaultPermissionPolicy, P as PermissionPolicyOptions } from '../permission-policy-
|
|
3
|
-
export { D as DANGEROUS_FOR_SUBAGENTS, T as ToolCapabilities, a as ToolCapability, g as getDangerousCapabilities, h as hasCapability, b as hasDangerousCapabilityForSubagents } from '../index-
|
|
4
|
-
import '../permission-
|
|
5
|
-
import '../context-
|
|
1
|
+
export { a as DefaultSecretScrubber, D as DefaultSecretVault, S as SecretVaultOptions, d as decryptConfigSecrets, e as encryptConfigSecrets, i as isSecretField, m as migratePlaintextSecrets, r as rewriteConfigEncrypted, b as rotateConfigKeys } from '../secret-vault-eMBKfheR.js';
|
|
2
|
+
export { A as AutoApprovePermissionPolicy, D as DefaultPermissionPolicy, P as PermissionPolicyOptions } from '../permission-policy-cYR4RJmw.js';
|
|
3
|
+
export { D as DANGEROUS_FOR_SUBAGENTS, T as ToolCapabilities, a as ToolCapability, g as getDangerousCapabilities, h as hasCapability, b as hasDangerousCapabilityForSubagents } from '../index-2Lhk5v0o.js';
|
|
4
|
+
import '../permission-CC7XFYWG.js';
|
|
5
|
+
import '../context-Dw55zZ_Q.js';
|
|
6
6
|
import '../logger-B63L5bTg.js';
|
|
7
7
|
import '../secret-vault-BAKpgFw_.js';
|
|
8
8
|
import '../input-reader-E-ffP2ee.js';
|
package/dist/security/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { randomBytes, createCipheriv, createDecipheriv } from 'crypto';
|
|
1
|
+
import { randomBytes, createCipheriv, createDecipheriv, scryptSync } from 'crypto';
|
|
2
2
|
import * as fs2 from 'fs';
|
|
3
3
|
import * as fs from 'fs/promises';
|
|
4
4
|
import * as path3 from 'path';
|
|
@@ -310,6 +310,7 @@ function escapeRegex(s) {
|
|
|
310
310
|
}
|
|
311
311
|
var COMPILED_GLOB_CACHE = /* @__PURE__ */ new Map();
|
|
312
312
|
var CACHE_MAX_SIZE = 2e3;
|
|
313
|
+
var NEVER_MATCH = /[^\s\S]/;
|
|
313
314
|
function getCachedGlob(pattern) {
|
|
314
315
|
const cached = COMPILED_GLOB_CACHE.get(pattern);
|
|
315
316
|
if (cached) return cached;
|
|
@@ -319,7 +320,12 @@ function getCachedGlob(pattern) {
|
|
|
319
320
|
COMPILED_GLOB_CACHE.delete(expectDefined(keys[i]));
|
|
320
321
|
}
|
|
321
322
|
}
|
|
322
|
-
|
|
323
|
+
let re;
|
|
324
|
+
try {
|
|
325
|
+
re = compileGlob(pattern);
|
|
326
|
+
} catch {
|
|
327
|
+
re = NEVER_MATCH;
|
|
328
|
+
}
|
|
323
329
|
COMPILED_GLOB_CACHE.set(pattern, re);
|
|
324
330
|
return re;
|
|
325
331
|
}
|
|
@@ -543,6 +549,83 @@ var ALGO = "aes-256-gcm";
|
|
|
543
549
|
var KEY_FILE_MODE = 384;
|
|
544
550
|
var KEY_FILE_MAGIC = Buffer.from("WSKV", "ascii");
|
|
545
551
|
var VERSIONED_KEY_FILE_SIZE = KEY_FILE_MAGIC.length + 1 + KEY_BYTES;
|
|
552
|
+
var KEK_MAGIC = Buffer.from("WSKW", "ascii");
|
|
553
|
+
var KEK_SALT_BYTES = 16;
|
|
554
|
+
var WRAPPED_KEY_FILE_SIZE = KEK_MAGIC.length + 1 + KEK_SALT_BYTES + IV_BYTES + TAG_BYTES + KEY_BYTES;
|
|
555
|
+
var SCRYPT_N = 1 << 15;
|
|
556
|
+
var SCRYPT_R = 8;
|
|
557
|
+
var SCRYPT_P = 1;
|
|
558
|
+
var SCRYPT_MAXMEM = 64 * 1024 * 1024;
|
|
559
|
+
function getVaultPassphrase() {
|
|
560
|
+
const v = process.env["WRONGSTACK_VAULT_PASSPHRASE"];
|
|
561
|
+
return v && v.length > 0 ? v : void 0;
|
|
562
|
+
}
|
|
563
|
+
function isWrappedKeyFile(buf) {
|
|
564
|
+
return buf.length === WRAPPED_KEY_FILE_SIZE && buf.subarray(0, KEK_MAGIC.length).equals(KEK_MAGIC);
|
|
565
|
+
}
|
|
566
|
+
function deriveKEK(passphrase, salt) {
|
|
567
|
+
return scryptSync(passphrase, salt, KEY_BYTES, {
|
|
568
|
+
N: SCRYPT_N,
|
|
569
|
+
r: SCRYPT_R,
|
|
570
|
+
p: SCRYPT_P,
|
|
571
|
+
maxmem: SCRYPT_MAXMEM
|
|
572
|
+
});
|
|
573
|
+
}
|
|
574
|
+
function wrapDataKey(dataKey, keyVersion, passphrase) {
|
|
575
|
+
const salt = randomBytes(KEK_SALT_BYTES);
|
|
576
|
+
const iv = randomBytes(IV_BYTES);
|
|
577
|
+
const kek = deriveKEK(passphrase, salt);
|
|
578
|
+
const cipher = createCipheriv(ALGO, kek, iv);
|
|
579
|
+
const ct = Buffer.concat([cipher.update(dataKey), cipher.final()]);
|
|
580
|
+
const tag = cipher.getAuthTag();
|
|
581
|
+
const out = Buffer.alloc(WRAPPED_KEY_FILE_SIZE);
|
|
582
|
+
let off = 0;
|
|
583
|
+
KEK_MAGIC.copy(out, off);
|
|
584
|
+
off += KEK_MAGIC.length;
|
|
585
|
+
out[off] = keyVersion & 255;
|
|
586
|
+
off += 1;
|
|
587
|
+
salt.copy(out, off);
|
|
588
|
+
off += KEK_SALT_BYTES;
|
|
589
|
+
iv.copy(out, off);
|
|
590
|
+
off += IV_BYTES;
|
|
591
|
+
tag.copy(out, off);
|
|
592
|
+
off += TAG_BYTES;
|
|
593
|
+
ct.copy(out, off);
|
|
594
|
+
return out;
|
|
595
|
+
}
|
|
596
|
+
function unwrapDataKey(buf, keyFile) {
|
|
597
|
+
const passphrase = getVaultPassphrase();
|
|
598
|
+
if (!passphrase) {
|
|
599
|
+
throw new ConfigError({
|
|
600
|
+
message: `SecretVault: key file ${keyFile} is passphrase-protected \u2014 set the WRONGSTACK_VAULT_PASSPHRASE environment variable to unlock it.`,
|
|
601
|
+
code: ERROR_CODES.CONFIG_INVALID,
|
|
602
|
+
context: { keyFile }
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
let off = KEK_MAGIC.length;
|
|
606
|
+
const version = buf[off];
|
|
607
|
+
off += 1;
|
|
608
|
+
const salt = buf.subarray(off, off + KEK_SALT_BYTES);
|
|
609
|
+
off += KEK_SALT_BYTES;
|
|
610
|
+
const iv = buf.subarray(off, off + IV_BYTES);
|
|
611
|
+
off += IV_BYTES;
|
|
612
|
+
const tag = buf.subarray(off, off + TAG_BYTES);
|
|
613
|
+
off += TAG_BYTES;
|
|
614
|
+
const ct = buf.subarray(off, off + KEY_BYTES);
|
|
615
|
+
const kek = deriveKEK(passphrase, salt);
|
|
616
|
+
const decipher = createDecipheriv(ALGO, kek, iv);
|
|
617
|
+
decipher.setAuthTag(tag);
|
|
618
|
+
try {
|
|
619
|
+
const key = Buffer.concat([decipher.update(ct), decipher.final()]);
|
|
620
|
+
return { key: Buffer.from(key), version };
|
|
621
|
+
} catch {
|
|
622
|
+
throw new ConfigError({
|
|
623
|
+
message: `SecretVault: failed to unlock key file ${keyFile} \u2014 wrong WRONGSTACK_VAULT_PASSPHRASE (key unwrap authentication failed).`,
|
|
624
|
+
code: ERROR_CODES.CONFIG_INVALID,
|
|
625
|
+
context: { keyFile }
|
|
626
|
+
});
|
|
627
|
+
}
|
|
628
|
+
}
|
|
546
629
|
function checkKeyFilePermissions(keyFile) {
|
|
547
630
|
if (process.platform === "win32") return;
|
|
548
631
|
try {
|
|
@@ -635,25 +718,56 @@ var DefaultSecretVault = class {
|
|
|
635
718
|
const oldVersion = this._keyVersion;
|
|
636
719
|
const newKey = randomBytes(KEY_BYTES);
|
|
637
720
|
const newVersion = oldVersion + 1;
|
|
638
|
-
const keyFileBuf = Buffer.alloc(VERSIONED_KEY_FILE_SIZE);
|
|
639
|
-
KEY_FILE_MAGIC.copy(keyFileBuf, 0);
|
|
640
|
-
keyFileBuf[KEY_FILE_MAGIC.length] = newVersion;
|
|
641
|
-
newKey.copy(keyFileBuf, KEY_FILE_MAGIC.length + 1);
|
|
642
721
|
fs2.mkdirSync(path3.dirname(this.keyFile), { recursive: true });
|
|
643
|
-
|
|
722
|
+
const passphrase = getVaultPassphrase();
|
|
723
|
+
if (passphrase) {
|
|
724
|
+
fs2.writeFileSync(this.keyFile, wrapDataKey(newKey, newVersion, passphrase), { mode: 384 });
|
|
725
|
+
} else {
|
|
726
|
+
const keyFileBuf = Buffer.alloc(VERSIONED_KEY_FILE_SIZE);
|
|
727
|
+
KEY_FILE_MAGIC.copy(keyFileBuf, 0);
|
|
728
|
+
keyFileBuf[KEY_FILE_MAGIC.length] = newVersion;
|
|
729
|
+
newKey.copy(keyFileBuf, KEY_FILE_MAGIC.length + 1);
|
|
730
|
+
fs2.writeFileSync(this.keyFile, keyFileBuf, { mode: 384 });
|
|
731
|
+
}
|
|
644
732
|
checkKeyFilePermissions(this.keyFile);
|
|
645
733
|
this.key = newKey;
|
|
646
734
|
this._keyVersion = newVersion;
|
|
647
735
|
return { oldVersion, newVersion };
|
|
648
736
|
}
|
|
737
|
+
/**
|
|
738
|
+
* If WRONGSTACK_VAULT_PASSPHRASE is set but the key on disk is still stored
|
|
739
|
+
* unwrapped (legacy v1 / versioned v2), re-write it in passphrase-wrapped (v3)
|
|
740
|
+
* form. The data key is preserved, so all existing ciphertext keeps
|
|
741
|
+
* decrypting. Best-effort: a write failure leaves the working unwrapped file
|
|
742
|
+
* in place and is not fatal to load.
|
|
743
|
+
*/
|
|
744
|
+
migrateToWrappedIfPassphrase() {
|
|
745
|
+
const passphrase = getVaultPassphrase();
|
|
746
|
+
if (!passphrase || !this.key) return;
|
|
747
|
+
try {
|
|
748
|
+
fs2.writeFileSync(this.keyFile, wrapDataKey(this.key, this._keyVersion, passphrase), {
|
|
749
|
+
mode: 384
|
|
750
|
+
});
|
|
751
|
+
checkKeyFilePermissions(this.keyFile);
|
|
752
|
+
} catch {
|
|
753
|
+
}
|
|
754
|
+
}
|
|
649
755
|
loadOrCreateKey() {
|
|
650
756
|
if (this.key) return this.key;
|
|
651
757
|
try {
|
|
652
758
|
const buf = fs2.readFileSync(this.keyFile);
|
|
759
|
+
if (isWrappedKeyFile(buf)) {
|
|
760
|
+
const { key: key2, version } = unwrapDataKey(buf, this.keyFile);
|
|
761
|
+
this.key = key2;
|
|
762
|
+
this._keyVersion = version;
|
|
763
|
+
checkKeyFilePermissions(this.keyFile);
|
|
764
|
+
return this.key;
|
|
765
|
+
}
|
|
653
766
|
if (buf.length === KEY_BYTES) {
|
|
654
767
|
this.key = buf;
|
|
655
768
|
this._keyVersion = 1;
|
|
656
769
|
checkKeyFilePermissions(this.keyFile);
|
|
770
|
+
this.migrateToWrappedIfPassphrase();
|
|
657
771
|
return this.key;
|
|
658
772
|
}
|
|
659
773
|
if (buf.length === VERSIONED_KEY_FILE_SIZE) {
|
|
@@ -677,6 +791,7 @@ var DefaultSecretVault = class {
|
|
|
677
791
|
this.key = Buffer.from(key2);
|
|
678
792
|
this._keyVersion = version;
|
|
679
793
|
checkKeyFilePermissions(this.keyFile);
|
|
794
|
+
this.migrateToWrappedIfPassphrase();
|
|
680
795
|
return this.key;
|
|
681
796
|
}
|
|
682
797
|
throw new ConfigError({
|
|
@@ -689,11 +804,20 @@ var DefaultSecretVault = class {
|
|
|
689
804
|
}
|
|
690
805
|
fs2.mkdirSync(path3.dirname(this.keyFile), { recursive: true });
|
|
691
806
|
const key = randomBytes(KEY_BYTES);
|
|
807
|
+
const passphrase = getVaultPassphrase();
|
|
808
|
+
const initialBytes = passphrase ? wrapDataKey(key, 1, passphrase) : key;
|
|
692
809
|
try {
|
|
693
|
-
fs2.writeFileSync(this.keyFile,
|
|
810
|
+
fs2.writeFileSync(this.keyFile, initialBytes, { mode: 384, flag: "wx" });
|
|
694
811
|
} catch (err) {
|
|
695
812
|
if (err.code !== "EEXIST") throw err;
|
|
696
813
|
const buf = fs2.readFileSync(this.keyFile);
|
|
814
|
+
if (isWrappedKeyFile(buf)) {
|
|
815
|
+
const { key: winnerKey, version } = unwrapDataKey(buf, this.keyFile);
|
|
816
|
+
this.key = winnerKey;
|
|
817
|
+
this._keyVersion = version;
|
|
818
|
+
checkKeyFilePermissions(this.keyFile);
|
|
819
|
+
return this.key;
|
|
820
|
+
}
|
|
697
821
|
if (buf.length === KEY_BYTES) {
|
|
698
822
|
this.key = buf;
|
|
699
823
|
this._keyVersion = 1;
|
|
@@ -1086,6 +1210,9 @@ function isClearlyDestructiveBashCommand(command, projectRoot) {
|
|
|
1086
1210
|
}
|
|
1087
1211
|
|
|
1088
1212
|
// src/security/permission-policy.ts
|
|
1213
|
+
function matchesTrust(patterns, subject) {
|
|
1214
|
+
return patterns.includes(subject) || matchAny(patterns, subject);
|
|
1215
|
+
}
|
|
1089
1216
|
var DefaultPermissionPolicy = class {
|
|
1090
1217
|
policy = {};
|
|
1091
1218
|
loaded = false;
|
|
@@ -1222,7 +1349,7 @@ var DefaultPermissionPolicy = class {
|
|
|
1222
1349
|
this._evalCache.set(cacheKey, decision);
|
|
1223
1350
|
return decision;
|
|
1224
1351
|
}
|
|
1225
|
-
if (entry?.deny && subject &&
|
|
1352
|
+
if (entry?.deny && subject && matchesTrust(entry.deny, subject)) {
|
|
1226
1353
|
const decision = { permission: "deny", source: "deny", reason: "matched deny pattern" };
|
|
1227
1354
|
this._evalCache.set(cacheKey, decision);
|
|
1228
1355
|
return decision;
|
|
@@ -1232,7 +1359,7 @@ var DefaultPermissionPolicy = class {
|
|
|
1232
1359
|
this._evalCache.set(cacheKey, decision);
|
|
1233
1360
|
return decision;
|
|
1234
1361
|
}
|
|
1235
|
-
if (entry?.allow && subject &&
|
|
1362
|
+
if (entry?.allow && subject && matchesTrust(entry.allow, subject)) {
|
|
1236
1363
|
const decision = { permission: "auto", source: "trust", reason: "matched allow pattern" };
|
|
1237
1364
|
this._evalCache.set(cacheKey, decision);
|
|
1238
1365
|
return decision;
|