@astrasyncai/verification-gateway 4.5.0 → 4.6.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/README.md +1 -1
- package/dist/adapter-interface/interface.d.mts +2 -2
- package/dist/adapter-interface/interface.d.ts +2 -2
- package/dist/adapters/express.d.mts +2 -2
- package/dist/adapters/express.d.ts +2 -2
- package/dist/adapters/express.js +6 -1
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +6 -1
- package/dist/adapters/express.mjs.map +1 -1
- package/dist/adapters/mcp.d.mts +3 -394
- package/dist/adapters/mcp.d.ts +3 -394
- package/dist/adapters/mcp.js +6 -1
- package/dist/adapters/mcp.js.map +1 -1
- package/dist/adapters/mcp.mjs +6 -1
- package/dist/adapters/mcp.mjs.map +1 -1
- package/dist/adapters/nextjs.d.mts +2 -2
- package/dist/adapters/nextjs.d.ts +2 -2
- package/dist/adapters/nextjs.js +6 -1
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +6 -1
- package/dist/adapters/nextjs.mjs.map +1 -1
- package/dist/adapters/sdk.d.mts +2 -2
- package/dist/adapters/sdk.d.ts +2 -2
- package/dist/adapters/sdk.js +6 -1
- package/dist/adapters/sdk.js.map +1 -1
- package/dist/adapters/sdk.mjs +6 -1
- package/dist/adapters/sdk.mjs.map +1 -1
- package/dist/agent/index.d.mts +2 -2
- package/dist/agent/index.d.ts +2 -2
- package/dist/agent/index.js +1 -1
- package/dist/agent/index.js.map +1 -1
- package/dist/agent/index.mjs +1 -1
- package/dist/agent/index.mjs.map +1 -1
- package/dist/bin/astrasync-claude-hook.js +60 -13
- package/dist/bin/astrasync-codex-hook.js +60 -13
- package/dist/bin/astrasync-guard.js +60 -13
- package/dist/bin/astrasync.js +68 -15
- package/dist/browser/background.js +60 -13
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +60 -13
- package/dist/browser/background.mjs.map +1 -1
- package/dist/browser/browser-adapter.d.mts +2 -2
- package/dist/browser/browser-adapter.d.ts +2 -2
- package/dist/claude-code/claude-code-adapter.d.mts +2 -2
- package/dist/claude-code/claude-code-adapter.d.ts +2 -2
- package/dist/cli/index.d.mts +2 -2
- package/dist/cli/index.d.ts +2 -2
- package/dist/cli/index.js +33 -6
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +33 -6
- package/dist/cli/index.mjs.map +1 -1
- package/dist/codex/index.d.mts +2 -2
- package/dist/codex/index.d.ts +2 -2
- package/dist/codex/index.js +60 -13
- package/dist/codex/index.js.map +1 -1
- package/dist/codex/index.mjs +60 -13
- package/dist/codex/index.mjs.map +1 -1
- package/dist/cursor/cursor-adapter.d.mts +2 -2
- package/dist/cursor/cursor-adapter.d.ts +2 -2
- package/dist/cursor/extension.d.mts +2 -2
- package/dist/cursor/extension.d.ts +2 -2
- package/dist/cursor/extension.js +60 -13
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +60 -13
- package/dist/cursor/extension.mjs.map +1 -1
- package/dist/edge-config.d.mts +1 -1
- package/dist/edge-config.d.ts +1 -1
- package/dist/edge-config.js +1 -1
- package/dist/edge-config.js.map +1 -1
- package/dist/edge-config.mjs +1 -1
- package/dist/edge-config.mjs.map +1 -1
- package/dist/edge-core/index.d.mts +1 -1
- package/dist/edge-core/index.d.ts +1 -1
- package/dist/edge-core/index.js +6 -1
- package/dist/edge-core/index.js.map +1 -1
- package/dist/edge-core/index.mjs +6 -1
- package/dist/edge-core/index.mjs.map +1 -1
- package/dist/{express-DaqL11tx.d.ts → express-D-8Ks2Uo.d.ts} +1 -1
- package/dist/{express-CR6F3njD.d.mts → express-DBtPKXOL.d.mts} +1 -1
- package/dist/gateway/gateway.d.mts +2 -2
- package/dist/gateway/gateway.d.ts +2 -2
- package/dist/gateway/gateway.js +60 -13
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +60 -13
- package/dist/gateway/gateway.mjs.map +1 -1
- package/dist/git-trigger/git-hooks.d.mts +2 -2
- package/dist/git-trigger/git-hooks.d.ts +2 -2
- package/dist/{index-BfIxCYIZ.d.ts → index-BND3kQev.d.ts} +1 -2
- package/dist/{index-CwAh7Tln.d.mts → index-CUfmJ1Dq.d.mts} +1 -2
- package/dist/{index-B5Ts1WtM.d.ts → index-DlZORQsb.d.ts} +1 -1
- package/dist/{index-Cub7lK-T.d.mts → index-kGCGWd5x.d.mts} +1 -1
- package/dist/index.d.mts +10 -10
- package/dist/index.d.ts +10 -10
- package/dist/index.js +17 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +12 -1
- package/dist/index.mjs.map +1 -1
- package/dist/local-evaluator/evaluator.d.mts +2 -2
- package/dist/local-evaluator/evaluator.d.ts +2 -2
- package/dist/local-evaluator/evaluator.js +22 -7
- package/dist/local-evaluator/evaluator.js.map +1 -1
- package/dist/local-evaluator/evaluator.mjs +22 -7
- package/dist/local-evaluator/evaluator.mjs.map +1 -1
- package/dist/mcp-DToTlwIn.d.ts +396 -0
- package/dist/mcp-ZRN4kY3b.d.mts +396 -0
- package/dist/{nextjs-DlX6xwbU.d.mts → nextjs-C0KASOy_.d.mts} +1 -1
- package/dist/{nextjs-DL6uE1ye.d.ts → nextjs-lwNvWYWT.d.ts} +1 -1
- package/dist/registration/index.d.mts +5 -1
- package/dist/registration/index.d.ts +5 -1
- package/dist/registration/index.js +2 -1
- package/dist/registration/index.js.map +1 -1
- package/dist/registration/index.mjs +2 -1
- package/dist/registration/index.mjs.map +1 -1
- package/dist/{sdk-C6SASmsh.d.ts → sdk-B4aodEwj.d.ts} +1 -1
- package/dist/{sdk-Bbh9B_dw.d.mts → sdk-B9dSwum7.d.mts} +1 -1
- package/dist/transport/index.d.mts +2 -2
- package/dist/transport/index.d.ts +2 -2
- package/dist/transport/index.js +1 -1
- package/dist/transport/index.js.map +1 -1
- package/dist/transport/index.mjs +1 -1
- package/dist/transport/index.mjs.map +1 -1
- package/dist/{types-DwSfO7Sb.d.ts → types-CGPU7HLi.d.ts} +8 -0
- package/dist/{types-nIh3HtuA.d.ts → types-CfSJLS4i.d.mts} +14 -1
- package/dist/{types-C0zfSXMB.d.mts → types-Cx9hTpKI.d.mts} +8 -0
- package/dist/{types-C7Rb-w0d.d.mts → types-DhhJxKIC.d.ts} +14 -1
- package/dist/ui/index.d.mts +1 -1
- package/dist/ui/index.d.ts +1 -1
- package/dist/verify.d.mts +1 -1
- package/dist/verify.d.ts +1 -1
- package/dist/verify.js +6 -1
- package/dist/verify.js.map +1 -1
- package/dist/verify.mjs +6 -1
- package/dist/verify.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -260,9 +260,9 @@ var LocalEvaluator = class {
|
|
|
260
260
|
if (scopeBlock) {
|
|
261
261
|
return { recommendation: "DENY", reason: scopeBlock };
|
|
262
262
|
}
|
|
263
|
-
const
|
|
264
|
-
if (
|
|
265
|
-
return
|
|
263
|
+
const limitDecision = this.checkLimits(context);
|
|
264
|
+
if (limitDecision) {
|
|
265
|
+
return limitDecision;
|
|
266
266
|
}
|
|
267
267
|
if (context.purpose === "sub_agent.spawn" && this.policy.selfInstantiation) {
|
|
268
268
|
if (!this.policy.selfInstantiation.allowed) {
|
|
@@ -327,9 +327,21 @@ var LocalEvaluator = class {
|
|
|
327
327
|
checkLimits(context) {
|
|
328
328
|
const limits = this.policy.limits;
|
|
329
329
|
if (!limits) return null;
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
330
|
+
const value = context.transactionValue;
|
|
331
|
+
if (value !== void 0 && value > 0 && (limits.autonomousThreshold !== void 0 || limits.maxTransactionAmount !== void 0)) {
|
|
332
|
+
const autonomousThreshold = limits.autonomousThreshold ?? 0;
|
|
333
|
+
const hardLimit = limits.maxTransactionAmount ?? limits.autonomousThreshold ?? 0;
|
|
334
|
+
if (value > autonomousThreshold) {
|
|
335
|
+
if (value >= hardLimit) {
|
|
336
|
+
return {
|
|
337
|
+
recommendation: "DENY",
|
|
338
|
+
reason: `Transaction value ${value} at or above Hard Limit ${hardLimit}`
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
return {
|
|
342
|
+
recommendation: "MANUAL_REVIEW",
|
|
343
|
+
reason: `Transaction value ${value} is in the human-approval band (${autonomousThreshold}, ${hardLimit})`
|
|
344
|
+
};
|
|
333
345
|
}
|
|
334
346
|
}
|
|
335
347
|
if (limits.maxRequestsPerHour !== void 0) {
|
|
@@ -342,7 +354,10 @@ var LocalEvaluator = class {
|
|
|
342
354
|
} else {
|
|
343
355
|
entry.count++;
|
|
344
356
|
if (entry.count > limits.maxRequestsPerHour) {
|
|
345
|
-
return
|
|
357
|
+
return {
|
|
358
|
+
recommendation: "DENY",
|
|
359
|
+
reason: `Rate limit exceeded: ${entry.count}/${limits.maxRequestsPerHour} requests per hour`
|
|
360
|
+
};
|
|
346
361
|
}
|
|
347
362
|
}
|
|
348
363
|
}
|
|
@@ -3551,10 +3566,16 @@ function validatePurpose(purpose, path) {
|
|
|
3551
3566
|
errors.push({ path: `${path}.targets`, message: "targets must be an array of strings" });
|
|
3552
3567
|
}
|
|
3553
3568
|
if (p.blockedPatterns !== void 0 && !isStringArray(p.blockedPatterns)) {
|
|
3554
|
-
errors.push({
|
|
3569
|
+
errors.push({
|
|
3570
|
+
path: `${path}.blockedPatterns`,
|
|
3571
|
+
message: "blockedPatterns must be an array of strings"
|
|
3572
|
+
});
|
|
3555
3573
|
}
|
|
3556
3574
|
if (p.requiresApproval !== void 0 && typeof p.requiresApproval !== "boolean") {
|
|
3557
|
-
errors.push({
|
|
3575
|
+
errors.push({
|
|
3576
|
+
path: `${path}.requiresApproval`,
|
|
3577
|
+
message: "requiresApproval must be a boolean"
|
|
3578
|
+
});
|
|
3558
3579
|
}
|
|
3559
3580
|
return errors;
|
|
3560
3581
|
}
|
|
@@ -3577,11 +3598,29 @@ function validateLimits(limits, path) {
|
|
|
3577
3598
|
return [{ path, message: "limits must be an object" }];
|
|
3578
3599
|
}
|
|
3579
3600
|
const l = limits;
|
|
3601
|
+
if (l.autonomousThreshold !== void 0 && typeof l.autonomousThreshold !== "number") {
|
|
3602
|
+
errors.push({
|
|
3603
|
+
path: `${path}.autonomousThreshold`,
|
|
3604
|
+
message: "autonomousThreshold must be a number"
|
|
3605
|
+
});
|
|
3606
|
+
}
|
|
3580
3607
|
if (l.maxTransactionAmount !== void 0 && typeof l.maxTransactionAmount !== "number") {
|
|
3581
|
-
errors.push({
|
|
3608
|
+
errors.push({
|
|
3609
|
+
path: `${path}.maxTransactionAmount`,
|
|
3610
|
+
message: "maxTransactionAmount must be a number"
|
|
3611
|
+
});
|
|
3612
|
+
}
|
|
3613
|
+
if (typeof l.autonomousThreshold === "number" && typeof l.maxTransactionAmount === "number" && l.autonomousThreshold > l.maxTransactionAmount) {
|
|
3614
|
+
errors.push({
|
|
3615
|
+
path: `${path}.autonomousThreshold`,
|
|
3616
|
+
message: "autonomousThreshold (Autonomous Limit) must be <= maxTransactionAmount (Hard Limit)"
|
|
3617
|
+
});
|
|
3582
3618
|
}
|
|
3583
3619
|
if (l.maxRequestsPerHour !== void 0 && typeof l.maxRequestsPerHour !== "number") {
|
|
3584
|
-
errors.push({
|
|
3620
|
+
errors.push({
|
|
3621
|
+
path: `${path}.maxRequestsPerHour`,
|
|
3622
|
+
message: "maxRequestsPerHour must be a number"
|
|
3623
|
+
});
|
|
3585
3624
|
}
|
|
3586
3625
|
if (l.currency !== void 0 && typeof l.currency !== "string") {
|
|
3587
3626
|
errors.push({ path: `${path}.currency`, message: "currency must be a string" });
|
|
@@ -3596,7 +3635,10 @@ function validateRiskThresholds(thresholds, path) {
|
|
|
3596
3635
|
const t = thresholds;
|
|
3597
3636
|
for (const range of ["autoAllow", "requireApproval", "autoBlock"]) {
|
|
3598
3637
|
if (!t[range] || typeof t[range] !== "object") {
|
|
3599
|
-
errors.push({
|
|
3638
|
+
errors.push({
|
|
3639
|
+
path: `${path}.${range}`,
|
|
3640
|
+
message: `${range} is required and must be an object with min and max`
|
|
3641
|
+
});
|
|
3600
3642
|
continue;
|
|
3601
3643
|
}
|
|
3602
3644
|
const r = t[range];
|
|
@@ -3701,7 +3743,7 @@ function getTrustLevel(score) {
|
|
|
3701
3743
|
}
|
|
3702
3744
|
|
|
3703
3745
|
// src/version.ts
|
|
3704
|
-
var SDK_VERSION = "4.
|
|
3746
|
+
var SDK_VERSION = "4.6.0";
|
|
3705
3747
|
|
|
3706
3748
|
// src/http.ts
|
|
3707
3749
|
var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
|
|
@@ -3925,6 +3967,11 @@ function createGuidanceResponse(_config, reason, options = {}) {
|
|
|
3925
3967
|
// 4.0.0: typed marker so adapters render the misconfig envelope (503 +
|
|
3926
3968
|
// MERCHANT_VERIFICATION_MISCONFIGURED) without string-matching.
|
|
3927
3969
|
...isMisconfig && { misconfigured: true },
|
|
3970
|
+
// 4.6.0: a transient api_error is retryable — mark it so consumers surface
|
|
3971
|
+
// "temporarily unavailable, retry" (recommendation 'error') instead of
|
|
3972
|
+
// coercing the absent recommendation to a policy 'deny'. Misconfig is
|
|
3973
|
+
// deterministic and intentionally NOT marked retryable.
|
|
3974
|
+
...isApiError && { retryable: true },
|
|
3928
3975
|
correlationId: options.correlationId,
|
|
3929
3976
|
attemptId: options.attemptId,
|
|
3930
3977
|
verifiedAt: /* @__PURE__ */ new Date()
|
|
@@ -259,9 +259,9 @@ var LocalEvaluator = class {
|
|
|
259
259
|
if (scopeBlock) {
|
|
260
260
|
return { recommendation: "DENY", reason: scopeBlock };
|
|
261
261
|
}
|
|
262
|
-
const
|
|
263
|
-
if (
|
|
264
|
-
return
|
|
262
|
+
const limitDecision = this.checkLimits(context);
|
|
263
|
+
if (limitDecision) {
|
|
264
|
+
return limitDecision;
|
|
265
265
|
}
|
|
266
266
|
if (context.purpose === "sub_agent.spawn" && this.policy.selfInstantiation) {
|
|
267
267
|
if (!this.policy.selfInstantiation.allowed) {
|
|
@@ -326,9 +326,21 @@ var LocalEvaluator = class {
|
|
|
326
326
|
checkLimits(context) {
|
|
327
327
|
const limits = this.policy.limits;
|
|
328
328
|
if (!limits) return null;
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
329
|
+
const value = context.transactionValue;
|
|
330
|
+
if (value !== void 0 && value > 0 && (limits.autonomousThreshold !== void 0 || limits.maxTransactionAmount !== void 0)) {
|
|
331
|
+
const autonomousThreshold = limits.autonomousThreshold ?? 0;
|
|
332
|
+
const hardLimit = limits.maxTransactionAmount ?? limits.autonomousThreshold ?? 0;
|
|
333
|
+
if (value > autonomousThreshold) {
|
|
334
|
+
if (value >= hardLimit) {
|
|
335
|
+
return {
|
|
336
|
+
recommendation: "DENY",
|
|
337
|
+
reason: `Transaction value ${value} at or above Hard Limit ${hardLimit}`
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
return {
|
|
341
|
+
recommendation: "MANUAL_REVIEW",
|
|
342
|
+
reason: `Transaction value ${value} is in the human-approval band (${autonomousThreshold}, ${hardLimit})`
|
|
343
|
+
};
|
|
332
344
|
}
|
|
333
345
|
}
|
|
334
346
|
if (limits.maxRequestsPerHour !== void 0) {
|
|
@@ -341,7 +353,10 @@ var LocalEvaluator = class {
|
|
|
341
353
|
} else {
|
|
342
354
|
entry.count++;
|
|
343
355
|
if (entry.count > limits.maxRequestsPerHour) {
|
|
344
|
-
return
|
|
356
|
+
return {
|
|
357
|
+
recommendation: "DENY",
|
|
358
|
+
reason: `Rate limit exceeded: ${entry.count}/${limits.maxRequestsPerHour} requests per hour`
|
|
359
|
+
};
|
|
345
360
|
}
|
|
346
361
|
}
|
|
347
362
|
}
|
|
@@ -3550,10 +3565,16 @@ function validatePurpose(purpose, path) {
|
|
|
3550
3565
|
errors.push({ path: `${path}.targets`, message: "targets must be an array of strings" });
|
|
3551
3566
|
}
|
|
3552
3567
|
if (p.blockedPatterns !== void 0 && !isStringArray(p.blockedPatterns)) {
|
|
3553
|
-
errors.push({
|
|
3568
|
+
errors.push({
|
|
3569
|
+
path: `${path}.blockedPatterns`,
|
|
3570
|
+
message: "blockedPatterns must be an array of strings"
|
|
3571
|
+
});
|
|
3554
3572
|
}
|
|
3555
3573
|
if (p.requiresApproval !== void 0 && typeof p.requiresApproval !== "boolean") {
|
|
3556
|
-
errors.push({
|
|
3574
|
+
errors.push({
|
|
3575
|
+
path: `${path}.requiresApproval`,
|
|
3576
|
+
message: "requiresApproval must be a boolean"
|
|
3577
|
+
});
|
|
3557
3578
|
}
|
|
3558
3579
|
return errors;
|
|
3559
3580
|
}
|
|
@@ -3576,11 +3597,29 @@ function validateLimits(limits, path) {
|
|
|
3576
3597
|
return [{ path, message: "limits must be an object" }];
|
|
3577
3598
|
}
|
|
3578
3599
|
const l = limits;
|
|
3600
|
+
if (l.autonomousThreshold !== void 0 && typeof l.autonomousThreshold !== "number") {
|
|
3601
|
+
errors.push({
|
|
3602
|
+
path: `${path}.autonomousThreshold`,
|
|
3603
|
+
message: "autonomousThreshold must be a number"
|
|
3604
|
+
});
|
|
3605
|
+
}
|
|
3579
3606
|
if (l.maxTransactionAmount !== void 0 && typeof l.maxTransactionAmount !== "number") {
|
|
3580
|
-
errors.push({
|
|
3607
|
+
errors.push({
|
|
3608
|
+
path: `${path}.maxTransactionAmount`,
|
|
3609
|
+
message: "maxTransactionAmount must be a number"
|
|
3610
|
+
});
|
|
3611
|
+
}
|
|
3612
|
+
if (typeof l.autonomousThreshold === "number" && typeof l.maxTransactionAmount === "number" && l.autonomousThreshold > l.maxTransactionAmount) {
|
|
3613
|
+
errors.push({
|
|
3614
|
+
path: `${path}.autonomousThreshold`,
|
|
3615
|
+
message: "autonomousThreshold (Autonomous Limit) must be <= maxTransactionAmount (Hard Limit)"
|
|
3616
|
+
});
|
|
3581
3617
|
}
|
|
3582
3618
|
if (l.maxRequestsPerHour !== void 0 && typeof l.maxRequestsPerHour !== "number") {
|
|
3583
|
-
errors.push({
|
|
3619
|
+
errors.push({
|
|
3620
|
+
path: `${path}.maxRequestsPerHour`,
|
|
3621
|
+
message: "maxRequestsPerHour must be a number"
|
|
3622
|
+
});
|
|
3584
3623
|
}
|
|
3585
3624
|
if (l.currency !== void 0 && typeof l.currency !== "string") {
|
|
3586
3625
|
errors.push({ path: `${path}.currency`, message: "currency must be a string" });
|
|
@@ -3595,7 +3634,10 @@ function validateRiskThresholds(thresholds, path) {
|
|
|
3595
3634
|
const t = thresholds;
|
|
3596
3635
|
for (const range of ["autoAllow", "requireApproval", "autoBlock"]) {
|
|
3597
3636
|
if (!t[range] || typeof t[range] !== "object") {
|
|
3598
|
-
errors.push({
|
|
3637
|
+
errors.push({
|
|
3638
|
+
path: `${path}.${range}`,
|
|
3639
|
+
message: `${range} is required and must be an object with min and max`
|
|
3640
|
+
});
|
|
3599
3641
|
continue;
|
|
3600
3642
|
}
|
|
3601
3643
|
const r = t[range];
|
|
@@ -3700,7 +3742,7 @@ function getTrustLevel(score) {
|
|
|
3700
3742
|
}
|
|
3701
3743
|
|
|
3702
3744
|
// src/version.ts
|
|
3703
|
-
var SDK_VERSION = "4.
|
|
3745
|
+
var SDK_VERSION = "4.6.0";
|
|
3704
3746
|
|
|
3705
3747
|
// src/http.ts
|
|
3706
3748
|
var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
|
|
@@ -3924,6 +3966,11 @@ function createGuidanceResponse(_config, reason, options = {}) {
|
|
|
3924
3966
|
// 4.0.0: typed marker so adapters render the misconfig envelope (503 +
|
|
3925
3967
|
// MERCHANT_VERIFICATION_MISCONFIGURED) without string-matching.
|
|
3926
3968
|
...isMisconfig && { misconfigured: true },
|
|
3969
|
+
// 4.6.0: a transient api_error is retryable — mark it so consumers surface
|
|
3970
|
+
// "temporarily unavailable, retry" (recommendation 'error') instead of
|
|
3971
|
+
// coercing the absent recommendation to a policy 'deny'. Misconfig is
|
|
3972
|
+
// deterministic and intentionally NOT marked retryable.
|
|
3973
|
+
...isApiError && { retryable: true },
|
|
3927
3974
|
correlationId: options.correlationId,
|
|
3928
3975
|
attemptId: options.attemptId,
|
|
3929
3976
|
verifiedAt: /* @__PURE__ */ new Date()
|
|
@@ -3137,10 +3137,16 @@ function validatePurpose(purpose, path2) {
|
|
|
3137
3137
|
errors.push({ path: `${path2}.targets`, message: "targets must be an array of strings" });
|
|
3138
3138
|
}
|
|
3139
3139
|
if (p.blockedPatterns !== void 0 && !isStringArray(p.blockedPatterns)) {
|
|
3140
|
-
errors.push({
|
|
3140
|
+
errors.push({
|
|
3141
|
+
path: `${path2}.blockedPatterns`,
|
|
3142
|
+
message: "blockedPatterns must be an array of strings"
|
|
3143
|
+
});
|
|
3141
3144
|
}
|
|
3142
3145
|
if (p.requiresApproval !== void 0 && typeof p.requiresApproval !== "boolean") {
|
|
3143
|
-
errors.push({
|
|
3146
|
+
errors.push({
|
|
3147
|
+
path: `${path2}.requiresApproval`,
|
|
3148
|
+
message: "requiresApproval must be a boolean"
|
|
3149
|
+
});
|
|
3144
3150
|
}
|
|
3145
3151
|
return errors;
|
|
3146
3152
|
}
|
|
@@ -3163,11 +3169,29 @@ function validateLimits(limits, path2) {
|
|
|
3163
3169
|
return [{ path: path2, message: "limits must be an object" }];
|
|
3164
3170
|
}
|
|
3165
3171
|
const l = limits;
|
|
3172
|
+
if (l.autonomousThreshold !== void 0 && typeof l.autonomousThreshold !== "number") {
|
|
3173
|
+
errors.push({
|
|
3174
|
+
path: `${path2}.autonomousThreshold`,
|
|
3175
|
+
message: "autonomousThreshold must be a number"
|
|
3176
|
+
});
|
|
3177
|
+
}
|
|
3166
3178
|
if (l.maxTransactionAmount !== void 0 && typeof l.maxTransactionAmount !== "number") {
|
|
3167
|
-
errors.push({
|
|
3179
|
+
errors.push({
|
|
3180
|
+
path: `${path2}.maxTransactionAmount`,
|
|
3181
|
+
message: "maxTransactionAmount must be a number"
|
|
3182
|
+
});
|
|
3183
|
+
}
|
|
3184
|
+
if (typeof l.autonomousThreshold === "number" && typeof l.maxTransactionAmount === "number" && l.autonomousThreshold > l.maxTransactionAmount) {
|
|
3185
|
+
errors.push({
|
|
3186
|
+
path: `${path2}.autonomousThreshold`,
|
|
3187
|
+
message: "autonomousThreshold (Autonomous Limit) must be <= maxTransactionAmount (Hard Limit)"
|
|
3188
|
+
});
|
|
3168
3189
|
}
|
|
3169
3190
|
if (l.maxRequestsPerHour !== void 0 && typeof l.maxRequestsPerHour !== "number") {
|
|
3170
|
-
errors.push({
|
|
3191
|
+
errors.push({
|
|
3192
|
+
path: `${path2}.maxRequestsPerHour`,
|
|
3193
|
+
message: "maxRequestsPerHour must be a number"
|
|
3194
|
+
});
|
|
3171
3195
|
}
|
|
3172
3196
|
if (l.currency !== void 0 && typeof l.currency !== "string") {
|
|
3173
3197
|
errors.push({ path: `${path2}.currency`, message: "currency must be a string" });
|
|
@@ -3182,7 +3206,10 @@ function validateRiskThresholds(thresholds, path2) {
|
|
|
3182
3206
|
const t = thresholds;
|
|
3183
3207
|
for (const range of ["autoAllow", "requireApproval", "autoBlock"]) {
|
|
3184
3208
|
if (!t[range] || typeof t[range] !== "object") {
|
|
3185
|
-
errors.push({
|
|
3209
|
+
errors.push({
|
|
3210
|
+
path: `${path2}.${range}`,
|
|
3211
|
+
message: `${range} is required and must be an object with min and max`
|
|
3212
|
+
});
|
|
3186
3213
|
continue;
|
|
3187
3214
|
}
|
|
3188
3215
|
const r = t[range];
|
|
@@ -3678,7 +3705,7 @@ Policy saved to ${outputPath}`);
|
|
|
3678
3705
|
};
|
|
3679
3706
|
|
|
3680
3707
|
// src/version.ts
|
|
3681
|
-
var SDK_VERSION = "4.
|
|
3708
|
+
var SDK_VERSION = "4.6.0";
|
|
3682
3709
|
|
|
3683
3710
|
// src/http.ts
|
|
3684
3711
|
var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
|
|
@@ -4419,9 +4446,9 @@ var LocalEvaluator = class {
|
|
|
4419
4446
|
if (scopeBlock) {
|
|
4420
4447
|
return { recommendation: "DENY", reason: scopeBlock };
|
|
4421
4448
|
}
|
|
4422
|
-
const
|
|
4423
|
-
if (
|
|
4424
|
-
return
|
|
4449
|
+
const limitDecision = this.checkLimits(context);
|
|
4450
|
+
if (limitDecision) {
|
|
4451
|
+
return limitDecision;
|
|
4425
4452
|
}
|
|
4426
4453
|
if (context.purpose === "sub_agent.spawn" && this.policy.selfInstantiation) {
|
|
4427
4454
|
if (!this.policy.selfInstantiation.allowed) {
|
|
@@ -4486,9 +4513,21 @@ var LocalEvaluator = class {
|
|
|
4486
4513
|
checkLimits(context) {
|
|
4487
4514
|
const limits = this.policy.limits;
|
|
4488
4515
|
if (!limits) return null;
|
|
4489
|
-
|
|
4490
|
-
|
|
4491
|
-
|
|
4516
|
+
const value = context.transactionValue;
|
|
4517
|
+
if (value !== void 0 && value > 0 && (limits.autonomousThreshold !== void 0 || limits.maxTransactionAmount !== void 0)) {
|
|
4518
|
+
const autonomousThreshold = limits.autonomousThreshold ?? 0;
|
|
4519
|
+
const hardLimit = limits.maxTransactionAmount ?? limits.autonomousThreshold ?? 0;
|
|
4520
|
+
if (value > autonomousThreshold) {
|
|
4521
|
+
if (value >= hardLimit) {
|
|
4522
|
+
return {
|
|
4523
|
+
recommendation: "DENY",
|
|
4524
|
+
reason: `Transaction value ${value} at or above Hard Limit ${hardLimit}`
|
|
4525
|
+
};
|
|
4526
|
+
}
|
|
4527
|
+
return {
|
|
4528
|
+
recommendation: "MANUAL_REVIEW",
|
|
4529
|
+
reason: `Transaction value ${value} is in the human-approval band (${autonomousThreshold}, ${hardLimit})`
|
|
4530
|
+
};
|
|
4492
4531
|
}
|
|
4493
4532
|
}
|
|
4494
4533
|
if (limits.maxRequestsPerHour !== void 0) {
|
|
@@ -4501,7 +4540,10 @@ var LocalEvaluator = class {
|
|
|
4501
4540
|
} else {
|
|
4502
4541
|
entry.count++;
|
|
4503
4542
|
if (entry.count > limits.maxRequestsPerHour) {
|
|
4504
|
-
return
|
|
4543
|
+
return {
|
|
4544
|
+
recommendation: "DENY",
|
|
4545
|
+
reason: `Rate limit exceeded: ${entry.count}/${limits.maxRequestsPerHour} requests per hour`
|
|
4546
|
+
};
|
|
4505
4547
|
}
|
|
4506
4548
|
}
|
|
4507
4549
|
}
|
|
@@ -4833,6 +4875,11 @@ function createGuidanceResponse(_config, reason, options = {}) {
|
|
|
4833
4875
|
// 4.0.0: typed marker so adapters render the misconfig envelope (503 +
|
|
4834
4876
|
// MERCHANT_VERIFICATION_MISCONFIGURED) without string-matching.
|
|
4835
4877
|
...isMisconfig && { misconfigured: true },
|
|
4878
|
+
// 4.6.0: a transient api_error is retryable — mark it so consumers surface
|
|
4879
|
+
// "temporarily unavailable, retry" (recommendation 'error') instead of
|
|
4880
|
+
// coercing the absent recommendation to a policy 'deny'. Misconfig is
|
|
4881
|
+
// deterministic and intentionally NOT marked retryable.
|
|
4882
|
+
...isApiError && { retryable: true },
|
|
4836
4883
|
correlationId: options.correlationId,
|
|
4837
4884
|
attemptId: options.attemptId,
|
|
4838
4885
|
verifiedAt: /* @__PURE__ */ new Date()
|
package/dist/bin/astrasync.js
CHANGED
|
@@ -6,8 +6,13 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
6
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
7
|
var __getProtoOf = Object.getPrototypeOf;
|
|
8
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
-
var __esm = (fn, res) => function __init() {
|
|
10
|
-
|
|
9
|
+
var __esm = (fn, res, err) => function __init() {
|
|
10
|
+
if (err) throw err[0];
|
|
11
|
+
try {
|
|
12
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
13
|
+
} catch (e) {
|
|
14
|
+
throw err = [e], e;
|
|
15
|
+
}
|
|
11
16
|
};
|
|
12
17
|
var __copyProps = (to, from, except, desc) => {
|
|
13
18
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
@@ -31,7 +36,7 @@ var SDK_VERSION;
|
|
|
31
36
|
var init_version = __esm({
|
|
32
37
|
"src/version.ts"() {
|
|
33
38
|
"use strict";
|
|
34
|
-
SDK_VERSION = "4.
|
|
39
|
+
SDK_VERSION = "4.6.0";
|
|
35
40
|
}
|
|
36
41
|
});
|
|
37
42
|
|
|
@@ -3477,10 +3482,16 @@ function validatePurpose(purpose, path2) {
|
|
|
3477
3482
|
errors.push({ path: `${path2}.targets`, message: "targets must be an array of strings" });
|
|
3478
3483
|
}
|
|
3479
3484
|
if (p.blockedPatterns !== void 0 && !isStringArray(p.blockedPatterns)) {
|
|
3480
|
-
errors.push({
|
|
3485
|
+
errors.push({
|
|
3486
|
+
path: `${path2}.blockedPatterns`,
|
|
3487
|
+
message: "blockedPatterns must be an array of strings"
|
|
3488
|
+
});
|
|
3481
3489
|
}
|
|
3482
3490
|
if (p.requiresApproval !== void 0 && typeof p.requiresApproval !== "boolean") {
|
|
3483
|
-
errors.push({
|
|
3491
|
+
errors.push({
|
|
3492
|
+
path: `${path2}.requiresApproval`,
|
|
3493
|
+
message: "requiresApproval must be a boolean"
|
|
3494
|
+
});
|
|
3484
3495
|
}
|
|
3485
3496
|
return errors;
|
|
3486
3497
|
}
|
|
@@ -3503,11 +3514,29 @@ function validateLimits(limits, path2) {
|
|
|
3503
3514
|
return [{ path: path2, message: "limits must be an object" }];
|
|
3504
3515
|
}
|
|
3505
3516
|
const l = limits;
|
|
3517
|
+
if (l.autonomousThreshold !== void 0 && typeof l.autonomousThreshold !== "number") {
|
|
3518
|
+
errors.push({
|
|
3519
|
+
path: `${path2}.autonomousThreshold`,
|
|
3520
|
+
message: "autonomousThreshold must be a number"
|
|
3521
|
+
});
|
|
3522
|
+
}
|
|
3506
3523
|
if (l.maxTransactionAmount !== void 0 && typeof l.maxTransactionAmount !== "number") {
|
|
3507
|
-
errors.push({
|
|
3524
|
+
errors.push({
|
|
3525
|
+
path: `${path2}.maxTransactionAmount`,
|
|
3526
|
+
message: "maxTransactionAmount must be a number"
|
|
3527
|
+
});
|
|
3528
|
+
}
|
|
3529
|
+
if (typeof l.autonomousThreshold === "number" && typeof l.maxTransactionAmount === "number" && l.autonomousThreshold > l.maxTransactionAmount) {
|
|
3530
|
+
errors.push({
|
|
3531
|
+
path: `${path2}.autonomousThreshold`,
|
|
3532
|
+
message: "autonomousThreshold (Autonomous Limit) must be <= maxTransactionAmount (Hard Limit)"
|
|
3533
|
+
});
|
|
3508
3534
|
}
|
|
3509
3535
|
if (l.maxRequestsPerHour !== void 0 && typeof l.maxRequestsPerHour !== "number") {
|
|
3510
|
-
errors.push({
|
|
3536
|
+
errors.push({
|
|
3537
|
+
path: `${path2}.maxRequestsPerHour`,
|
|
3538
|
+
message: "maxRequestsPerHour must be a number"
|
|
3539
|
+
});
|
|
3511
3540
|
}
|
|
3512
3541
|
if (l.currency !== void 0 && typeof l.currency !== "string") {
|
|
3513
3542
|
errors.push({ path: `${path2}.currency`, message: "currency must be a string" });
|
|
@@ -3522,7 +3551,10 @@ function validateRiskThresholds(thresholds, path2) {
|
|
|
3522
3551
|
const t = thresholds;
|
|
3523
3552
|
for (const range of ["autoAllow", "requireApproval", "autoBlock"]) {
|
|
3524
3553
|
if (!t[range] || typeof t[range] !== "object") {
|
|
3525
|
-
errors.push({
|
|
3554
|
+
errors.push({
|
|
3555
|
+
path: `${path2}.${range}`,
|
|
3556
|
+
message: `${range} is required and must be an object with min and max`
|
|
3557
|
+
});
|
|
3526
3558
|
continue;
|
|
3527
3559
|
}
|
|
3528
3560
|
const r = t[range];
|
|
@@ -4807,9 +4839,9 @@ var init_evaluator = __esm({
|
|
|
4807
4839
|
if (scopeBlock) {
|
|
4808
4840
|
return { recommendation: "DENY", reason: scopeBlock };
|
|
4809
4841
|
}
|
|
4810
|
-
const
|
|
4811
|
-
if (
|
|
4812
|
-
return
|
|
4842
|
+
const limitDecision = this.checkLimits(context);
|
|
4843
|
+
if (limitDecision) {
|
|
4844
|
+
return limitDecision;
|
|
4813
4845
|
}
|
|
4814
4846
|
if (context.purpose === "sub_agent.spawn" && this.policy.selfInstantiation) {
|
|
4815
4847
|
if (!this.policy.selfInstantiation.allowed) {
|
|
@@ -4874,9 +4906,21 @@ var init_evaluator = __esm({
|
|
|
4874
4906
|
checkLimits(context) {
|
|
4875
4907
|
const limits = this.policy.limits;
|
|
4876
4908
|
if (!limits) return null;
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
|
|
4909
|
+
const value = context.transactionValue;
|
|
4910
|
+
if (value !== void 0 && value > 0 && (limits.autonomousThreshold !== void 0 || limits.maxTransactionAmount !== void 0)) {
|
|
4911
|
+
const autonomousThreshold = limits.autonomousThreshold ?? 0;
|
|
4912
|
+
const hardLimit = limits.maxTransactionAmount ?? limits.autonomousThreshold ?? 0;
|
|
4913
|
+
if (value > autonomousThreshold) {
|
|
4914
|
+
if (value >= hardLimit) {
|
|
4915
|
+
return {
|
|
4916
|
+
recommendation: "DENY",
|
|
4917
|
+
reason: `Transaction value ${value} at or above Hard Limit ${hardLimit}`
|
|
4918
|
+
};
|
|
4919
|
+
}
|
|
4920
|
+
return {
|
|
4921
|
+
recommendation: "MANUAL_REVIEW",
|
|
4922
|
+
reason: `Transaction value ${value} is in the human-approval band (${autonomousThreshold}, ${hardLimit})`
|
|
4923
|
+
};
|
|
4880
4924
|
}
|
|
4881
4925
|
}
|
|
4882
4926
|
if (limits.maxRequestsPerHour !== void 0) {
|
|
@@ -4889,7 +4933,10 @@ var init_evaluator = __esm({
|
|
|
4889
4933
|
} else {
|
|
4890
4934
|
entry.count++;
|
|
4891
4935
|
if (entry.count > limits.maxRequestsPerHour) {
|
|
4892
|
-
return
|
|
4936
|
+
return {
|
|
4937
|
+
recommendation: "DENY",
|
|
4938
|
+
reason: `Rate limit exceeded: ${entry.count}/${limits.maxRequestsPerHour} requests per hour`
|
|
4939
|
+
};
|
|
4893
4940
|
}
|
|
4894
4941
|
}
|
|
4895
4942
|
}
|
|
@@ -5224,6 +5271,11 @@ function createGuidanceResponse(_config, reason, options = {}) {
|
|
|
5224
5271
|
// 4.0.0: typed marker so adapters render the misconfig envelope (503 +
|
|
5225
5272
|
// MERCHANT_VERIFICATION_MISCONFIGURED) without string-matching.
|
|
5226
5273
|
...isMisconfig && { misconfigured: true },
|
|
5274
|
+
// 4.6.0: a transient api_error is retryable — mark it so consumers surface
|
|
5275
|
+
// "temporarily unavailable, retry" (recommendation 'error') instead of
|
|
5276
|
+
// coercing the absent recommendation to a policy 'deny'. Misconfig is
|
|
5277
|
+
// deterministic and intentionally NOT marked retryable.
|
|
5278
|
+
...isApiError && { retryable: true },
|
|
5227
5279
|
correlationId: options.correlationId,
|
|
5228
5280
|
attemptId: options.attemptId,
|
|
5229
5281
|
verifiedAt: /* @__PURE__ */ new Date()
|
|
@@ -6142,6 +6194,7 @@ var init_src = __esm({
|
|
|
6142
6194
|
init_verify();
|
|
6143
6195
|
init_metadata_capture();
|
|
6144
6196
|
init_runtime_signatures();
|
|
6197
|
+
init_verified_hop();
|
|
6145
6198
|
init_http();
|
|
6146
6199
|
init_version();
|
|
6147
6200
|
}
|