@decionis/mcp 0.2.0 → 0.3.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 +24 -2
- package/dist/AgentHookCli.js +2 -2
- package/dist/ManagedAgentHookCli.js +328 -194
- package/dist/agent/AgentIndex.js +2 -2
- package/dist/{chunk-7QNV7MXC.js → chunk-ABHNQFWI.js} +2 -2
- package/dist/{chunk-NF5JL6QR.js → chunk-LIVLO4MV.js} +329 -195
- package/dist/chunk-LIVLO4MV.js.map +1 -0
- package/dist/index.js +312 -52
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/dist/chunk-NF5JL6QR.js.map +0 -1
- /package/dist/{chunk-7QNV7MXC.js.map → chunk-ABHNQFWI.js.map} +0 -0
|
@@ -42279,6 +42279,19 @@ var FinalizationEffectEvidenceSchema = external_exports.union([
|
|
|
42279
42279
|
EffectEvidenceSchema,
|
|
42280
42280
|
ExecutionEffectEvidenceSchema
|
|
42281
42281
|
]);
|
|
42282
|
+
var EffectReceiptRecordSchema = external_exports.object({
|
|
42283
|
+
token: external_exports.string().min(1).max(2e4),
|
|
42284
|
+
token_digest: external_exports.string().regex(/^sha256:[0-9a-f]{64}$/),
|
|
42285
|
+
verified: external_exports.boolean(),
|
|
42286
|
+
verification_code: external_exports.string().min(1).max(100),
|
|
42287
|
+
provider_key_id: external_exports.string().min(1).max(200).nullable(),
|
|
42288
|
+
issuer: external_exports.string().min(1).max(500).nullable(),
|
|
42289
|
+
receipt_jti: external_exports.string().min(1).max(200).nullable(),
|
|
42290
|
+
effect_status: external_exports.enum(["EFFECTED", "REFUSED", "INDETERMINATE"]).nullable(),
|
|
42291
|
+
effect_digest: external_exports.string().regex(/^sha256:[0-9a-f]{64}$/).nullable(),
|
|
42292
|
+
effect_reference: external_exports.string().min(1).max(2e3).nullable(),
|
|
42293
|
+
effected_at: external_exports.string().datetime().nullable()
|
|
42294
|
+
}).strict();
|
|
42282
42295
|
function validateExecutionEffectEvidence(input) {
|
|
42283
42296
|
if (!input.expected_request_digest) return "EFFECT_REQUEST_BINDING_UNAVAILABLE";
|
|
42284
42297
|
if (input.effect_evidence.request_digest !== input.expected_request_digest) {
|
|
@@ -42302,6 +42315,7 @@ var ExecutionCommitEvidenceSchema = external_exports.object({
|
|
|
42302
42315
|
recorded_at: external_exports.string().datetime(),
|
|
42303
42316
|
downstream_evidence_digest: external_exports.string().regex(/^sha256:[0-9a-f]{64}$/),
|
|
42304
42317
|
effect_evidence: FinalizationEffectEvidenceSchema.nullable().optional(),
|
|
42318
|
+
effect_receipt: EffectReceiptRecordSchema.nullable().optional(),
|
|
42305
42319
|
evidence_hash: external_exports.string().regex(/^sha256:[0-9a-f]{64}$/)
|
|
42306
42320
|
}).strict().superRefine((evidence, context) => {
|
|
42307
42321
|
const expectedClaimState = evidence.commit_outcome === "COMMITTED" ? "FINALIZED" : evidence.commit_outcome === "FAILED" ? "FAILED" : "INDETERMINATE";
|
|
@@ -42673,10 +42687,22 @@ var AuthorityVerificationRequirementsSchema = external_exports.object({
|
|
|
42673
42687
|
});
|
|
42674
42688
|
}
|
|
42675
42689
|
});
|
|
42690
|
+
var AuthorityApprovalTierSchema = external_exports.object({
|
|
42691
|
+
priority: external_exports.number().int().min(1).max(5),
|
|
42692
|
+
principal_ids: external_exports.array(external_exports.string().min(1).max(200)).min(1).max(10)
|
|
42693
|
+
}).strict();
|
|
42676
42694
|
var AuthorityResolutionPolicySchema = external_exports.object({
|
|
42677
42695
|
quorum: external_exports.literal(1),
|
|
42678
42696
|
delegation: external_exports.enum(["DISALLOWED", "REQUIREMENT_REFRESH"]),
|
|
42679
|
-
fallback_role_ids: external_exports.array(external_exports.string().regex(/^[A-Z][A-Z0-9_]{1,63}$/)).max(10).default([])
|
|
42697
|
+
fallback_role_ids: external_exports.array(external_exports.string().regex(/^[A-Z][A-Z0-9_]{1,63}$/)).max(10).default([]),
|
|
42698
|
+
/**
|
|
42699
|
+
* An approval chain. Absent, the requirement is one ceremony by one subject
|
|
42700
|
+
* (`quorum` 1). Present, the policy names who approves in priority tiers and
|
|
42701
|
+
* the requirement is met only by one valid proof from every tier; Decionis
|
|
42702
|
+
* keeps no chain state — the orchestrator (or Presence) runs it and Decionis
|
|
42703
|
+
* verifies each proof against the tier it comes from.
|
|
42704
|
+
*/
|
|
42705
|
+
tiers: external_exports.array(AuthorityApprovalTierSchema).min(1).max(5).optional()
|
|
42680
42706
|
}).strict().superRefine((policy, context) => {
|
|
42681
42707
|
if (new Set(policy.fallback_role_ids).size !== policy.fallback_role_ids.length) {
|
|
42682
42708
|
context.addIssue({
|
|
@@ -42685,6 +42711,24 @@ var AuthorityResolutionPolicySchema = external_exports.object({
|
|
|
42685
42711
|
message: "fallback role ids must be unique"
|
|
42686
42712
|
});
|
|
42687
42713
|
}
|
|
42714
|
+
if (policy.tiers) {
|
|
42715
|
+
const priorities = policy.tiers.map((tier) => tier.priority);
|
|
42716
|
+
if (priorities.some((priority, index) => index > 0 && priority <= priorities[index - 1])) {
|
|
42717
|
+
context.addIssue({
|
|
42718
|
+
code: external_exports.ZodIssueCode.custom,
|
|
42719
|
+
path: ["tiers"],
|
|
42720
|
+
message: "tier priorities must be unique and ascending"
|
|
42721
|
+
});
|
|
42722
|
+
}
|
|
42723
|
+
const principals = policy.tiers.flatMap((tier) => tier.principal_ids);
|
|
42724
|
+
if (new Set(principals).size !== principals.length) {
|
|
42725
|
+
context.addIssue({
|
|
42726
|
+
code: external_exports.ZodIssueCode.custom,
|
|
42727
|
+
path: ["tiers"],
|
|
42728
|
+
message: "a principal belongs to one tier only"
|
|
42729
|
+
});
|
|
42730
|
+
}
|
|
42731
|
+
}
|
|
42688
42732
|
});
|
|
42689
42733
|
var AuthorityRequirementOriginatorSchema = external_exports.object({
|
|
42690
42734
|
organization_id: external_exports.string().min(1).max(200),
|
|
@@ -42750,6 +42794,13 @@ var AuthorityRequirementSchema = external_exports.object({
|
|
|
42750
42794
|
message: "fallback roles must not repeat the primary role"
|
|
42751
42795
|
});
|
|
42752
42796
|
}
|
|
42797
|
+
if (requirement.resolution.tiers && requirement.selector.kind !== "ROLE") {
|
|
42798
|
+
context.addIssue({
|
|
42799
|
+
code: external_exports.ZodIssueCode.custom,
|
|
42800
|
+
path: ["resolution", "tiers"],
|
|
42801
|
+
message: "an approval chain names its members' trusted role through a ROLE selector"
|
|
42802
|
+
});
|
|
42803
|
+
}
|
|
42753
42804
|
if (requirement.orchestration?.mode === "MANAGED" && requirement.selector.kind === "PRINCIPAL" && requirement.selector.role_id === void 0) {
|
|
42754
42805
|
context.addIssue({
|
|
42755
42806
|
code: external_exports.ZodIssueCode.custom,
|
|
@@ -45891,17 +45942,21 @@ var connectors = [
|
|
|
45891
45942
|
// ── Enterprise ────────────────────────────────────────────────────────
|
|
45892
45943
|
{
|
|
45893
45944
|
// SAP PartnerEdge Solution Review approved 2026-06-22 (solution id
|
|
45894
|
-
// 2004368
|
|
45945
|
+
// 2004368; listing evidence now lives in decionis/Commerce
|
|
45946
|
+
// docs/marketplace/sap/solution-hub-listing.md). The PartnerEdge
|
|
45895
45947
|
// solution URL is partner-gated (anonymous fetch 404s — sweep
|
|
45896
|
-
// 2026-08-10), so it is deliberately NOT an install channel here
|
|
45897
|
-
// customer-deployable BTP
|
|
45898
|
-
//
|
|
45948
|
+
// 2026-08-10), so it is deliberately NOT an install channel here.
|
|
45949
|
+
// The CAP application and the customer-deployable BTP kit are
|
|
45950
|
+
// Commerce-owned (decionis/Commerce apps/sap + commerce-dashboard): the
|
|
45951
|
+
// decionis.com channel URLs below 301 to commerce.decionis.com like every
|
|
45952
|
+
// other Commerce-owned row, and this repo no longer ships the kit
|
|
45953
|
+
// artifacts or pins their version (drift-gated in Commerce, not here).
|
|
45954
|
+
// Dual-gate wording from the owning listing copy.
|
|
45899
45955
|
slug: "sap",
|
|
45900
45956
|
name: "Decionis Governed Execution Gate for SAP",
|
|
45901
45957
|
vendor: "SAP",
|
|
45902
45958
|
category: "enterprise",
|
|
45903
45959
|
status: "validated",
|
|
45904
|
-
version: "0.1.0",
|
|
45905
45960
|
summary: "Dual-gate governed execution for SAP S/4HANA, BTP, and CAP-side workflows \u2014 vendor payment release, procurement approval, and finance controls checked before they execute, with a signed Decision Dossier written back to the governed document.",
|
|
45906
45961
|
capabilities: [
|
|
45907
45962
|
"dual-gate-execution",
|
|
@@ -45918,20 +45973,14 @@ var connectors = [
|
|
|
45918
45973
|
installation: [
|
|
45919
45974
|
{
|
|
45920
45975
|
// Customer-deployed BTP kit (curated CAP source, mbt build →
|
|
45921
|
-
// cf deploy)
|
|
45922
|
-
//
|
|
45976
|
+
// cf deploy). The kit page, zip, checksum, manifest and SBOM are
|
|
45977
|
+
// served by Commerce; this URL resolves through the reviewed 301 in
|
|
45978
|
+
// CommerceOwnership.mjs (rule 1.1 by redirect, not by local file).
|
|
45923
45979
|
kind: "hosted_download",
|
|
45924
45980
|
url: `${SITE}/marketplace/sap/deployment-kit`,
|
|
45925
45981
|
label: "SAP BTP deployment kit (customer-deployed)"
|
|
45926
45982
|
}
|
|
45927
45983
|
],
|
|
45928
|
-
package: {
|
|
45929
|
-
artifact: "/marketplace/sap/deployment-kit/decionis-sap-deployment-kit-0.1.0.zip",
|
|
45930
|
-
sha256Path: "/marketplace/sap/deployment-kit/decionis-sap-deployment-kit-0.1.0.sha256.txt",
|
|
45931
|
-
manifestPath: "/marketplace/sap/deployment-kit/manifest.json",
|
|
45932
|
-
sbomPath: "/marketplace/sap/deployment-kit/SBOM.json",
|
|
45933
|
-
format: "sap-mta-deployment-kit"
|
|
45934
|
-
},
|
|
45935
45984
|
documentation: `${SITE}/marketplace/sap`,
|
|
45936
45985
|
verification: {
|
|
45937
45986
|
validatedBy: "SAP PartnerEdge Solution Review",
|
|
@@ -50322,7 +50371,8 @@ var AuthorityPolicyParser = class _AuthorityPolicyParser {
|
|
|
50322
50371
|
const verification = _AuthorityPolicyParser.parseVerification(record.verification_requirements);
|
|
50323
50372
|
const resolution = _AuthorityPolicyParser.parseResolution(record.resolution, selector);
|
|
50324
50373
|
const expiresInSeconds = asNumber(record.expires_in_seconds);
|
|
50325
|
-
|
|
50374
|
+
const maxExpiresInSeconds = resolution?.tiers === void 0 ? _AuthorityPolicyParser.MAX_CEREMONY_SECONDS : _AuthorityPolicyParser.MAX_CHAIN_SECONDS;
|
|
50375
|
+
if (!reasonCodes || !selector || !verification || !resolution || expiresInSeconds == null || !Number.isInteger(expiresInSeconds) || expiresInSeconds < 60 || expiresInSeconds > maxExpiresInSeconds) {
|
|
50326
50376
|
return null;
|
|
50327
50377
|
}
|
|
50328
50378
|
return {
|
|
@@ -50333,6 +50383,8 @@ var AuthorityPolicyParser = class _AuthorityPolicyParser {
|
|
|
50333
50383
|
expires_in_seconds: expiresInSeconds
|
|
50334
50384
|
};
|
|
50335
50385
|
}
|
|
50386
|
+
static MAX_CEREMONY_SECONDS = 3600;
|
|
50387
|
+
static MAX_CHAIN_SECONDS = 7 * 24 * 3600;
|
|
50336
50388
|
static policyKeys = /* @__PURE__ */ new Set([
|
|
50337
50389
|
"reason_codes",
|
|
50338
50390
|
"selector",
|
|
@@ -50414,7 +50466,7 @@ var AuthorityPolicyParser = class _AuthorityPolicyParser {
|
|
|
50414
50466
|
const record = asRecord3(input);
|
|
50415
50467
|
if (!_AuthorityPolicyParser.hasOnlyKeys(
|
|
50416
50468
|
record,
|
|
50417
|
-
/* @__PURE__ */ new Set(["quorum", "delegation", "fallback_role_ids"])
|
|
50469
|
+
/* @__PURE__ */ new Set(["quorum", "delegation", "fallback_role_ids", "tiers"])
|
|
50418
50470
|
) || record.quorum !== 1 || record.delegation !== "DISALLOWED" && record.delegation !== "REQUIREMENT_REFRESH" || !Array.isArray(record.fallback_role_ids) || record.fallback_role_ids.length > 10) {
|
|
50419
50471
|
return null;
|
|
50420
50472
|
}
|
|
@@ -50424,12 +50476,46 @@ var AuthorityPolicyParser = class _AuthorityPolicyParser {
|
|
|
50424
50476
|
if (fallbackRoles.length !== record.fallback_role_ids.length || new Set(fallbackRoles).size !== fallbackRoles.length || selector?.kind === "ROLE" && fallbackRoles.includes(selector.role_id)) {
|
|
50425
50477
|
return null;
|
|
50426
50478
|
}
|
|
50479
|
+
const tiers = _AuthorityPolicyParser.parseTiers(record.tiers);
|
|
50480
|
+
if (record.tiers !== void 0 && tiers === null) return null;
|
|
50481
|
+
if (tiers && selector?.kind !== "ROLE") return null;
|
|
50427
50482
|
return {
|
|
50428
50483
|
quorum: 1,
|
|
50429
50484
|
delegation: record.delegation,
|
|
50430
|
-
fallback_role_ids: fallbackRoles
|
|
50485
|
+
fallback_role_ids: fallbackRoles,
|
|
50486
|
+
...tiers ? { tiers } : {}
|
|
50431
50487
|
};
|
|
50432
50488
|
}
|
|
50489
|
+
/** Priority tiers of principals; unique ascending priorities, a principal in one tier only. */
|
|
50490
|
+
static parseTiers(input) {
|
|
50491
|
+
if (input === void 0) return null;
|
|
50492
|
+
if (!Array.isArray(input) || input.length < 1 || input.length > 5) return null;
|
|
50493
|
+
const tiers = [];
|
|
50494
|
+
const seen = /* @__PURE__ */ new Set();
|
|
50495
|
+
for (const value of input) {
|
|
50496
|
+
const tier = asRecord3(value);
|
|
50497
|
+
if (!_AuthorityPolicyParser.hasOnlyKeys(tier, /* @__PURE__ */ new Set(["priority", "principal_ids"]))) {
|
|
50498
|
+
return null;
|
|
50499
|
+
}
|
|
50500
|
+
const priority = asNumber(tier.priority);
|
|
50501
|
+
if (priority == null || !Number.isInteger(priority) || priority < 1 || priority > 5 || tiers.length > 0 && priority <= tiers[tiers.length - 1].priority) {
|
|
50502
|
+
return null;
|
|
50503
|
+
}
|
|
50504
|
+
if (!Array.isArray(tier.principal_ids) || tier.principal_ids.length < 1 || tier.principal_ids.length > 10) {
|
|
50505
|
+
return null;
|
|
50506
|
+
}
|
|
50507
|
+
const principalIds = tier.principal_ids.filter(
|
|
50508
|
+
(id) => typeof id === "string" && id.length >= 1 && id.length <= 200
|
|
50509
|
+
);
|
|
50510
|
+
if (principalIds.length !== tier.principal_ids.length) return null;
|
|
50511
|
+
for (const id of principalIds) {
|
|
50512
|
+
if (seen.has(id)) return null;
|
|
50513
|
+
seen.add(id);
|
|
50514
|
+
}
|
|
50515
|
+
tiers.push({ priority, principal_ids: principalIds });
|
|
50516
|
+
}
|
|
50517
|
+
return tiers;
|
|
50518
|
+
}
|
|
50433
50519
|
static parseRegions(input) {
|
|
50434
50520
|
if (input === void 0) return null;
|
|
50435
50521
|
if (!Array.isArray(input) || input.length < 1 || input.length > 100) return null;
|
|
@@ -52765,6 +52851,19 @@ var AgentTaskGatewayRoutes = class {
|
|
|
52765
52851
|
var PROTOCOL_SERVICE = "decionis-protocol";
|
|
52766
52852
|
var PROTOCOL_VERSION = "1.0.0";
|
|
52767
52853
|
|
|
52854
|
+
// ../protocol/src/discovery/GlamaClaimRoutes.ts
|
|
52855
|
+
var GlamaClaimRoutes = class {
|
|
52856
|
+
register(app) {
|
|
52857
|
+
app.get(
|
|
52858
|
+
"/.well-known/glama.json",
|
|
52859
|
+
async (_request, reply) => reply.header("cache-control", "public, max-age=300").send({
|
|
52860
|
+
$schema: "https://glama.ai/mcp/schemas/connector.json",
|
|
52861
|
+
claim: "glama_claim_BUHrLznF-9qs1cZEwwb2AN5CkXK7tNjS"
|
|
52862
|
+
})
|
|
52863
|
+
);
|
|
52864
|
+
}
|
|
52865
|
+
};
|
|
52866
|
+
|
|
52768
52867
|
// ../protocol/src/health/HealthRoutes.ts
|
|
52769
52868
|
function registerHealthRoutes(app, deps) {
|
|
52770
52869
|
const { store } = deps;
|
|
@@ -53684,6 +53783,27 @@ var policy_bundle_schema_default = {
|
|
|
53684
53783
|
maxItems: 10,
|
|
53685
53784
|
uniqueItems: true,
|
|
53686
53785
|
items: { type: "string", pattern: "^[A-Z][A-Z0-9_]{1,63}$" }
|
|
53786
|
+
},
|
|
53787
|
+
tiers: {
|
|
53788
|
+
type: "array",
|
|
53789
|
+
minItems: 1,
|
|
53790
|
+
maxItems: 5,
|
|
53791
|
+
description: "An approval chain: priority tiers of principals, asked at once; one valid proof from every tier satisfies the requirement. Requires a ROLE selector naming the members' trusted role.",
|
|
53792
|
+
items: {
|
|
53793
|
+
type: "object",
|
|
53794
|
+
additionalProperties: false,
|
|
53795
|
+
properties: {
|
|
53796
|
+
priority: { type: "integer", minimum: 1, maximum: 5 },
|
|
53797
|
+
principal_ids: {
|
|
53798
|
+
type: "array",
|
|
53799
|
+
minItems: 1,
|
|
53800
|
+
maxItems: 10,
|
|
53801
|
+
uniqueItems: true,
|
|
53802
|
+
items: { type: "string", minLength: 1, maxLength: 200 }
|
|
53803
|
+
}
|
|
53804
|
+
},
|
|
53805
|
+
required: ["priority", "principal_ids"]
|
|
53806
|
+
}
|
|
53687
53807
|
}
|
|
53688
53808
|
},
|
|
53689
53809
|
required: ["quorum", "delegation", "fallback_role_ids"]
|
|
@@ -53707,7 +53827,8 @@ var policy_bundle_schema_default = {
|
|
|
53707
53827
|
expires_in_seconds: {
|
|
53708
53828
|
type: "integer",
|
|
53709
53829
|
minimum: 60,
|
|
53710
|
-
maximum:
|
|
53830
|
+
maximum: 604800,
|
|
53831
|
+
description: "How long the requirement lives. At most 3600 for one ceremony; a requirement whose resolution names tiers is an approval chain and may run to a week."
|
|
53711
53832
|
}
|
|
53712
53833
|
},
|
|
53713
53834
|
required: [
|
|
@@ -54993,6 +55114,171 @@ var affiliateRewardsVerticalPack = {
|
|
|
54993
55114
|
}
|
|
54994
55115
|
};
|
|
54995
55116
|
|
|
55117
|
+
// ../protocol/src/verticals/commerce/CommercePack.ts
|
|
55118
|
+
var commerceVerticalPack = {
|
|
55119
|
+
key: "commerce",
|
|
55120
|
+
display_name: "Commerce Gate",
|
|
55121
|
+
description: "Governance for storefront and marketplace decisions \u2014 price and promotion changes, inventory mutations, order acceptance and release, and refunds \u2014 against the merchant's margin, inventory and refund floors.",
|
|
55122
|
+
workflow_keys: [
|
|
55123
|
+
"commerce",
|
|
55124
|
+
"commerce_order_release",
|
|
55125
|
+
"commerce_refund_approve",
|
|
55126
|
+
"commerce_refund_request",
|
|
55127
|
+
"commerce_price_change",
|
|
55128
|
+
"commerce_promotion_change",
|
|
55129
|
+
"commerce_inventory_mutation",
|
|
55130
|
+
"commerce_order_acceptance"
|
|
55131
|
+
],
|
|
55132
|
+
default_domain: "COMMERCE",
|
|
55133
|
+
signal_mappings: [
|
|
55134
|
+
{ domain: "COMMERCE", metric_name: "net_margin_percent", source_hint: "commerce_connector" },
|
|
55135
|
+
{ domain: "COMMERCE", metric_name: "available_inventory", source_hint: "commerce_connector" },
|
|
55136
|
+
{ domain: "COMMERCE", metric_name: "refund_amount", source_hint: "commerce_connector" }
|
|
55137
|
+
],
|
|
55138
|
+
policy_bundle: {
|
|
55139
|
+
version: "commerce-v1",
|
|
55140
|
+
rules: [
|
|
55141
|
+
{
|
|
55142
|
+
rule_id: "reject_refund_above_refundable",
|
|
55143
|
+
name: "Reject refunds above the refundable balance",
|
|
55144
|
+
decision_domain: "COMMERCE",
|
|
55145
|
+
when: {
|
|
55146
|
+
all: [{ field: "signals.refund_exceeds_refundable", operator: "EQ", value: true }]
|
|
55147
|
+
},
|
|
55148
|
+
then: { action: "AUTO_REJECT", severity: "urgent", sla_minutes: 60 },
|
|
55149
|
+
priority: 400,
|
|
55150
|
+
enabled: true,
|
|
55151
|
+
rationale: "A refund that exceeds what the order has left to refund is never sent."
|
|
55152
|
+
},
|
|
55153
|
+
{
|
|
55154
|
+
rule_id: "escalate_order_release",
|
|
55155
|
+
name: "A held order is released only by an approver",
|
|
55156
|
+
decision_domain: "COMMERCE",
|
|
55157
|
+
when: {
|
|
55158
|
+
all: [{ field: "workflow_key", operator: "EQ", value: "commerce_order_release" }]
|
|
55159
|
+
},
|
|
55160
|
+
then: { action: "ESCALATE", severity: "elevated", sla_minutes: 240 },
|
|
55161
|
+
priority: 360,
|
|
55162
|
+
enabled: true,
|
|
55163
|
+
rationale: "Releasing an order the gate held is its own decision and needs an approver to prove who made it."
|
|
55164
|
+
},
|
|
55165
|
+
{
|
|
55166
|
+
rule_id: "escalate_large_refund",
|
|
55167
|
+
name: "Escalate refunds above the unattended limit",
|
|
55168
|
+
decision_domain: "COMMERCE",
|
|
55169
|
+
when: { all: [{ field: "signals.refund_amount", operator: "GT", value: 1e3 }] },
|
|
55170
|
+
then: { action: "ESCALATE", severity: "elevated", sla_minutes: 240 },
|
|
55171
|
+
priority: 350,
|
|
55172
|
+
enabled: true,
|
|
55173
|
+
rationale: "A refund above the unattended limit needs a named approver before it is sent."
|
|
55174
|
+
},
|
|
55175
|
+
{
|
|
55176
|
+
rule_id: "review_repeat_refund",
|
|
55177
|
+
name: "Review a second refund on the same line",
|
|
55178
|
+
decision_domain: "COMMERCE",
|
|
55179
|
+
when: { all: [{ field: "signals.prior_refund_count", operator: "GT", value: 0 }] },
|
|
55180
|
+
then: { action: "REQUIRE_REVIEW", severity: "elevated", sla_minutes: 240 },
|
|
55181
|
+
priority: 340,
|
|
55182
|
+
enabled: true,
|
|
55183
|
+
rationale: "A refund on an order line that was already refunded is the double-refund case."
|
|
55184
|
+
},
|
|
55185
|
+
{
|
|
55186
|
+
rule_id: "review_margin_floor",
|
|
55187
|
+
name: "Protect minimum margin",
|
|
55188
|
+
decision_domain: "COMMERCE",
|
|
55189
|
+
when: { all: [{ field: "signals.net_margin_percent", operator: "LT", value: 12 }] },
|
|
55190
|
+
then: { action: "REQUIRE_REVIEW", severity: "elevated", sla_minutes: 240 },
|
|
55191
|
+
priority: 300,
|
|
55192
|
+
enabled: true,
|
|
55193
|
+
rationale: "Review commerce actions that would take net margin below the merchant floor."
|
|
55194
|
+
},
|
|
55195
|
+
{
|
|
55196
|
+
rule_id: "review_inventory_floor",
|
|
55197
|
+
name: "Protect low inventory",
|
|
55198
|
+
decision_domain: "COMMERCE",
|
|
55199
|
+
when: { all: [{ field: "signals.available_inventory", operator: "LT", value: 10 }] },
|
|
55200
|
+
then: { action: "REQUIRE_REVIEW", severity: "elevated", sla_minutes: 240 },
|
|
55201
|
+
priority: 250,
|
|
55202
|
+
enabled: true,
|
|
55203
|
+
rationale: "Review fulfilment when source-of-truth inventory is below the safety floor."
|
|
55204
|
+
},
|
|
55205
|
+
{
|
|
55206
|
+
rule_id: "review_discount_stacking",
|
|
55207
|
+
name: "Review stacked promotions",
|
|
55208
|
+
decision_domain: "COMMERCE",
|
|
55209
|
+
when: { all: [{ field: "signals.discount_count", operator: "GT", value: 1 }] },
|
|
55210
|
+
then: { action: "REQUIRE_REVIEW", severity: "elevated", sla_minutes: 240 },
|
|
55211
|
+
priority: 200,
|
|
55212
|
+
enabled: true,
|
|
55213
|
+
rationale: "Review carts that combine more discount sources than the merchant allows."
|
|
55214
|
+
},
|
|
55215
|
+
{
|
|
55216
|
+
rule_id: "approve_routine_commerce",
|
|
55217
|
+
name: "Approve routine commerce actions",
|
|
55218
|
+
decision_domain: "COMMERCE",
|
|
55219
|
+
when: { all: [{ field: "decision_type", operator: "EXISTS", value: true }] },
|
|
55220
|
+
then: { action: "AUTO_APPROVE", severity: "routine", sla_minutes: 30 },
|
|
55221
|
+
priority: 10,
|
|
55222
|
+
enabled: true,
|
|
55223
|
+
rationale: "A storefront action proceeds when no floor is breached and nothing is held."
|
|
55224
|
+
}
|
|
55225
|
+
]
|
|
55226
|
+
},
|
|
55227
|
+
resolver_overrides: {
|
|
55228
|
+
// Whatever engine scored it, a storefront decision is a commerce decision.
|
|
55229
|
+
domain_by_engine: {
|
|
55230
|
+
finance: "COMMERCE",
|
|
55231
|
+
software: "COMMERCE",
|
|
55232
|
+
procure: "COMMERCE",
|
|
55233
|
+
hiring: "COMMERCE"
|
|
55234
|
+
},
|
|
55235
|
+
intent_domain_hints: [
|
|
55236
|
+
{
|
|
55237
|
+
domain: "COMMERCE",
|
|
55238
|
+
keywords: [
|
|
55239
|
+
"commerce",
|
|
55240
|
+
"order",
|
|
55241
|
+
"refund",
|
|
55242
|
+
"price",
|
|
55243
|
+
"promotion",
|
|
55244
|
+
"discount",
|
|
55245
|
+
"inventory",
|
|
55246
|
+
"listing",
|
|
55247
|
+
"cart",
|
|
55248
|
+
"checkout",
|
|
55249
|
+
"merchant",
|
|
55250
|
+
"storefront",
|
|
55251
|
+
"marketplace"
|
|
55252
|
+
]
|
|
55253
|
+
}
|
|
55254
|
+
],
|
|
55255
|
+
evidence_required_keywords: ["refund", "release"],
|
|
55256
|
+
missing_evidence_fields: ["purchase_order_id"],
|
|
55257
|
+
base_confidence: 0.6,
|
|
55258
|
+
attachment_confidence_bonus: 0.08,
|
|
55259
|
+
intake_confidence_bonus: 0.02,
|
|
55260
|
+
missing_evidence_penalty: 0.2
|
|
55261
|
+
},
|
|
55262
|
+
execution_templates: {
|
|
55263
|
+
SUCCEEDED: [
|
|
55264
|
+
"Apply the storefront change",
|
|
55265
|
+
"Record the decision dossier",
|
|
55266
|
+
"Notify the merchant"
|
|
55267
|
+
],
|
|
55268
|
+
NEEDS_EVIDENCE: ["Attach cost or refund evidence", "Confirm the approver", "Re-run evaluation"],
|
|
55269
|
+
FAILED: [
|
|
55270
|
+
"Hold the order or change",
|
|
55271
|
+
"Escalate to the merchant's approver",
|
|
55272
|
+
"Capture the override reason"
|
|
55273
|
+
]
|
|
55274
|
+
},
|
|
55275
|
+
ui_copy: {
|
|
55276
|
+
recommendation_success: "Proceed with the {domain} action; the merchant's floors hold.",
|
|
55277
|
+
recommendation_needs_evidence: "Attach the cost or refund evidence {domain} needs before approval.",
|
|
55278
|
+
recommendation_failed: "Hold the {domain} action for the merchant's approver."
|
|
55279
|
+
}
|
|
55280
|
+
};
|
|
55281
|
+
|
|
54996
55282
|
// ../protocol/src/verticals/core/CorePack.ts
|
|
54997
55283
|
var coreVerticalPack = {
|
|
54998
55284
|
key: "core",
|
|
@@ -57790,6 +58076,7 @@ var DEFAULT_VERTICAL_PACK_KEY = "core";
|
|
|
57790
58076
|
var packRegistry = new Map([
|
|
57791
58077
|
[coreVerticalPack.key, coreVerticalPack],
|
|
57792
58078
|
[affiliateRewardsVerticalPack.key, affiliateRewardsVerticalPack],
|
|
58079
|
+
[commerceVerticalPack.key, commerceVerticalPack],
|
|
57793
58080
|
[devopsVerticalPack.key, devopsVerticalPack],
|
|
57794
58081
|
[financeVerticalPack.key, financeVerticalPack],
|
|
57795
58082
|
[hospitalityVerticalPack.key, hospitalityVerticalPack],
|
|
@@ -60962,6 +61249,7 @@ function appendEvaluateDecisionLedgerEvent(store, input) {
|
|
|
60962
61249
|
// ../protocol/src/authority/AuthorityRequirementIssuer.ts
|
|
60963
61250
|
import { randomBytes, randomUUID as randomUUID9 } from "crypto";
|
|
60964
61251
|
var AuthorityRequirementIssuer = class _AuthorityRequirementIssuer {
|
|
61252
|
+
static MANAGED_CEREMONY_LIFETIME_MS = 5 * 6e4;
|
|
60965
61253
|
requirementId;
|
|
60966
61254
|
nonce;
|
|
60967
61255
|
constructor(dependencies = {}) {
|
|
@@ -60993,10 +61281,12 @@ var AuthorityRequirementIssuer = class _AuthorityRequirementIssuer {
|
|
|
60993
61281
|
const intentExpiresAtMs = Date.parse(
|
|
60994
61282
|
typeof agentSafe.expires_at === "string" ? agentSafe.expires_at : ""
|
|
60995
61283
|
);
|
|
61284
|
+
const chained = authorityPolicy.resolution.tiers !== void 0;
|
|
60996
61285
|
const expiresAt = new Date(
|
|
60997
61286
|
Math.min(
|
|
60998
61287
|
issuedAtMs + authorityPolicy.expires_in_seconds * 1e3,
|
|
60999
|
-
Number.isFinite(intentExpiresAtMs) ? intentExpiresAtMs : Number.POSITIVE_INFINITY
|
|
61288
|
+
Number.isFinite(intentExpiresAtMs) ? intentExpiresAtMs : Number.POSITIVE_INFINITY,
|
|
61289
|
+
managedEscalationId && !chained ? issuedAtMs + _AuthorityRequirementIssuer.MANAGED_CEREMONY_LIFETIME_MS : Number.POSITIVE_INFINITY
|
|
61000
61290
|
)
|
|
61001
61291
|
).toISOString();
|
|
61002
61292
|
return AuthorityRequirementSchema.parse({
|
|
@@ -61020,7 +61310,13 @@ var AuthorityRequirementIssuer = class _AuthorityRequirementIssuer {
|
|
|
61020
61310
|
},
|
|
61021
61311
|
resolution: {
|
|
61022
61312
|
...authorityPolicy.resolution,
|
|
61023
|
-
fallback_role_ids: [...authorityPolicy.resolution.fallback_role_ids]
|
|
61313
|
+
fallback_role_ids: [...authorityPolicy.resolution.fallback_role_ids],
|
|
61314
|
+
...authorityPolicy.resolution.tiers ? {
|
|
61315
|
+
tiers: authorityPolicy.resolution.tiers.map((tier) => ({
|
|
61316
|
+
priority: tier.priority,
|
|
61317
|
+
principal_ids: [...tier.principal_ids]
|
|
61318
|
+
}))
|
|
61319
|
+
} : {}
|
|
61024
61320
|
},
|
|
61025
61321
|
originator: {
|
|
61026
61322
|
organization_id: input.request.org_id,
|
|
@@ -62973,161 +63269,6 @@ function resolveSalesforceMode(payload) {
|
|
|
62973
63269
|
return SalesforceSurface.resolveMode(payload);
|
|
62974
63270
|
}
|
|
62975
63271
|
|
|
62976
|
-
// ../protocol/src/verticals/salesforce/SapCostBasis.ts
|
|
62977
|
-
var FETCH_TIMEOUT_MS = 2500;
|
|
62978
|
-
var DEFAULTS = {
|
|
62979
|
-
servicePath: "/sap/opu/odata/sap/API_PRODUCT_SRV",
|
|
62980
|
-
entitySet: "A_ProductValuationArea",
|
|
62981
|
-
skuProperty: "Product",
|
|
62982
|
-
costProperty: "StandardPrice"
|
|
62983
|
-
};
|
|
62984
|
-
var SapCostBasis = class _SapCostBasis {
|
|
62985
|
-
/**
|
|
62986
|
-
* Resolve the S/4HANA OData cost destination. With `orgId`, a per-org override in
|
|
62987
|
-
* `DECIONIS_SAP_SOR_BY_ORG` wins (multi-tenant); otherwise the global env destination
|
|
62988
|
-
* is used. Returns null when neither is configured.
|
|
62989
|
-
*/
|
|
62990
|
-
static resolveConfig(env = process.env, orgId) {
|
|
62991
|
-
const o = _SapCostBasis.readPerOrgCostOverride(env, orgId);
|
|
62992
|
-
const baseUrl = String(o?.url ?? env.DECIONIS_SAP_SOR_URL ?? "").trim();
|
|
62993
|
-
if (!baseUrl) return null;
|
|
62994
|
-
return {
|
|
62995
|
-
baseUrl: baseUrl.replace(/\/$/, ""),
|
|
62996
|
-
token: String(o?.token ?? env.DECIONIS_SAP_SOR_TOKEN ?? "").trim() || null,
|
|
62997
|
-
servicePath: String(
|
|
62998
|
-
o?.servicePath ?? env.DECIONIS_SAP_SOR_SERVICE_PATH ?? DEFAULTS.servicePath
|
|
62999
|
-
).replace(/\/$/, ""),
|
|
63000
|
-
entitySet: String(o?.entitySet ?? env.DECIONIS_SAP_SOR_ENTITY ?? DEFAULTS.entitySet),
|
|
63001
|
-
skuProperty: String(
|
|
63002
|
-
o?.skuProperty ?? env.DECIONIS_SAP_SOR_SKU_PROPERTY ?? DEFAULTS.skuProperty
|
|
63003
|
-
),
|
|
63004
|
-
costProperty: String(
|
|
63005
|
-
o?.costProperty ?? env.DECIONIS_SAP_SOR_COST_PROPERTY ?? DEFAULTS.costProperty
|
|
63006
|
-
)
|
|
63007
|
-
};
|
|
63008
|
-
}
|
|
63009
|
-
/** The destination is operator-configured, but require TLS and reject internal hosts. */
|
|
63010
|
-
static isSafeUrl(rawUrl) {
|
|
63011
|
-
let url;
|
|
63012
|
-
try {
|
|
63013
|
-
url = new URL(rawUrl);
|
|
63014
|
-
} catch {
|
|
63015
|
-
return false;
|
|
63016
|
-
}
|
|
63017
|
-
if (url.protocol !== "https:") return false;
|
|
63018
|
-
const h = url.hostname.toLowerCase().replace(/^\[|\]$/g, "");
|
|
63019
|
-
if (h === "localhost" || h === "127.0.0.1" || h === "::1" || h === "169.254.169.254" || // cloud metadata
|
|
63020
|
-
h.endsWith(".local") || h.endsWith(".internal") || h.startsWith("10.") || h.startsWith("192.168.") || /^172\.(1[6-9]|2\d|3[01])\./.test(h)) {
|
|
63021
|
-
return false;
|
|
63022
|
-
}
|
|
63023
|
-
return true;
|
|
63024
|
-
}
|
|
63025
|
-
static buildCostQueryUrl(config, skus) {
|
|
63026
|
-
const filter = skus.map((sku) => `${config.skuProperty} eq ${_SapCostBasis.odataString(sku)}`).join(" or ");
|
|
63027
|
-
const params = new URLSearchParams({
|
|
63028
|
-
$select: `${config.skuProperty},${config.costProperty}`,
|
|
63029
|
-
$filter: filter,
|
|
63030
|
-
$format: "json"
|
|
63031
|
-
});
|
|
63032
|
-
return `${config.baseUrl}${config.servicePath}/${config.entitySet}?${params.toString()}`;
|
|
63033
|
-
}
|
|
63034
|
-
/**
|
|
63035
|
-
* Returns SKU → SAP cost (or null when SAP can't confirm it). Every requested SKU
|
|
63036
|
-
* is present in the map. Fail-safe: returns all-null on SSRF rejection, missing
|
|
63037
|
-
* transport, non-2xx, or error.
|
|
63038
|
-
*/
|
|
63039
|
-
static async fetchCostBasis(config, skus, options = {}) {
|
|
63040
|
-
const result = /* @__PURE__ */ new Map();
|
|
63041
|
-
const unique = [...new Set(skus.filter(Boolean))];
|
|
63042
|
-
for (const sku of unique) result.set(sku, null);
|
|
63043
|
-
if (unique.length === 0) return result;
|
|
63044
|
-
if (!_SapCostBasis.isSafeUrl(config.baseUrl)) return result;
|
|
63045
|
-
const transport = options.transport ?? globalThis.fetch;
|
|
63046
|
-
if (!transport) return result;
|
|
63047
|
-
const controller = new AbortController();
|
|
63048
|
-
const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
|
|
63049
|
-
try {
|
|
63050
|
-
const res = await transport(_SapCostBasis.buildCostQueryUrl(config, unique), {
|
|
63051
|
-
method: "GET",
|
|
63052
|
-
headers: {
|
|
63053
|
-
accept: "application/json",
|
|
63054
|
-
...config.token ? { authorization: `Bearer ${config.token}` } : {}
|
|
63055
|
-
},
|
|
63056
|
-
signal: controller.signal
|
|
63057
|
-
});
|
|
63058
|
-
if (!res.ok) return result;
|
|
63059
|
-
const rows = _SapCostBasis.extractRows(await res.json());
|
|
63060
|
-
for (const row of rows) {
|
|
63061
|
-
const sku = row[config.skuProperty];
|
|
63062
|
-
if (typeof sku !== "string" || !result.has(sku)) continue;
|
|
63063
|
-
const cost = Number(row[config.costProperty]);
|
|
63064
|
-
result.set(sku, Number.isFinite(cost) ? cost : null);
|
|
63065
|
-
}
|
|
63066
|
-
} catch {
|
|
63067
|
-
} finally {
|
|
63068
|
-
clearTimeout(timer);
|
|
63069
|
-
}
|
|
63070
|
-
return result;
|
|
63071
|
-
}
|
|
63072
|
-
/**
|
|
63073
|
-
* Override each order line's `cost_basis` with the SAP cost when available; lines
|
|
63074
|
-
* SAP can't confirm keep their existing (payload) cost. Pure.
|
|
63075
|
-
*/
|
|
63076
|
-
static applyCostBasis(payload, costMap) {
|
|
63077
|
-
const items = Array.isArray(payload.order_items) ? payload.order_items : [];
|
|
63078
|
-
return {
|
|
63079
|
-
...payload,
|
|
63080
|
-
order_items: items.map((it) => {
|
|
63081
|
-
const matnr = String(it.matnr ?? "");
|
|
63082
|
-
const sapCost = matnr ? costMap.get(matnr) : null;
|
|
63083
|
-
return sapCost != null ? { ...it, cost_basis: sapCost } : it;
|
|
63084
|
-
})
|
|
63085
|
-
};
|
|
63086
|
-
}
|
|
63087
|
-
/** True when at least one SKU got an authoritative SAP cost. */
|
|
63088
|
-
static hasResolvedCost(costMap) {
|
|
63089
|
-
for (const value of costMap.values()) if (value != null) return true;
|
|
63090
|
-
return false;
|
|
63091
|
-
}
|
|
63092
|
-
/** Per-org SAP destination override from `DECIONIS_SAP_SOR_BY_ORG` (JSON keyed by org id). */
|
|
63093
|
-
static readPerOrgCostOverride(env, orgId) {
|
|
63094
|
-
if (!orgId) return null;
|
|
63095
|
-
const raw = env.DECIONIS_SAP_SOR_BY_ORG;
|
|
63096
|
-
if (!raw) return null;
|
|
63097
|
-
try {
|
|
63098
|
-
const map = JSON.parse(raw);
|
|
63099
|
-
const entry = map && typeof map === "object" ? map[orgId] : null;
|
|
63100
|
-
return entry && typeof entry === "object" ? entry : null;
|
|
63101
|
-
} catch {
|
|
63102
|
-
return null;
|
|
63103
|
-
}
|
|
63104
|
-
}
|
|
63105
|
-
static odataString(value) {
|
|
63106
|
-
return `'${value.replace(/'/g, "''")}'`;
|
|
63107
|
-
}
|
|
63108
|
-
/** OData v2 (`d.results`) and v4 (`value`) both supported. */
|
|
63109
|
-
static extractRows(json) {
|
|
63110
|
-
if (!json || typeof json !== "object") return [];
|
|
63111
|
-
const v2 = json.d?.results;
|
|
63112
|
-
if (Array.isArray(v2)) return v2;
|
|
63113
|
-
const v4 = json.value;
|
|
63114
|
-
if (Array.isArray(v4)) return v4;
|
|
63115
|
-
return [];
|
|
63116
|
-
}
|
|
63117
|
-
};
|
|
63118
|
-
function resolveSapCostConfig(env = process.env, orgId) {
|
|
63119
|
-
return SapCostBasis.resolveConfig(env, orgId);
|
|
63120
|
-
}
|
|
63121
|
-
async function fetchSapCostBasis(config, skus, options = {}) {
|
|
63122
|
-
return SapCostBasis.fetchCostBasis(config, skus, options);
|
|
63123
|
-
}
|
|
63124
|
-
function applySapCostBasis(payload, costMap) {
|
|
63125
|
-
return SapCostBasis.applyCostBasis(payload, costMap);
|
|
63126
|
-
}
|
|
63127
|
-
function hasResolvedCost(costMap) {
|
|
63128
|
-
return SapCostBasis.hasResolvedCost(costMap);
|
|
63129
|
-
}
|
|
63130
|
-
|
|
63131
63272
|
// ../protocol/src/surface-verify/SalesforceVerifyRoutes.ts
|
|
63132
63273
|
function registerSalesforceVerifyRoutes(app, deps) {
|
|
63133
63274
|
const { store } = deps;
|
|
@@ -63170,26 +63311,10 @@ function registerSalesforceVerifyRoutes(app, deps) {
|
|
|
63170
63311
|
const candidateOrg = authedOrgId || asString2(ctx.org_id)?.trim() || process.env.DECIONIS_SALESFORCE_ORG_ID?.trim() || SAP_DEFAULT_ORG_ID;
|
|
63171
63312
|
const orgId = isLikelyUuid(candidateOrg) ? candidateOrg : SAP_DEFAULT_ORG_ID;
|
|
63172
63313
|
await ensureSalesforcePolicyBundle(orgId);
|
|
63173
|
-
let evalPayload = payload;
|
|
63174
|
-
let costBasisSource = "payload";
|
|
63175
|
-
if (gate === "execution_authority") {
|
|
63176
|
-
const costConfig = resolveSapCostConfig(process.env, orgId);
|
|
63177
|
-
if (costConfig) {
|
|
63178
|
-
try {
|
|
63179
|
-
const skus = (payload.order_items ?? []).map((it) => String(it.matnr ?? "").trim()).filter(Boolean);
|
|
63180
|
-
const costMap = await fetchSapCostBasis(costConfig, skus);
|
|
63181
|
-
if (hasResolvedCost(costMap)) {
|
|
63182
|
-
evalPayload = applySapCostBasis(payload, costMap);
|
|
63183
|
-
costBasisSource = "sap";
|
|
63184
|
-
}
|
|
63185
|
-
} catch {
|
|
63186
|
-
}
|
|
63187
|
-
}
|
|
63188
|
-
}
|
|
63189
63314
|
const evalRes = await injectInternalProtocolRoute(app, {
|
|
63190
63315
|
method: "POST",
|
|
63191
63316
|
url: "/v1/protocol/evaluate-decision",
|
|
63192
|
-
payload: buildSalesforceEvaluateRequest(
|
|
63317
|
+
payload: buildSalesforceEvaluateRequest(payload, gate, orgId)
|
|
63193
63318
|
});
|
|
63194
63319
|
if (evalRes.statusCode !== 200) {
|
|
63195
63320
|
return reply.code(502).send({
|
|
@@ -63230,11 +63355,19 @@ function registerSalesforceVerifyRoutes(app, deps) {
|
|
|
63230
63355
|
ledger_entry_hash: response.ledger_entry_hash ?? null,
|
|
63231
63356
|
decision_chain: response.decision_chain ?? null,
|
|
63232
63357
|
idempotent_replay: Boolean(response.idempotent_replay),
|
|
63233
|
-
cost_basis_source:
|
|
63358
|
+
cost_basis_source: "payload",
|
|
63234
63359
|
federated: true,
|
|
63235
63360
|
pipeline: true
|
|
63236
63361
|
});
|
|
63237
63362
|
};
|
|
63363
|
+
app.post(
|
|
63364
|
+
"/v1/protocol/surfaces/salesforce/state-admission/verify",
|
|
63365
|
+
(req, reply) => handleSalesforceGate("state_admission", req, reply)
|
|
63366
|
+
);
|
|
63367
|
+
app.post(
|
|
63368
|
+
"/v1/protocol/surfaces/salesforce/execution-authority/verify",
|
|
63369
|
+
(req, reply) => handleSalesforceGate("execution_authority", req, reply)
|
|
63370
|
+
);
|
|
63238
63371
|
app.post(
|
|
63239
63372
|
"/salesforce/state-admission/verify",
|
|
63240
63373
|
(req, reply) => handleSalesforceGate("state_admission", req, reply)
|
|
@@ -68926,6 +69059,7 @@ function buildProtocolApp(options) {
|
|
|
68926
69059
|
const protocolAuthLookup = options?.mcpAuthLookup ?? null;
|
|
68927
69060
|
registerInternalAccessGuard(app, process.env, protocolAuthLookup);
|
|
68928
69061
|
registerHealthRoutes(app, { store });
|
|
69062
|
+
new GlamaClaimRoutes().register(app);
|
|
68929
69063
|
registerFinanceOverrideRoutes(app, { store });
|
|
68930
69064
|
registerEvaluateDecisionRoutes(app, { store });
|
|
68931
69065
|
registerWebexRoutes(app, { store });
|