@decionis/mcp 0.2.0 → 0.4.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/.claude-plugin/plugin.json +1 -1
- package/README.md +30 -2
- package/dist/AgentHookCli.js +2 -2
- package/dist/ManagedAgentHookCli.js +1949 -1105
- package/dist/agent/AgentIndex.js +2 -2
- package/dist/{chunk-NF5JL6QR.js → chunk-5Q6BCK32.js} +1309 -465
- package/dist/chunk-5Q6BCK32.js.map +1 -0
- package/dist/{chunk-7QNV7MXC.js → chunk-GCE6PUYD.js} +2 -2
- package/dist/index.js +370 -51
- package/dist/index.js.map +1 -1
- package/package.json +22 -22
- package/dist/chunk-NF5JL6QR.js.map +0 -1
- /package/dist/{chunk-7QNV7MXC.js.map → chunk-GCE6PUYD.js.map} +0 -0
|
@@ -29,9 +29,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
29
29
|
mod
|
|
30
30
|
));
|
|
31
31
|
|
|
32
|
-
//
|
|
32
|
+
// ../../../Decionis/node_modules/.pnpm/fastify-plugin@6.0.0/node_modules/fastify-plugin/lib/getPluginName.js
|
|
33
33
|
var require_getPluginName = __commonJS({
|
|
34
|
-
"
|
|
34
|
+
"../../../Decionis/node_modules/.pnpm/fastify-plugin@6.0.0/node_modules/fastify-plugin/lib/getPluginName.js"(exports, module) {
|
|
35
35
|
"use strict";
|
|
36
36
|
var fpStackTracePattern = /at\s(?:.*\.)?plugin\s.*\n\s*(.*)/;
|
|
37
37
|
var fileNamePattern = /(\w*(\.\w*)*)\..*/;
|
|
@@ -54,9 +54,9 @@ var require_getPluginName = __commonJS({
|
|
|
54
54
|
}
|
|
55
55
|
});
|
|
56
56
|
|
|
57
|
-
//
|
|
57
|
+
// ../../../Decionis/node_modules/.pnpm/fastify-plugin@6.0.0/node_modules/fastify-plugin/lib/toCamelCase.js
|
|
58
58
|
var require_toCamelCase = __commonJS({
|
|
59
|
-
"
|
|
59
|
+
"../../../Decionis/node_modules/.pnpm/fastify-plugin@6.0.0/node_modules/fastify-plugin/lib/toCamelCase.js"(exports, module) {
|
|
60
60
|
"use strict";
|
|
61
61
|
module.exports = function toCamelCase(name) {
|
|
62
62
|
if (name[0] === "@") {
|
|
@@ -69,9 +69,9 @@ var require_toCamelCase = __commonJS({
|
|
|
69
69
|
}
|
|
70
70
|
});
|
|
71
71
|
|
|
72
|
-
//
|
|
72
|
+
// ../../../Decionis/node_modules/.pnpm/fastify-plugin@6.0.0/node_modules/fastify-plugin/index.js
|
|
73
73
|
var require_fastify_plugin = __commonJS({
|
|
74
|
-
"
|
|
74
|
+
"../../../Decionis/node_modules/.pnpm/fastify-plugin@6.0.0/node_modules/fastify-plugin/index.js"(exports, module) {
|
|
75
75
|
"use strict";
|
|
76
76
|
var getPluginName = require_getPluginName();
|
|
77
77
|
var toCamelCase = require_toCamelCase();
|
|
@@ -119,9 +119,9 @@ var require_fastify_plugin = __commonJS({
|
|
|
119
119
|
}
|
|
120
120
|
});
|
|
121
121
|
|
|
122
|
-
//
|
|
122
|
+
// ../../../Decionis/node_modules/.pnpm/toad-cache@3.7.0/node_modules/toad-cache/dist/toad-cache.cjs
|
|
123
123
|
var require_toad_cache = __commonJS({
|
|
124
|
-
"
|
|
124
|
+
"../../../Decionis/node_modules/.pnpm/toad-cache@3.7.0/node_modules/toad-cache/dist/toad-cache.cjs"(exports) {
|
|
125
125
|
"use strict";
|
|
126
126
|
var FifoMap = class {
|
|
127
127
|
constructor(max = 1e3, ttlInMsecs = 0) {
|
|
@@ -802,9 +802,9 @@ var require_toad_cache = __commonJS({
|
|
|
802
802
|
}
|
|
803
803
|
});
|
|
804
804
|
|
|
805
|
-
//
|
|
805
|
+
// ../../../Decionis/node_modules/.pnpm/@fastify+cors@11.3.0/node_modules/@fastify/cors/vary.js
|
|
806
806
|
var require_vary = __commonJS({
|
|
807
|
-
"
|
|
807
|
+
"../../../Decionis/node_modules/.pnpm/@fastify+cors@11.3.0/node_modules/@fastify/cors/vary.js"(exports, module) {
|
|
808
808
|
"use strict";
|
|
809
809
|
var { FifoMap: FifoCache } = require_toad_cache();
|
|
810
810
|
var validFieldnameRE = /^[!#$%&'*+\-.^\w`|~]+$/u;
|
|
@@ -883,9 +883,9 @@ var require_vary = __commonJS({
|
|
|
883
883
|
}
|
|
884
884
|
});
|
|
885
885
|
|
|
886
|
-
//
|
|
886
|
+
// ../../../Decionis/node_modules/.pnpm/@fastify+cors@11.3.0/node_modules/@fastify/cors/index.js
|
|
887
887
|
var require_cors = __commonJS({
|
|
888
|
-
"
|
|
888
|
+
"../../../Decionis/node_modules/.pnpm/@fastify+cors@11.3.0/node_modules/@fastify/cors/index.js"(exports, module) {
|
|
889
889
|
"use strict";
|
|
890
890
|
var fp = require_fastify_plugin();
|
|
891
891
|
var {
|
|
@@ -1129,14 +1129,14 @@ var require_cors = __commonJS({
|
|
|
1129
1129
|
}
|
|
1130
1130
|
});
|
|
1131
1131
|
|
|
1132
|
-
//
|
|
1132
|
+
// ../../../Decionis/apps/protocol/src/app.ts
|
|
1133
1133
|
var import_cors = __toESM(require_cors(), 1);
|
|
1134
1134
|
import Fastify from "fastify";
|
|
1135
1135
|
|
|
1136
|
-
//
|
|
1136
|
+
// ../../../Decionis/apps/protocol/src/store/MemoryProtocolStore.ts
|
|
1137
1137
|
import { randomUUID } from "crypto";
|
|
1138
1138
|
|
|
1139
|
-
//
|
|
1139
|
+
// ../../../Decionis/packages/shared/src/Domain/DomainEnums.ts
|
|
1140
1140
|
var Band = {
|
|
1141
1141
|
NONE: "NONE",
|
|
1142
1142
|
LOW: "LOW",
|
|
@@ -1225,7 +1225,7 @@ var TopFrictionArea = {
|
|
|
1225
1225
|
ORIGIN_TRACKING: "ORIGIN_TRACKING"
|
|
1226
1226
|
};
|
|
1227
1227
|
|
|
1228
|
-
//
|
|
1228
|
+
// ../../../Decionis/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/external.js
|
|
1229
1229
|
var external_exports = {};
|
|
1230
1230
|
__export(external_exports, {
|
|
1231
1231
|
BRAND: () => BRAND,
|
|
@@ -1337,7 +1337,7 @@ __export(external_exports, {
|
|
|
1337
1337
|
void: () => voidType
|
|
1338
1338
|
});
|
|
1339
1339
|
|
|
1340
|
-
//
|
|
1340
|
+
// ../../../Decionis/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/util.js
|
|
1341
1341
|
var util;
|
|
1342
1342
|
(function(util2) {
|
|
1343
1343
|
util2.assertEqual = (_) => {
|
|
@@ -1471,7 +1471,7 @@ var getParsedType = (data) => {
|
|
|
1471
1471
|
}
|
|
1472
1472
|
};
|
|
1473
1473
|
|
|
1474
|
-
//
|
|
1474
|
+
// ../../../Decionis/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/ZodError.js
|
|
1475
1475
|
var ZodIssueCode = util.arrayToEnum([
|
|
1476
1476
|
"invalid_type",
|
|
1477
1477
|
"invalid_literal",
|
|
@@ -1589,7 +1589,7 @@ ZodError.create = (issues) => {
|
|
|
1589
1589
|
return error;
|
|
1590
1590
|
};
|
|
1591
1591
|
|
|
1592
|
-
//
|
|
1592
|
+
// ../../../Decionis/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/locales/en.js
|
|
1593
1593
|
var errorMap = (issue, _ctx) => {
|
|
1594
1594
|
let message;
|
|
1595
1595
|
switch (issue.code) {
|
|
@@ -1692,7 +1692,7 @@ var errorMap = (issue, _ctx) => {
|
|
|
1692
1692
|
};
|
|
1693
1693
|
var en_default = errorMap;
|
|
1694
1694
|
|
|
1695
|
-
//
|
|
1695
|
+
// ../../../Decionis/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/errors.js
|
|
1696
1696
|
var overrideErrorMap = en_default;
|
|
1697
1697
|
function setErrorMap(map) {
|
|
1698
1698
|
overrideErrorMap = map;
|
|
@@ -1701,7 +1701,7 @@ function getErrorMap() {
|
|
|
1701
1701
|
return overrideErrorMap;
|
|
1702
1702
|
}
|
|
1703
1703
|
|
|
1704
|
-
//
|
|
1704
|
+
// ../../../Decionis/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js
|
|
1705
1705
|
var makeIssue = (params) => {
|
|
1706
1706
|
const { data, path, errorMaps, issueData } = params;
|
|
1707
1707
|
const fullPath = [...path, ...issueData.path || []];
|
|
@@ -1811,14 +1811,14 @@ var isDirty = (x) => x.status === "dirty";
|
|
|
1811
1811
|
var isValid = (x) => x.status === "valid";
|
|
1812
1812
|
var isAsync = (x) => typeof Promise !== "undefined" && x instanceof Promise;
|
|
1813
1813
|
|
|
1814
|
-
//
|
|
1814
|
+
// ../../../Decionis/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.js
|
|
1815
1815
|
var errorUtil;
|
|
1816
1816
|
(function(errorUtil2) {
|
|
1817
1817
|
errorUtil2.errToObj = (message) => typeof message === "string" ? { message } : message || {};
|
|
1818
1818
|
errorUtil2.toString = (message) => typeof message === "string" ? message : message?.message;
|
|
1819
1819
|
})(errorUtil || (errorUtil = {}));
|
|
1820
1820
|
|
|
1821
|
-
//
|
|
1821
|
+
// ../../../Decionis/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js
|
|
1822
1822
|
var ParseInputLazyPath = class {
|
|
1823
1823
|
constructor(parent, value, path, key) {
|
|
1824
1824
|
this._cachedPath = [];
|
|
@@ -5266,7 +5266,7 @@ var coerce = {
|
|
|
5266
5266
|
};
|
|
5267
5267
|
var NEVER = INVALID;
|
|
5268
5268
|
|
|
5269
|
-
//
|
|
5269
|
+
// ../../../Decionis/packages/shared/src/Domain/DomainSchemas.ts
|
|
5270
5270
|
var SignalExtractionSchema = external_exports.object({
|
|
5271
5271
|
team_size: external_exports.enum(["SOLO", "SMALL", "MID", "LARGE"]),
|
|
5272
5272
|
revenue: external_exports.enum(["PRE_REVENUE", "UNPREDICTABLE", "PREDICTABLE", "PROFITABLE"]),
|
|
@@ -5350,7 +5350,7 @@ var SignalSetDbShape = external_exports.object({
|
|
|
5350
5350
|
cognitive_load: external_exports.nativeEnum(Band)
|
|
5351
5351
|
}).strict();
|
|
5352
5352
|
|
|
5353
|
-
//
|
|
5353
|
+
// ../../../Decionis/packages/shared/src/Decisioning/AiIntentContracts.ts
|
|
5354
5354
|
var AIIntentSurfaceSchema = external_exports.enum([
|
|
5355
5355
|
"webex",
|
|
5356
5356
|
"power_automate",
|
|
@@ -5451,7 +5451,7 @@ var AIIntentInterceptionResultContractSchema = external_exports.object({
|
|
|
5451
5451
|
handoff: AIIntentHandoffContractSchema
|
|
5452
5452
|
}).strict();
|
|
5453
5453
|
|
|
5454
|
-
//
|
|
5454
|
+
// ../../../Decionis/packages/shared/src/Decisioning/ExecutionBinding.ts
|
|
5455
5455
|
var EXECUTION_BINDING_SCHEMA_VERSION = "1.0";
|
|
5456
5456
|
var EXECUTION_BINDING_DIGEST_ALGORITHM = "SHA-256";
|
|
5457
5457
|
var JCS_CANONICALIZATION_PROFILE = "RFC8785/JCS";
|
|
@@ -5787,7 +5787,7 @@ function assertUnicodeScalarString(value) {
|
|
|
5787
5787
|
}
|
|
5788
5788
|
}
|
|
5789
5789
|
|
|
5790
|
-
//
|
|
5790
|
+
// ../../../Decionis/packages/shared/src/Decisioning/DecisionDossierIntegrity.ts
|
|
5791
5791
|
var DOSSIER_CONTENT_DIGEST_PROFILE = "DECIONIS_DOSSIER_CONTENT_V2";
|
|
5792
5792
|
var DOSSIER_CONTENT_DIGEST_CANONICALIZATION = "RFC8785/JCS";
|
|
5793
5793
|
var DECISION_DOSSIER_PROOF_ARTIFACT_SHAPES = {
|
|
@@ -5960,7 +5960,7 @@ function computeDecisionDossierContentSha256(dossierPayload) {
|
|
|
5960
5960
|
return DecisionDossierIntegrity.computeContentSha256(dossierPayload);
|
|
5961
5961
|
}
|
|
5962
5962
|
|
|
5963
|
-
//
|
|
5963
|
+
// ../../../Decionis/packages/shared/src/Decisioning/DecisioningContracts.ts
|
|
5964
5964
|
var EvidenceRefSchema = external_exports.object({
|
|
5965
5965
|
tool_event_id: external_exports.string().min(1).max(200),
|
|
5966
5966
|
output_hash: external_exports.string().min(16).max(128),
|
|
@@ -6042,7 +6042,7 @@ var EvidenceBackedClaimSchema = external_exports.object({
|
|
|
6042
6042
|
evidence: external_exports.array(EvidenceRefSchema).min(1)
|
|
6043
6043
|
}).strict();
|
|
6044
6044
|
|
|
6045
|
-
//
|
|
6045
|
+
// ../../../Decionis/packages/shared/src/Decisioning/SnapshotValidity.ts
|
|
6046
6046
|
var SnapshotValidity = class _SnapshotValidity {
|
|
6047
6047
|
/** Default snapshot lifetime (24h). */
|
|
6048
6048
|
static DEFAULT_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -6110,7 +6110,7 @@ function withRollingValidity(template, options = {}) {
|
|
|
6110
6110
|
return SnapshotValidity.withRollingValidity(template, options);
|
|
6111
6111
|
}
|
|
6112
6112
|
|
|
6113
|
-
//
|
|
6113
|
+
// ../../../Decionis/packages/shared/src/Decisioning/EnforcementMode.ts
|
|
6114
6114
|
var ENFORCEMENT_SPELLINGS = /* @__PURE__ */ new Set(["enforce", "enforced", "enforcement"]);
|
|
6115
6115
|
function normalizeEnforcementMode(value, fallback = "SHADOW") {
|
|
6116
6116
|
if (typeof value !== "string") return fallback;
|
|
@@ -6121,7 +6121,7 @@ function normalizeEnforcementMode(value, fallback = "SHADOW") {
|
|
|
6121
6121
|
return fallback;
|
|
6122
6122
|
}
|
|
6123
6123
|
|
|
6124
|
-
//
|
|
6124
|
+
// ../../../Decionis/packages/shared/src/Decisioning/PolicyResolution.ts
|
|
6125
6125
|
var EVALUATE_DECISION_POLICY_RESOLUTIONS = [
|
|
6126
6126
|
/** A policy guard stopped the evaluation before rules ran. */
|
|
6127
6127
|
"policy_guard_blocked",
|
|
@@ -6156,7 +6156,7 @@ var RESERVED_REQUEST_FACTS = [
|
|
|
6156
6156
|
"requested_policy_version"
|
|
6157
6157
|
];
|
|
6158
6158
|
|
|
6159
|
-
//
|
|
6159
|
+
// ../../../Decionis/packages/shared/src/Decisioning/EffectEvidence.ts
|
|
6160
6160
|
var EFFECT_EVIDENCE_VERSION = "1.0";
|
|
6161
6161
|
var EffectObservationMethodSchema = external_exports.enum([
|
|
6162
6162
|
"DOWNSTREAM_ACK",
|
|
@@ -6228,7 +6228,7 @@ var EffectEvidenceSchema = external_exports.object({
|
|
|
6228
6228
|
}
|
|
6229
6229
|
});
|
|
6230
6230
|
|
|
6231
|
-
//
|
|
6231
|
+
// ../../../Decionis/packages/shared/src/Decisioning/SemanticSignals.ts
|
|
6232
6232
|
var SEMANTIC_SIGNAL_SCHEMA_VERSION = "1.0";
|
|
6233
6233
|
var BUILT_IN_SEMANTIC_SIGNAL_KINDS = [
|
|
6234
6234
|
"intent_risk",
|
|
@@ -6404,7 +6404,7 @@ function stringOrNull(value) {
|
|
|
6404
6404
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
6405
6405
|
}
|
|
6406
6406
|
|
|
6407
|
-
//
|
|
6407
|
+
// ../../../Decionis/packages/shared/src/Decisioning/UpstreamAuthorization.ts
|
|
6408
6408
|
var AUTHZEN_PROTOCOL = "authzen/1.0";
|
|
6409
6409
|
var sha256Digest3 = external_exports.string().regex(/^sha256:[0-9a-f]{64}$/);
|
|
6410
6410
|
var bounded = external_exports.string().trim().min(1).max(200);
|
|
@@ -6438,7 +6438,7 @@ var UpstreamAuthorizationValueSchema = external_exports.object({
|
|
|
6438
6438
|
reasons: external_exports.array(bounded).max(50).optional()
|
|
6439
6439
|
}).strict();
|
|
6440
6440
|
|
|
6441
|
-
//
|
|
6441
|
+
// ../../../Decionis/packages/shared/src/Decisioning/AuthoritySemantics.ts
|
|
6442
6442
|
var DECIONIS_PROTOCOL_AUTHORITY_VERSION = "1.1";
|
|
6443
6443
|
var DECIONIS_EVALUATOR_VERSION = "policy-graph/1.1";
|
|
6444
6444
|
var DECIONIS_POLICY_SCHEMA_VERSION = "1.0";
|
|
@@ -6677,7 +6677,7 @@ function buildAuthorityEvidence(input) {
|
|
|
6677
6677
|
});
|
|
6678
6678
|
}
|
|
6679
6679
|
|
|
6680
|
-
//
|
|
6680
|
+
// ../../../Decionis/packages/shared/src/Decisioning/ExecutionRevalidation.ts
|
|
6681
6681
|
var EXECUTION_REVALIDATION_REASON_CODES = [
|
|
6682
6682
|
"EXECUTION_BINDING_VALID",
|
|
6683
6683
|
"PAYLOAD_BINDING_MISMATCH",
|
|
@@ -6766,6 +6766,19 @@ var FinalizationEffectEvidenceSchema = external_exports.union([
|
|
|
6766
6766
|
EffectEvidenceSchema,
|
|
6767
6767
|
ExecutionEffectEvidenceSchema
|
|
6768
6768
|
]);
|
|
6769
|
+
var EffectReceiptRecordSchema = external_exports.object({
|
|
6770
|
+
token: external_exports.string().min(1).max(2e4),
|
|
6771
|
+
token_digest: external_exports.string().regex(/^sha256:[0-9a-f]{64}$/),
|
|
6772
|
+
verified: external_exports.boolean(),
|
|
6773
|
+
verification_code: external_exports.string().min(1).max(100),
|
|
6774
|
+
provider_key_id: external_exports.string().min(1).max(200).nullable(),
|
|
6775
|
+
issuer: external_exports.string().min(1).max(500).nullable(),
|
|
6776
|
+
receipt_jti: external_exports.string().min(1).max(200).nullable(),
|
|
6777
|
+
effect_status: external_exports.enum(["EFFECTED", "REFUSED", "INDETERMINATE"]).nullable(),
|
|
6778
|
+
effect_digest: external_exports.string().regex(/^sha256:[0-9a-f]{64}$/).nullable(),
|
|
6779
|
+
effect_reference: external_exports.string().min(1).max(2e3).nullable(),
|
|
6780
|
+
effected_at: external_exports.string().datetime().nullable()
|
|
6781
|
+
}).strict();
|
|
6769
6782
|
function validateExecutionEffectEvidence(input) {
|
|
6770
6783
|
if (!input.expected_request_digest) return "EFFECT_REQUEST_BINDING_UNAVAILABLE";
|
|
6771
6784
|
if (input.effect_evidence.request_digest !== input.expected_request_digest) {
|
|
@@ -6789,6 +6802,7 @@ var ExecutionCommitEvidenceSchema = external_exports.object({
|
|
|
6789
6802
|
recorded_at: external_exports.string().datetime(),
|
|
6790
6803
|
downstream_evidence_digest: external_exports.string().regex(/^sha256:[0-9a-f]{64}$/),
|
|
6791
6804
|
effect_evidence: FinalizationEffectEvidenceSchema.nullable().optional(),
|
|
6805
|
+
effect_receipt: EffectReceiptRecordSchema.nullable().optional(),
|
|
6792
6806
|
evidence_hash: external_exports.string().regex(/^sha256:[0-9a-f]{64}$/)
|
|
6793
6807
|
}).strict().superRefine((evidence, context) => {
|
|
6794
6808
|
const expectedClaimState = evidence.commit_outcome === "COMMITTED" ? "FINALIZED" : evidence.commit_outcome === "FAILED" ? "FAILED" : "INDETERMINATE";
|
|
@@ -6801,7 +6815,142 @@ var ExecutionCommitEvidenceSchema = external_exports.object({
|
|
|
6801
6815
|
}
|
|
6802
6816
|
});
|
|
6803
6817
|
|
|
6804
|
-
//
|
|
6818
|
+
// ../../../Decionis/packages/shared/src/Decisioning/RuntimeSignals.ts
|
|
6819
|
+
var token = external_exports.string().trim().min(1).max(200).regex(/^[a-z0-9][\w.:/-]*$/i);
|
|
6820
|
+
var bounded2 = (max) => external_exports.string().trim().min(1).max(max);
|
|
6821
|
+
var RUNTIME_SIGNAL_ROOTS = ["enforcement_boundary", "workload"];
|
|
6822
|
+
var RUNTIME_ATTRIBUTION_FACT = "runtime_attribution";
|
|
6823
|
+
var WORKLOAD_TRUST_LEVELS = ["unverified", "supplied", "observed", "verified"];
|
|
6824
|
+
var BoundaryPlacementSchema = external_exports.object({
|
|
6825
|
+
cluster_id: token.optional(),
|
|
6826
|
+
namespace: token.optional(),
|
|
6827
|
+
region: token.optional(),
|
|
6828
|
+
workload_id: token.optional()
|
|
6829
|
+
}).strict();
|
|
6830
|
+
var EnforcementBoundarySignalSchema = external_exports.object({
|
|
6831
|
+
boundary_id: token,
|
|
6832
|
+
agentsafe_version: bounded2(80),
|
|
6833
|
+
protocol_version: external_exports.literal("agent-safe.intent/1"),
|
|
6834
|
+
deployment_type: token,
|
|
6835
|
+
environment: token.optional(),
|
|
6836
|
+
conformance_version: bounded2(120).optional(),
|
|
6837
|
+
placement: BoundaryPlacementSchema.optional()
|
|
6838
|
+
}).strict();
|
|
6839
|
+
var WorkloadProvenanceSchema = external_exports.object({
|
|
6840
|
+
source: token,
|
|
6841
|
+
trust_level: external_exports.enum(WORKLOAD_TRUST_LEVELS)
|
|
6842
|
+
}).strict();
|
|
6843
|
+
var WorkloadSignalSchema = external_exports.object({
|
|
6844
|
+
runtime: token.optional(),
|
|
6845
|
+
artifact_type: token.optional(),
|
|
6846
|
+
// An OCI reference and a publisher name, held to the character classes a
|
|
6847
|
+
// reference and a name actually use. The producer constrains these where
|
|
6848
|
+
// it reads them, but Decionis receives this shape from any producer, and
|
|
6849
|
+
// these values reach signed evidence and an operator's console: free text
|
|
6850
|
+
// arriving here would be free text leaving there.
|
|
6851
|
+
image: external_exports.string().trim().min(1).max(500).regex(/^[\w.:/@-]+$/).optional(),
|
|
6852
|
+
digest: external_exports.string().regex(/^sha256:[0-9a-f]{64}$/).optional(),
|
|
6853
|
+
publisher: external_exports.string().trim().min(1).max(200).regex(/^[\w .:/@-]+$/).optional(),
|
|
6854
|
+
provenance: WorkloadProvenanceSchema
|
|
6855
|
+
}).strict();
|
|
6856
|
+
var RuntimeSignals = class _RuntimeSignals {
|
|
6857
|
+
static parse(context) {
|
|
6858
|
+
const boundaryRaw = context.enforcement_boundary;
|
|
6859
|
+
const workloadRaw = context.workload;
|
|
6860
|
+
let boundary = null;
|
|
6861
|
+
let workload = null;
|
|
6862
|
+
if (boundaryRaw !== void 0 && boundaryRaw !== null) {
|
|
6863
|
+
const parsed = EnforcementBoundarySignalSchema.safeParse(boundaryRaw);
|
|
6864
|
+
if (!parsed.success) {
|
|
6865
|
+
return {
|
|
6866
|
+
ok: false,
|
|
6867
|
+
path: "context.enforcement_boundary",
|
|
6868
|
+
message: _RuntimeSignals.messageOf(parsed.error)
|
|
6869
|
+
};
|
|
6870
|
+
}
|
|
6871
|
+
boundary = parsed.data;
|
|
6872
|
+
}
|
|
6873
|
+
if (workloadRaw !== void 0 && workloadRaw !== null) {
|
|
6874
|
+
const parsed = WorkloadSignalSchema.safeParse(workloadRaw);
|
|
6875
|
+
if (!parsed.success) {
|
|
6876
|
+
return {
|
|
6877
|
+
ok: false,
|
|
6878
|
+
path: "context.workload",
|
|
6879
|
+
message: _RuntimeSignals.messageOf(parsed.error)
|
|
6880
|
+
};
|
|
6881
|
+
}
|
|
6882
|
+
workload = parsed.data;
|
|
6883
|
+
}
|
|
6884
|
+
return { ok: true, boundary, workload };
|
|
6885
|
+
}
|
|
6886
|
+
/**
|
|
6887
|
+
* The first problem, named by its own path. Bounded and structural: it
|
|
6888
|
+
* repeats no value the caller sent, so a refusal cannot echo a payload back
|
|
6889
|
+
* into a log.
|
|
6890
|
+
*/
|
|
6891
|
+
static messageOf(error) {
|
|
6892
|
+
const issue = error.issues[0];
|
|
6893
|
+
if (!issue) return "invalid";
|
|
6894
|
+
const where = issue.path.length > 0 ? issue.path.join(".") : "(root)";
|
|
6895
|
+
return `${where}: ${issue.code}`;
|
|
6896
|
+
}
|
|
6897
|
+
/** What Decionis says about the report, computed from the parsed signals alone. */
|
|
6898
|
+
static attributionOf(input) {
|
|
6899
|
+
const { boundary, workload } = input;
|
|
6900
|
+
const placement = boundary?.placement;
|
|
6901
|
+
return {
|
|
6902
|
+
reported: boundary !== null || workload !== null,
|
|
6903
|
+
boundary_id: boundary?.boundary_id ?? null,
|
|
6904
|
+
deployment_type: boundary?.deployment_type ?? null,
|
|
6905
|
+
environment: boundary?.environment ?? null,
|
|
6906
|
+
cluster_id: placement?.cluster_id ?? null,
|
|
6907
|
+
namespace: placement?.namespace ?? null,
|
|
6908
|
+
region: placement?.region ?? null,
|
|
6909
|
+
workload_digest: workload?.digest ?? null,
|
|
6910
|
+
workload_image: workload?.image ?? null,
|
|
6911
|
+
workload_publisher: workload?.publisher ?? null,
|
|
6912
|
+
workload_runtime: workload?.runtime ?? null,
|
|
6913
|
+
trust_level: workload?.provenance.trust_level ?? null,
|
|
6914
|
+
trust_source: workload?.provenance.source ?? null,
|
|
6915
|
+
// Nothing in this chain verified an artifact. When something does, it
|
|
6916
|
+
// sets this, and every policy written against it starts meaning more
|
|
6917
|
+
// without being rewritten.
|
|
6918
|
+
platform_verified: false
|
|
6919
|
+
};
|
|
6920
|
+
}
|
|
6921
|
+
/**
|
|
6922
|
+
* What reaches signed evidence: the boundary that admitted the action and
|
|
6923
|
+
* the artifact that proposed it, with the platform's own statement about
|
|
6924
|
+
* how far that goes.
|
|
6925
|
+
*
|
|
6926
|
+
* The placement is included because an operator's own cluster and namespace
|
|
6927
|
+
* are theirs and are what a policy means by "production in eu". The
|
|
6928
|
+
* instance is not, and never arrives: the producer leaves the container,
|
|
6929
|
+
* pod and node out of what it binds.
|
|
6930
|
+
*/
|
|
6931
|
+
static evidenceOf(attribution) {
|
|
6932
|
+
if (!attribution.reported) return null;
|
|
6933
|
+
return {
|
|
6934
|
+
boundary_id: attribution.boundary_id,
|
|
6935
|
+
deployment_type: attribution.deployment_type,
|
|
6936
|
+
environment: attribution.environment,
|
|
6937
|
+
cluster_id: attribution.cluster_id,
|
|
6938
|
+
namespace: attribution.namespace,
|
|
6939
|
+
region: attribution.region,
|
|
6940
|
+
workload_digest: attribution.workload_digest,
|
|
6941
|
+
workload_image: attribution.workload_image,
|
|
6942
|
+
workload_publisher: attribution.workload_publisher,
|
|
6943
|
+
trust_level: attribution.trust_level,
|
|
6944
|
+
trust_source: attribution.trust_source,
|
|
6945
|
+
platform_verified: attribution.platform_verified
|
|
6946
|
+
};
|
|
6947
|
+
}
|
|
6948
|
+
};
|
|
6949
|
+
var parseRuntimeSignals = RuntimeSignals.parse.bind(RuntimeSignals);
|
|
6950
|
+
var runtimeAttributionOf = RuntimeSignals.attributionOf.bind(RuntimeSignals);
|
|
6951
|
+
var runtimeAttributionEvidence = RuntimeSignals.evidenceOf.bind(RuntimeSignals);
|
|
6952
|
+
|
|
6953
|
+
// ../../../Decionis/packages/shared/src/Decisioning/ReasonCodes.ts
|
|
6805
6954
|
var ReasonCodes = class _ReasonCodes {
|
|
6806
6955
|
static codes = [
|
|
6807
6956
|
"PROTOCOL_OUTCOME_APPROVE",
|
|
@@ -7120,7 +7269,7 @@ function buildProtocolDecisionReasonCodes(response) {
|
|
|
7120
7269
|
return ReasonCodes.buildProtocolDecisionReasonCodes(response);
|
|
7121
7270
|
}
|
|
7122
7271
|
|
|
7123
|
-
//
|
|
7272
|
+
// ../../../Decionis/packages/shared/src/Authority/AuthorityRequirement.ts
|
|
7124
7273
|
var AUTHORITY_REQUIREMENT_VERSION = "decionis.authority_requirement/1";
|
|
7125
7274
|
var SYSTEM_APPROVER_ROLE_ID = "APPROVER";
|
|
7126
7275
|
var AuthoritySelectorSchema = external_exports.discriminatedUnion("kind", [
|
|
@@ -7160,10 +7309,22 @@ var AuthorityVerificationRequirementsSchema = external_exports.object({
|
|
|
7160
7309
|
});
|
|
7161
7310
|
}
|
|
7162
7311
|
});
|
|
7312
|
+
var AuthorityApprovalTierSchema = external_exports.object({
|
|
7313
|
+
priority: external_exports.number().int().min(1).max(5),
|
|
7314
|
+
principal_ids: external_exports.array(external_exports.string().min(1).max(200)).min(1).max(10)
|
|
7315
|
+
}).strict();
|
|
7163
7316
|
var AuthorityResolutionPolicySchema = external_exports.object({
|
|
7164
7317
|
quorum: external_exports.literal(1),
|
|
7165
7318
|
delegation: external_exports.enum(["DISALLOWED", "REQUIREMENT_REFRESH"]),
|
|
7166
|
-
fallback_role_ids: external_exports.array(external_exports.string().regex(/^[A-Z][A-Z0-9_]{1,63}$/)).max(10).default([])
|
|
7319
|
+
fallback_role_ids: external_exports.array(external_exports.string().regex(/^[A-Z][A-Z0-9_]{1,63}$/)).max(10).default([]),
|
|
7320
|
+
/**
|
|
7321
|
+
* An approval chain. Absent, the requirement is one ceremony by one subject
|
|
7322
|
+
* (`quorum` 1). Present, the policy names who approves in priority tiers and
|
|
7323
|
+
* the requirement is met only by one valid proof from every tier; Decionis
|
|
7324
|
+
* keeps no chain state — the orchestrator (or Presence) runs it and Decionis
|
|
7325
|
+
* verifies each proof against the tier it comes from.
|
|
7326
|
+
*/
|
|
7327
|
+
tiers: external_exports.array(AuthorityApprovalTierSchema).min(1).max(5).optional()
|
|
7167
7328
|
}).strict().superRefine((policy, context) => {
|
|
7168
7329
|
if (new Set(policy.fallback_role_ids).size !== policy.fallback_role_ids.length) {
|
|
7169
7330
|
context.addIssue({
|
|
@@ -7172,6 +7333,24 @@ var AuthorityResolutionPolicySchema = external_exports.object({
|
|
|
7172
7333
|
message: "fallback role ids must be unique"
|
|
7173
7334
|
});
|
|
7174
7335
|
}
|
|
7336
|
+
if (policy.tiers) {
|
|
7337
|
+
const priorities = policy.tiers.map((tier) => tier.priority);
|
|
7338
|
+
if (priorities.some((priority, index) => index > 0 && priority <= priorities[index - 1])) {
|
|
7339
|
+
context.addIssue({
|
|
7340
|
+
code: external_exports.ZodIssueCode.custom,
|
|
7341
|
+
path: ["tiers"],
|
|
7342
|
+
message: "tier priorities must be unique and ascending"
|
|
7343
|
+
});
|
|
7344
|
+
}
|
|
7345
|
+
const principals = policy.tiers.flatMap((tier) => tier.principal_ids);
|
|
7346
|
+
if (new Set(principals).size !== principals.length) {
|
|
7347
|
+
context.addIssue({
|
|
7348
|
+
code: external_exports.ZodIssueCode.custom,
|
|
7349
|
+
path: ["tiers"],
|
|
7350
|
+
message: "a principal belongs to one tier only"
|
|
7351
|
+
});
|
|
7352
|
+
}
|
|
7353
|
+
}
|
|
7175
7354
|
});
|
|
7176
7355
|
var AuthorityRequirementOriginatorSchema = external_exports.object({
|
|
7177
7356
|
organization_id: external_exports.string().min(1).max(200),
|
|
@@ -7237,6 +7416,13 @@ var AuthorityRequirementSchema = external_exports.object({
|
|
|
7237
7416
|
message: "fallback roles must not repeat the primary role"
|
|
7238
7417
|
});
|
|
7239
7418
|
}
|
|
7419
|
+
if (requirement.resolution.tiers && requirement.selector.kind !== "ROLE") {
|
|
7420
|
+
context.addIssue({
|
|
7421
|
+
code: external_exports.ZodIssueCode.custom,
|
|
7422
|
+
path: ["resolution", "tiers"],
|
|
7423
|
+
message: "an approval chain names its members' trusted role through a ROLE selector"
|
|
7424
|
+
});
|
|
7425
|
+
}
|
|
7240
7426
|
if (requirement.orchestration?.mode === "MANAGED" && requirement.selector.kind === "PRINCIPAL" && requirement.selector.role_id === void 0) {
|
|
7241
7427
|
context.addIssue({
|
|
7242
7428
|
code: external_exports.ZodIssueCode.custom,
|
|
@@ -7246,7 +7432,7 @@ var AuthorityRequirementSchema = external_exports.object({
|
|
|
7246
7432
|
}
|
|
7247
7433
|
});
|
|
7248
7434
|
|
|
7249
|
-
//
|
|
7435
|
+
// ../../../Decionis/packages/shared/src/Marketplaces.ts
|
|
7250
7436
|
var Marketplaces = class {
|
|
7251
7437
|
static targets = [
|
|
7252
7438
|
"atlassian",
|
|
@@ -7289,8 +7475,10 @@ var Marketplaces = class {
|
|
|
7289
7475
|
launch_state: "pilot_ready"
|
|
7290
7476
|
},
|
|
7291
7477
|
aws: {
|
|
7292
|
-
//
|
|
7293
|
-
//
|
|
7478
|
+
// The AWS adapter is Commerce Gate's AgentSaaS (API-based SaaS) and
|
|
7479
|
+
// AgentOps (its container for Bedrock AgentCore), built in the Commerce
|
|
7480
|
+
// repository; they replaced the customer-VPC Lambda and Bedrock guards,
|
|
7481
|
+
// retired on 2026-09-26. Listing not yet GA.
|
|
7294
7482
|
adapter_state: "available",
|
|
7295
7483
|
workflow_state: "available",
|
|
7296
7484
|
docs_state: "available",
|
|
@@ -7373,10 +7561,11 @@ var Marketplaces = class {
|
|
|
7373
7561
|
// classic checkout, core COGS, HPOS order CRUD, and the signed dossier were
|
|
7374
7562
|
// verified end to end on a staging store with real credentials — including
|
|
7375
7563
|
// an admin-enabled ENFORCEMENT block — before the listing went live.
|
|
7564
|
+
// Production (Festus, 2026-09-26); each store still starts in Shadow Mode.
|
|
7376
7565
|
adapter_state: "available",
|
|
7377
7566
|
workflow_state: "available",
|
|
7378
7567
|
docs_state: "available",
|
|
7379
|
-
launch_state: "
|
|
7568
|
+
launch_state: "production"
|
|
7380
7569
|
},
|
|
7381
7570
|
tiktok: {
|
|
7382
7571
|
// Post-purchase fulfillment circuit breaker: OAuth + refresh, signed Open API,
|
|
@@ -7402,19 +7591,23 @@ var Marketplaces = class {
|
|
|
7402
7591
|
// referral fee + shipping), and Acknowledge-Order release/hold are built and
|
|
7403
7592
|
// unit-tested. Production Solution Provider credentials are issued and every
|
|
7404
7593
|
// previously guessed API detail is verified against the Walmart Developer Portal
|
|
7405
|
-
// (2026-08-16; decionis/Commerce docs/walmart/ConfirmBeforeLive.md).
|
|
7406
|
-
//
|
|
7594
|
+
// (2026-08-16; decionis/Commerce docs/walmart/ConfirmBeforeLive.md). On
|
|
7595
|
+
// 2026-09-16 Walmart approved Decionis, Inc. as a Marketplace Solution
|
|
7596
|
+
// Provider (Specialty Partner — Orders) and the Decionis Commerce Gate app
|
|
7597
|
+
// passed review and was published in the Seller Center App Store, where
|
|
7598
|
+
// sellers install it in one click. Production since then (Festus,
|
|
7599
|
+
// 2026-09-26); each seller still starts in Shadow Mode.
|
|
7407
7600
|
adapter_state: "available",
|
|
7408
7601
|
workflow_state: "available",
|
|
7409
7602
|
docs_state: "partial",
|
|
7410
|
-
launch_state: "
|
|
7603
|
+
launch_state: "production"
|
|
7411
7604
|
}
|
|
7412
7605
|
};
|
|
7413
7606
|
};
|
|
7414
7607
|
var MARKETPLACE_TARGETS = Marketplaces.targets;
|
|
7415
7608
|
var MARKETPLACE_READINESS_BY_TARGET = Marketplaces.readinessByTarget;
|
|
7416
7609
|
|
|
7417
|
-
//
|
|
7610
|
+
// ../../../Decionis/packages/shared/src/Patterns/ExecutionPatternClassifier.ts
|
|
7418
7611
|
var EXECUTION_PATTERN_RULES = [
|
|
7419
7612
|
{
|
|
7420
7613
|
pattern: "mcp-egress",
|
|
@@ -7521,7 +7714,7 @@ var EXECUTION_PATTERN_RECIPE_TAGS = Object.fromEntries(
|
|
|
7521
7714
|
EXECUTION_PATTERN_RULES.map((rule) => [rule.pattern, rule.recipeTags])
|
|
7522
7715
|
);
|
|
7523
7716
|
|
|
7524
|
-
//
|
|
7717
|
+
// ../../../Decionis/packages/shared/src/PolicyPacks/PolicyPackRegistry.ts
|
|
7525
7718
|
var DISCOUNT_GUARDRAILS = {
|
|
7526
7719
|
id: "discount-guardrails",
|
|
7527
7720
|
name: "Discount Guardrails",
|
|
@@ -7625,7 +7818,7 @@ var POLICY_PACKS = [
|
|
|
7625
7818
|
];
|
|
7626
7819
|
var POLICY_PACK_IDS = POLICY_PACKS.map((pack) => pack.id);
|
|
7627
7820
|
|
|
7628
|
-
//
|
|
7821
|
+
// ../../../Decionis/packages/shared/src/capital/CapitalContracts.ts
|
|
7629
7822
|
var defaultCapitalPolicySnapshot = withRollingValidity({
|
|
7630
7823
|
policyVersion: "capital-multiplier-v1",
|
|
7631
7824
|
// Shadow by default: observe and quantify before anything moves money.
|
|
@@ -7658,7 +7851,7 @@ var defaultCapitalPolicySnapshot = withRollingValidity({
|
|
|
7658
7851
|
}
|
|
7659
7852
|
});
|
|
7660
7853
|
|
|
7661
|
-
//
|
|
7854
|
+
// ../../../Decionis/packages/shared/src/capital/CapitalCopy.ts
|
|
7662
7855
|
var CapitalCopy = class _CapitalCopy {
|
|
7663
7856
|
static defaultCopy = {
|
|
7664
7857
|
early_payment_yield: {
|
|
@@ -7830,7 +8023,7 @@ var CapitalCopy = class _CapitalCopy {
|
|
|
7830
8023
|
};
|
|
7831
8024
|
var CAPITAL_COPY_BY_PLATFORM = CapitalCopy.copyByPlatform;
|
|
7832
8025
|
|
|
7833
|
-
//
|
|
8026
|
+
// ../../../Decionis/packages/shared/src/capital/CapitalCards.ts
|
|
7834
8027
|
var CapitalCards = class _CapitalCards {
|
|
7835
8028
|
static actionVerbs = {
|
|
7836
8029
|
approve: "capital.recommendation.approve",
|
|
@@ -7948,7 +8141,7 @@ ${rec.disposition.replace(/_/g, " ")}` }
|
|
|
7948
8141
|
};
|
|
7949
8142
|
var capitalRecommendationActionVerbs = CapitalCards.actionVerbs;
|
|
7950
8143
|
|
|
7951
|
-
//
|
|
8144
|
+
// ../../../Decionis/packages/shared/src/Microsoft/MicrosoftDecisionDossier.ts
|
|
7952
8145
|
var MicrosoftDecisionDossierFactory = class _MicrosoftDecisionDossierFactory {
|
|
7953
8146
|
static actionVerbs = {
|
|
7954
8147
|
approve: "decision.dossier.approve",
|
|
@@ -8286,7 +8479,7 @@ ${dossier.reason}`,
|
|
|
8286
8479
|
};
|
|
8287
8480
|
var microsoftTeamsDecisionDossierActionVerbs = MicrosoftDecisionDossierFactory.actionVerbs;
|
|
8288
8481
|
|
|
8289
|
-
//
|
|
8482
|
+
// ../../../Decionis/packages/shared/src/Procure/ProcureContracts.ts
|
|
8290
8483
|
var ProcureDisposition = {
|
|
8291
8484
|
APPROVE: "APPROVE",
|
|
8292
8485
|
REJECT: "REJECT",
|
|
@@ -8336,7 +8529,7 @@ var ProcureDecisionStepOutputSchema = external_exports.object({
|
|
|
8336
8529
|
referral_id: external_exports.string().uuid().optional()
|
|
8337
8530
|
}).strict();
|
|
8338
8531
|
|
|
8339
|
-
//
|
|
8532
|
+
// ../../../Decionis/packages/shared/src/Procure/ProcureDsl.ts
|
|
8340
8533
|
var PrimitiveSchema = external_exports.union([external_exports.string(), external_exports.number(), external_exports.boolean(), external_exports.null()]);
|
|
8341
8534
|
var ProcureDslConditionSchema = external_exports.lazy(
|
|
8342
8535
|
() => external_exports.union([
|
|
@@ -8397,7 +8590,7 @@ var ProcureDslSchema = external_exports.object({
|
|
|
8397
8590
|
fallback: ProcureDslThenSchema
|
|
8398
8591
|
}).strict();
|
|
8399
8592
|
|
|
8400
|
-
//
|
|
8593
|
+
// ../../../Decionis/packages/shared/src/Sidecar/SidecarContracts.ts
|
|
8401
8594
|
var ReaderArtifactTypeSchema = external_exports.enum([
|
|
8402
8595
|
"DECISION_DOSSIER",
|
|
8403
8596
|
"DECISION_CHAIN",
|
|
@@ -8597,8 +8790,10 @@ var ExtensionConfigResponseSchema = external_exports.object({
|
|
|
8597
8790
|
generated_at: external_exports.string()
|
|
8598
8791
|
}).strict();
|
|
8599
8792
|
|
|
8600
|
-
//
|
|
8793
|
+
// ../../../Decionis/apps/protocol/src/ledger/LedgerChain.ts
|
|
8601
8794
|
import { createHash } from "crypto";
|
|
8795
|
+
var LEDGER_FORK_RESOLVED_EVENT_TYPE = "LEDGER_FORK_RESOLVED";
|
|
8796
|
+
var LEDGER_ORPHAN_ISSUE_INDEX = -1;
|
|
8602
8797
|
var LedgerChain = class _LedgerChain {
|
|
8603
8798
|
static computeLedgerEntryHash(input) {
|
|
8604
8799
|
const canonicalPayload = {
|
|
@@ -8730,6 +8925,87 @@ var LedgerChain = class _LedgerChain {
|
|
|
8730
8925
|
issues
|
|
8731
8926
|
};
|
|
8732
8927
|
}
|
|
8928
|
+
/**
|
|
8929
|
+
* Verify registered fork orphans. Each must be a well-formed entry whose
|
|
8930
|
+
* hash recomputes over its own predecessor, whose predecessor is a real
|
|
8931
|
+
* entry, and which a non-orphaned LEDGER_FORK_RESOLVED entry commits to (by
|
|
8932
|
+
* id, entry hash and predecessor hash) — so the registry can exclude only
|
|
8933
|
+
* what the hash chain itself records as excluded.
|
|
8934
|
+
*/
|
|
8935
|
+
static verifyLedgerOrphans(orgId, candidates) {
|
|
8936
|
+
const issues = [];
|
|
8937
|
+
const orphaned = [];
|
|
8938
|
+
for (const candidate of candidates) {
|
|
8939
|
+
const registration = candidate.registration;
|
|
8940
|
+
const issuesBefore = issues.length;
|
|
8941
|
+
const issue = (reason, expected, actual) => issues.push({
|
|
8942
|
+
ledger_entry_id: registration.ledger_entry_id,
|
|
8943
|
+
index: LEDGER_ORPHAN_ISSUE_INDEX,
|
|
8944
|
+
reason,
|
|
8945
|
+
...expected !== void 0 ? { expected } : {},
|
|
8946
|
+
...actual !== void 0 ? { actual } : {}
|
|
8947
|
+
});
|
|
8948
|
+
const entry = candidate.entry;
|
|
8949
|
+
if (!entry || entry.ledger_entry_id !== registration.ledger_entry_id) {
|
|
8950
|
+
issue("ORPHAN_REGISTRY_MISMATCH");
|
|
8951
|
+
orphaned.push(_LedgerChain.orphanReport(registration, null, false));
|
|
8952
|
+
continue;
|
|
8953
|
+
}
|
|
8954
|
+
const own = _LedgerChain.verifyLedgerChainPage(orgId, [entry], {
|
|
8955
|
+
checked: 0,
|
|
8956
|
+
expected_prev_hash: entry.prev_hash,
|
|
8957
|
+
tail_hash: null,
|
|
8958
|
+
head_hash: null,
|
|
8959
|
+
issues: []
|
|
8960
|
+
});
|
|
8961
|
+
for (const found of own.issues) {
|
|
8962
|
+
issues.push({ ...found, index: LEDGER_ORPHAN_ISSUE_INDEX });
|
|
8963
|
+
}
|
|
8964
|
+
const entryHash = _LedgerChain.normalizeHash(entry.entry_hash);
|
|
8965
|
+
const prevHash = _LedgerChain.normalizeHash(entry.prev_hash);
|
|
8966
|
+
if (_LedgerChain.normalizeHash(registration.entry_hash) !== entryHash || _LedgerChain.normalizeHash(registration.fork_prev_hash) !== prevHash) {
|
|
8967
|
+
issue("ORPHAN_REGISTRY_MISMATCH", registration.entry_hash, entry.entry_hash);
|
|
8968
|
+
}
|
|
8969
|
+
if (!prevHash || !candidate.predecessor_exists) {
|
|
8970
|
+
issue("ORPHAN_PREDECESSOR_MISSING", null, entry.prev_hash);
|
|
8971
|
+
}
|
|
8972
|
+
if (!registration.resolution_entry_id) {
|
|
8973
|
+
issue("ORPHAN_UNRESOLVED");
|
|
8974
|
+
} else if (!_LedgerChain.resolutionCommitsToOrphan(orgId, registration, entry, candidate.resolution)) {
|
|
8975
|
+
issue("ORPHAN_RESOLUTION_MISMATCH", registration.resolution_entry_id, null);
|
|
8976
|
+
}
|
|
8977
|
+
orphaned.push(_LedgerChain.orphanReport(registration, entry, issues.length === issuesBefore));
|
|
8978
|
+
}
|
|
8979
|
+
return { orphaned, issues };
|
|
8980
|
+
}
|
|
8981
|
+
static resolutionCommitsToOrphan(orgId, registration, entry, resolution) {
|
|
8982
|
+
if (!resolution || resolution.orphaned) return false;
|
|
8983
|
+
const envelope = resolution.entry.payload;
|
|
8984
|
+
if (resolution.entry.ledger_entry_id !== registration.resolution_entry_id || envelope.event_type !== LEDGER_FORK_RESOLVED_EVENT_TYPE || envelope.org_id !== orgId) {
|
|
8985
|
+
return false;
|
|
8986
|
+
}
|
|
8987
|
+
const committed = _LedgerChain.asRecord(envelope.payload);
|
|
8988
|
+
const canonicalHead = _LedgerChain.asRecord(committed.canonical_head);
|
|
8989
|
+
if (committed.org_id !== orgId || _LedgerChain.normalizeHash(canonicalHead.entry_hash) !== _LedgerChain.normalizeHash(resolution.entry.prev_hash)) {
|
|
8990
|
+
return false;
|
|
8991
|
+
}
|
|
8992
|
+
const orphans = Array.isArray(committed.orphans) ? committed.orphans : [];
|
|
8993
|
+
return orphans.some((item) => {
|
|
8994
|
+
const orphan = _LedgerChain.asRecord(item);
|
|
8995
|
+
return orphan.ledger_entry_id === entry.ledger_entry_id && _LedgerChain.normalizeHash(orphan.entry_hash) === _LedgerChain.normalizeHash(entry.entry_hash) && _LedgerChain.normalizeHash(orphan.prev_hash) === _LedgerChain.normalizeHash(entry.prev_hash);
|
|
8996
|
+
});
|
|
8997
|
+
}
|
|
8998
|
+
static orphanReport(registration, entry, verified) {
|
|
8999
|
+
return {
|
|
9000
|
+
ledger_entry_id: registration.ledger_entry_id,
|
|
9001
|
+
entry_hash: entry?.entry_hash ?? registration.entry_hash,
|
|
9002
|
+
prev_hash: entry ? entry.prev_hash : registration.fork_prev_hash,
|
|
9003
|
+
status: "orphaned",
|
|
9004
|
+
reason: registration.reason,
|
|
9005
|
+
resolution_entry_id: registration.resolution_entry_id,
|
|
9006
|
+
verified
|
|
9007
|
+
};
|
|
9008
|
+
}
|
|
8733
9009
|
static normalizeHash(value) {
|
|
8734
9010
|
if (typeof value !== "string") return null;
|
|
8735
9011
|
const hash = value.trim();
|
|
@@ -8776,19 +9052,26 @@ function bindLedgerEntryToPrevious(payload, previousHash) {
|
|
|
8776
9052
|
function verifyLedgerChain(orgId, entries) {
|
|
8777
9053
|
return LedgerChain.verifyLedgerChain(orgId, entries);
|
|
8778
9054
|
}
|
|
9055
|
+
function verifyLedgerOrphans(orgId, candidates) {
|
|
9056
|
+
return LedgerChain.verifyLedgerOrphans(orgId, candidates);
|
|
9057
|
+
}
|
|
8779
9058
|
|
|
8780
|
-
//
|
|
9059
|
+
// ../../../Decionis/apps/protocol/src/store/StoreContracts.ts
|
|
8781
9060
|
var DECISION_CHAIN_PROJECTION_LIMIT = 500;
|
|
9061
|
+
var AUDIT_LEDGER_NOT_APPENDABLE = "AUDIT_LEDGER_NOT_APPENDABLE";
|
|
8782
9062
|
var ProtocolStoreValidationError = class extends Error {
|
|
8783
9063
|
issues;
|
|
8784
|
-
|
|
9064
|
+
/** Stable machine-readable code for failures callers must tell apart. */
|
|
9065
|
+
code;
|
|
9066
|
+
constructor(message, issues, options) {
|
|
8785
9067
|
super(message);
|
|
8786
9068
|
this.name = "ProtocolStoreValidationError";
|
|
8787
9069
|
this.issues = issues;
|
|
9070
|
+
if (options?.code) this.code = options.code;
|
|
8788
9071
|
}
|
|
8789
9072
|
};
|
|
8790
9073
|
|
|
8791
|
-
//
|
|
9074
|
+
// ../../../Decionis/apps/protocol/src/store/DecisionDossierImmutability.ts
|
|
8792
9075
|
function evaluationCommitmentFromInput(input, evaluationId) {
|
|
8793
9076
|
return {
|
|
8794
9077
|
id: evaluationId,
|
|
@@ -8870,7 +9153,7 @@ function assertCanonicalDecisionDossierRetry(input) {
|
|
|
8870
9153
|
return committedEvaluation;
|
|
8871
9154
|
}
|
|
8872
9155
|
|
|
8873
|
-
//
|
|
9156
|
+
// ../../../Decionis/apps/protocol/src/store/StoreHelpers.ts
|
|
8874
9157
|
var UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
8875
9158
|
var ARTIFACT_ID_FIELDS = {
|
|
8876
9159
|
signal_envelope: "envelope_id",
|
|
@@ -8953,7 +9236,7 @@ function getOccurredAt(kind, payload) {
|
|
|
8953
9236
|
return StoreHelpers.getOccurredAt(kind, payload);
|
|
8954
9237
|
}
|
|
8955
9238
|
|
|
8956
|
-
//
|
|
9239
|
+
// ../../../Decionis/apps/protocol/src/store/MemoryProtocolStore.ts
|
|
8957
9240
|
var DECISION_CHAIN_LEDGER_ACTION_ORDER = {
|
|
8958
9241
|
"protocol.execution.precommit_revalidated": 0,
|
|
8959
9242
|
"protocol.execution.dispatched": 1,
|
|
@@ -8976,6 +9259,8 @@ function compareDecisionChainLedgerRows(left, right) {
|
|
|
8976
9259
|
var MemoryProtocolStore = class _MemoryProtocolStore {
|
|
8977
9260
|
byKey = /* @__PURE__ */ new Map();
|
|
8978
9261
|
auditLedgerChainById = /* @__PURE__ */ new Map();
|
|
9262
|
+
/** Mirror of `decionis_protocol.audit_ledger_orphans`. */
|
|
9263
|
+
auditLedgerOrphans = /* @__PURE__ */ new Map();
|
|
8979
9264
|
auditLedgerAppendOrdinal = 0n;
|
|
8980
9265
|
orgVerticalPacks = /* @__PURE__ */ new Map();
|
|
8981
9266
|
evaluationById = /* @__PURE__ */ new Map();
|
|
@@ -9077,8 +9362,18 @@ var MemoryProtocolStore = class _MemoryProtocolStore {
|
|
|
9077
9362
|
entry_hash: existingLedgerRow.entry_hash
|
|
9078
9363
|
};
|
|
9079
9364
|
}
|
|
9080
|
-
const
|
|
9081
|
-
|
|
9365
|
+
const orgRows = Array.from(this.auditLedgerChainById.values()).filter(
|
|
9366
|
+
(row) => row.org_id === orgId
|
|
9367
|
+
);
|
|
9368
|
+
const heads = this.candidateAuditLedgerHeads(orgRows);
|
|
9369
|
+
if (orgRows.length === 0 && heads.length !== 0 || orgRows.length > 0 && heads.length !== 1) {
|
|
9370
|
+
throw new ProtocolStoreValidationError(
|
|
9371
|
+
"Audit ledger is not appendable",
|
|
9372
|
+
[{ path: "chain.prev_hash", message: "canonical ledger has no unique head" }],
|
|
9373
|
+
{ code: AUDIT_LEDGER_NOT_APPENDABLE }
|
|
9374
|
+
);
|
|
9375
|
+
}
|
|
9376
|
+
const bound = bindLedgerEntryToPrevious(payload, heads[0]?.entry_hash ?? null);
|
|
9082
9377
|
persistedPayload = bound.payload;
|
|
9083
9378
|
const chain = persistedPayload.chain && typeof persistedPayload.chain === "object" && !Array.isArray(persistedPayload.chain) ? persistedPayload.chain : {};
|
|
9084
9379
|
const entryHash = typeof chain.entry_hash === "string" ? chain.entry_hash.toLowerCase() : "";
|
|
@@ -9126,8 +9421,101 @@ var MemoryProtocolStore = class _MemoryProtocolStore {
|
|
|
9126
9421
|
}).slice(0, input.limit);
|
|
9127
9422
|
return rows.map((row) => row.payload);
|
|
9128
9423
|
}
|
|
9424
|
+
candidateAuditLedgerHeads(orgRows) {
|
|
9425
|
+
const predecessors = new Set(
|
|
9426
|
+
orgRows.map((row) => row.prev_hash).filter((hash) => hash !== null)
|
|
9427
|
+
);
|
|
9428
|
+
return orgRows.filter(
|
|
9429
|
+
(row) => !predecessors.has(row.entry_hash) && !this.auditLedgerOrphans.has(row.ledger_entry_id)
|
|
9430
|
+
);
|
|
9431
|
+
}
|
|
9432
|
+
withLedgerMembership(row) {
|
|
9433
|
+
const orphan = this.auditLedgerOrphans.get(row.ledger_entry_id);
|
|
9434
|
+
return orphan && orphan.org_id === row.org_id ? {
|
|
9435
|
+
...row,
|
|
9436
|
+
ledger_membership: "orphaned",
|
|
9437
|
+
orphan_resolution_entry_id: orphan.resolution_entry_id
|
|
9438
|
+
} : row;
|
|
9439
|
+
}
|
|
9440
|
+
auditLedgerOrphanCandidates(orgId) {
|
|
9441
|
+
const orgRows = Array.from(this.auditLedgerChainById.values()).filter(
|
|
9442
|
+
(row) => row.org_id === orgId
|
|
9443
|
+
);
|
|
9444
|
+
const hashes = new Set(orgRows.map((row) => row.entry_hash));
|
|
9445
|
+
const occurredAt = (id) => this.auditLedgerChainById.get(id)?.occurred_at ?? "";
|
|
9446
|
+
return Array.from(this.auditLedgerOrphans.values()).filter((orphan) => orphan.org_id === orgId).sort(
|
|
9447
|
+
(left, right) => occurredAt(left.ledger_entry_id).localeCompare(occurredAt(right.ledger_entry_id)) || left.ledger_entry_id.localeCompare(right.ledger_entry_id)
|
|
9448
|
+
).map((orphan) => {
|
|
9449
|
+
const entry = this.auditLedgerChainById.get(orphan.ledger_entry_id);
|
|
9450
|
+
const resolution = orphan.resolution_entry_id ? this.auditLedgerChainById.get(orphan.resolution_entry_id) : void 0;
|
|
9451
|
+
return {
|
|
9452
|
+
registration: {
|
|
9453
|
+
ledger_entry_id: orphan.ledger_entry_id,
|
|
9454
|
+
entry_hash: orphan.entry_hash,
|
|
9455
|
+
fork_prev_hash: orphan.fork_prev_hash,
|
|
9456
|
+
reason: orphan.reason,
|
|
9457
|
+
resolution_entry_id: orphan.resolution_entry_id
|
|
9458
|
+
},
|
|
9459
|
+
entry: entry && entry.org_id === orgId ? structuredClone(entry) : null,
|
|
9460
|
+
predecessor_exists: entry?.prev_hash ? hashes.has(entry.prev_hash) : false,
|
|
9461
|
+
resolution: resolution && resolution.org_id === orgId ? {
|
|
9462
|
+
entry: structuredClone(resolution),
|
|
9463
|
+
orphaned: this.auditLedgerOrphans.has(resolution.ledger_entry_id)
|
|
9464
|
+
} : null
|
|
9465
|
+
};
|
|
9466
|
+
});
|
|
9467
|
+
}
|
|
9468
|
+
/**
|
|
9469
|
+
* Mirror of the operator registry insert (`audit_ledger_orphans`) with the
|
|
9470
|
+
* same integrity rules its trigger enforces: the entry exists in this org's
|
|
9471
|
+
* ledger, the recorded hashes are the entry's own, and nothing is registered
|
|
9472
|
+
* twice. The chain itself is never modified.
|
|
9473
|
+
*/
|
|
9474
|
+
async registerAuditLedgerOrphans(input) {
|
|
9475
|
+
const staged = [];
|
|
9476
|
+
for (const orphan of input.orphans) {
|
|
9477
|
+
const entry = this.auditLedgerChainById.get(orphan.ledger_entry_id);
|
|
9478
|
+
if (!entry || entry.org_id !== input.orgId) {
|
|
9479
|
+
throw new ProtocolStoreValidationError("Audit ledger orphan is not a ledger entry", [
|
|
9480
|
+
{ path: "ledger_entry_id", message: "must name an entry of this org's ledger" }
|
|
9481
|
+
]);
|
|
9482
|
+
}
|
|
9483
|
+
if (this.auditLedgerOrphans.has(orphan.ledger_entry_id) || staged.some((row) => row.ledger_entry_id === orphan.ledger_entry_id)) {
|
|
9484
|
+
throw new ProtocolStoreValidationError("Audit ledger orphan is already registered", [
|
|
9485
|
+
{ path: "ledger_entry_id", message: "an orphan is registered once" }
|
|
9486
|
+
]);
|
|
9487
|
+
}
|
|
9488
|
+
staged.push({
|
|
9489
|
+
ledger_entry_id: entry.ledger_entry_id,
|
|
9490
|
+
org_id: input.orgId,
|
|
9491
|
+
entry_hash: entry.entry_hash,
|
|
9492
|
+
fork_prev_hash: entry.prev_hash,
|
|
9493
|
+
reason: orphan.reason,
|
|
9494
|
+
resolution_entry_id: null,
|
|
9495
|
+
recorded_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
9496
|
+
recorded_by: input.recordedBy
|
|
9497
|
+
});
|
|
9498
|
+
}
|
|
9499
|
+
for (const row of staged) this.auditLedgerOrphans.set(row.ledger_entry_id, row);
|
|
9500
|
+
}
|
|
9501
|
+
/** Mirror of the one permitted registry update: name the resolution entry, once. */
|
|
9502
|
+
async setAuditLedgerOrphanResolution(input) {
|
|
9503
|
+
const resolution = this.auditLedgerChainById.get(input.resolutionEntryId);
|
|
9504
|
+
if (!resolution || resolution.org_id !== input.orgId) {
|
|
9505
|
+
throw new ProtocolStoreValidationError("Audit ledger resolution entry is unknown", [
|
|
9506
|
+
{ path: "resolution_entry_id", message: "must name an entry of this org's ledger" }
|
|
9507
|
+
]);
|
|
9508
|
+
}
|
|
9509
|
+
const rows = input.ledgerEntryIds.map((id) => this.auditLedgerOrphans.get(id));
|
|
9510
|
+
if (rows.some((row) => !row || row.org_id !== input.orgId || row.resolution_entry_id !== null)) {
|
|
9511
|
+
throw new ProtocolStoreValidationError("Audit ledger orphan resolution is immutable", [
|
|
9512
|
+
{ path: "resolution_entry_id", message: "set once, on a registered unresolved orphan" }
|
|
9513
|
+
]);
|
|
9514
|
+
}
|
|
9515
|
+
for (const row of rows) row.resolution_entry_id = input.resolutionEntryId;
|
|
9516
|
+
}
|
|
9129
9517
|
async getLatestAuditLedgerHead(orgId) {
|
|
9130
|
-
const latest = Array.from(this.auditLedgerChainById.values()).filter((row) => row.org_id === orgId).sort(_MemoryProtocolStore.compareCanonicalLedgerRows).at(-1);
|
|
9518
|
+
const latest = Array.from(this.auditLedgerChainById.values()).filter((row) => row.org_id === orgId && !this.auditLedgerOrphans.has(row.ledger_entry_id)).sort(_MemoryProtocolStore.compareCanonicalLedgerRows).at(-1);
|
|
9131
9519
|
if (!latest) return null;
|
|
9132
9520
|
return {
|
|
9133
9521
|
ledger_entry_id: latest.ledger_entry_id,
|
|
@@ -9137,7 +9525,7 @@ var MemoryProtocolStore = class _MemoryProtocolStore {
|
|
|
9137
9525
|
}
|
|
9138
9526
|
async getAuditLedgerEntry(input) {
|
|
9139
9527
|
const row = this.auditLedgerChainById.get(input.ledgerEntryId);
|
|
9140
|
-
return row?.org_id === input.orgId ? structuredClone(row) : null;
|
|
9528
|
+
return row?.org_id === input.orgId ? structuredClone(this.withLedgerMembership(row)) : null;
|
|
9141
9529
|
}
|
|
9142
9530
|
async listSignalEnvelopes(input) {
|
|
9143
9531
|
const wanted = new Set(input.signalIds);
|
|
@@ -9155,12 +9543,12 @@ var MemoryProtocolStore = class _MemoryProtocolStore {
|
|
|
9155
9543
|
return Array.from(latest.values()).map((row) => row.payload);
|
|
9156
9544
|
}
|
|
9157
9545
|
async verifyAuditLedgerChain(input) {
|
|
9158
|
-
const rows = Array.from(this.byKey.values()).filter((row) => row.kind === "audit_ledger_entry").filter((row) => row.org_id === input.orgId).sort((left, right) => {
|
|
9546
|
+
const rows = Array.from(this.byKey.values()).filter((row) => row.kind === "audit_ledger_entry").filter((row) => row.org_id === input.orgId).filter((row) => !this.auditLedgerOrphans.has(row.artifact_id)).sort((left, right) => {
|
|
9159
9547
|
const leftTs = left.occurred_at?.getTime() ?? 0;
|
|
9160
9548
|
const rightTs = right.occurred_at?.getTime() ?? 0;
|
|
9161
9549
|
return leftTs - rightTs;
|
|
9162
9550
|
}).slice(0, Math.max(1, Math.min(input.limit, 5e3)));
|
|
9163
|
-
|
|
9551
|
+
const verification = verifyLedgerChain(
|
|
9164
9552
|
input.orgId,
|
|
9165
9553
|
rows.map((row) => {
|
|
9166
9554
|
const chain = row.payload.chain ?? {};
|
|
@@ -9172,10 +9560,21 @@ var MemoryProtocolStore = class _MemoryProtocolStore {
|
|
|
9172
9560
|
};
|
|
9173
9561
|
})
|
|
9174
9562
|
);
|
|
9563
|
+
const candidates = this.auditLedgerOrphanCandidates(input.orgId);
|
|
9564
|
+
if (candidates.length === 0) return verification;
|
|
9565
|
+
const verifiedOrphans = verifyLedgerOrphans(input.orgId, candidates);
|
|
9566
|
+
const issues = [...verification.issues, ...verifiedOrphans.issues];
|
|
9567
|
+
return {
|
|
9568
|
+
...verification,
|
|
9569
|
+
broken_links: issues.length,
|
|
9570
|
+
valid: issues.length === 0,
|
|
9571
|
+
issues,
|
|
9572
|
+
orphaned: verifiedOrphans.orphaned
|
|
9573
|
+
};
|
|
9175
9574
|
}
|
|
9176
9575
|
async verifyAuditLedgerContinuity(input) {
|
|
9177
9576
|
const rows = Array.from(this.auditLedgerChainById.values()).filter(
|
|
9178
|
-
(row) => row.org_id === input.orgId
|
|
9577
|
+
(row) => row.org_id === input.orgId && !this.auditLedgerOrphans.has(row.ledger_entry_id)
|
|
9179
9578
|
);
|
|
9180
9579
|
rows.sort(_MemoryProtocolStore.compareCanonicalLedgerRows);
|
|
9181
9580
|
const maxEntries = input.maxEntries === void 0 ? rows.length : Number.isFinite(input.maxEntries) ? Math.max(1, Math.min(Math.floor(input.maxEntries), Number.MAX_SAFE_INTEGER)) : 1;
|
|
@@ -9188,14 +9587,19 @@ var MemoryProtocolStore = class _MemoryProtocolStore {
|
|
|
9188
9587
|
algorithm: typeof row.payload.chain?.algorithm === "string" ? row.payload.chain.algorithm : void 0
|
|
9189
9588
|
}))
|
|
9190
9589
|
);
|
|
9590
|
+
const verifiedOrphans = verifyLedgerOrphans(
|
|
9591
|
+
input.orgId,
|
|
9592
|
+
this.auditLedgerOrphanCandidates(input.orgId)
|
|
9593
|
+
);
|
|
9191
9594
|
return {
|
|
9192
9595
|
org_id: verification.org_id,
|
|
9193
9596
|
checked: verification.checked,
|
|
9194
|
-
valid: complete && verification.valid,
|
|
9597
|
+
valid: complete && verification.valid && verifiedOrphans.issues.length === 0,
|
|
9195
9598
|
complete,
|
|
9196
|
-
broken_links: verification.broken_links,
|
|
9599
|
+
broken_links: verification.broken_links + verifiedOrphans.issues.length,
|
|
9197
9600
|
head_hash: verification.head_hash,
|
|
9198
|
-
tail_hash: verification.tail_hash
|
|
9601
|
+
tail_hash: verification.tail_hash,
|
|
9602
|
+
...verifiedOrphans.orphaned.length > 0 ? { orphaned: verifiedOrphans.orphaned } : {}
|
|
9199
9603
|
};
|
|
9200
9604
|
}
|
|
9201
9605
|
async listPolicyBundles(input) {
|
|
@@ -9404,7 +9808,7 @@ var MemoryProtocolStore = class _MemoryProtocolStore {
|
|
|
9404
9808
|
const matching = Array.from(this.auditLedgerChainById.values()).filter((row) => row.org_id === input.orgId).filter((row) => {
|
|
9405
9809
|
const payload = row.payload.payload;
|
|
9406
9810
|
return payload !== null && typeof payload === "object" && !Array.isArray(payload) && payload.chain_id === input.chainId;
|
|
9407
|
-
}).sort(compareDecisionChainLedgerRows);
|
|
9811
|
+
}).sort(compareDecisionChainLedgerRows).map((row) => this.withLedgerMembership(row));
|
|
9408
9812
|
return {
|
|
9409
9813
|
entries: matching.slice(0, limit),
|
|
9410
9814
|
limit,
|
|
@@ -9481,7 +9885,7 @@ function createMemoryProtocolStore() {
|
|
|
9481
9885
|
return new MemoryProtocolStore();
|
|
9482
9886
|
}
|
|
9483
9887
|
|
|
9484
|
-
//
|
|
9888
|
+
// ../../../Decionis/apps/protocol/src/auth/McpAuth.ts
|
|
9485
9889
|
import { createHash as createHash2 } from "crypto";
|
|
9486
9890
|
var McpAuth = class _McpAuth {
|
|
9487
9891
|
static hashApiKey(rawKey, env = process.env) {
|
|
@@ -9551,7 +9955,7 @@ function hasAnyScope(grantedScopes, requiredScopes) {
|
|
|
9551
9955
|
return McpAuth.hasAnyScope(grantedScopes, requiredScopes);
|
|
9552
9956
|
}
|
|
9553
9957
|
|
|
9554
|
-
//
|
|
9958
|
+
// ../../../Decionis/apps/protocol/src/mcp/McpContracts.ts
|
|
9555
9959
|
var MCP_PROTOCOL_VERSIONS = [
|
|
9556
9960
|
"2025-11-25",
|
|
9557
9961
|
"2025-06-18",
|
|
@@ -9565,7 +9969,7 @@ var MCP_OAUTH_USER_EMAIL_ARGUMENT = "__decionis_oauth_user_email";
|
|
|
9565
9969
|
var DEFAULT_PUBLIC_BASE_URL = "https://protocol.decionis.com";
|
|
9566
9970
|
var MCP_HTTP_PATHS = ["/mcp", "/v1/protocol/mcp"];
|
|
9567
9971
|
|
|
9568
|
-
//
|
|
9972
|
+
// ../../../Decionis/apps/protocol/src/http/InternalAccessGuard.ts
|
|
9569
9973
|
import { timingSafeEqual } from "crypto";
|
|
9570
9974
|
var MCP_DISCOVERY_SUFFIXES = [
|
|
9571
9975
|
"/.well-known/oauth-protected-resource",
|
|
@@ -9657,7 +10061,7 @@ function registerInternalAccessGuard(app, env = process.env, tenantAuthLookup =
|
|
|
9657
10061
|
});
|
|
9658
10062
|
}
|
|
9659
10063
|
|
|
9660
|
-
//
|
|
10064
|
+
// ../../../Decionis/apps/protocol/src/http/InternalRouteInvoker.ts
|
|
9661
10065
|
function injectInternalProtocolRoute(app, input) {
|
|
9662
10066
|
const internalSecret = resolveInternalSecret();
|
|
9663
10067
|
return app.inject({
|
|
@@ -9671,7 +10075,7 @@ function injectInternalProtocolRoute(app, input) {
|
|
|
9671
10075
|
});
|
|
9672
10076
|
}
|
|
9673
10077
|
|
|
9674
|
-
//
|
|
10078
|
+
// ../../../Decionis/apps/protocol/src/mcp/McpSupport.ts
|
|
9675
10079
|
var McpSupport = class {
|
|
9676
10080
|
static asRecord(value) {
|
|
9677
10081
|
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
@@ -9783,10 +10187,11 @@ function withQuery(path, query) {
|
|
|
9783
10187
|
return McpSupport.withQuery(path, query);
|
|
9784
10188
|
}
|
|
9785
10189
|
|
|
9786
|
-
//
|
|
10190
|
+
// ../../../Decionis/apps/protocol/src/mcp/McpAuthGuard.ts
|
|
9787
10191
|
var orgScopedToolNames = /* @__PURE__ */ new Set([
|
|
9788
10192
|
"decionis.get_started",
|
|
9789
10193
|
"get_started",
|
|
10194
|
+
"explore",
|
|
9790
10195
|
"decionis.evaluate_decision",
|
|
9791
10196
|
"evaluate_decision",
|
|
9792
10197
|
"decionis.explain_decision",
|
|
@@ -9809,6 +10214,8 @@ var orgScopedToolNames = /* @__PURE__ */ new Set([
|
|
|
9809
10214
|
"list_enforcement_rollouts",
|
|
9810
10215
|
"decionis.upsert_enforcement_rollout",
|
|
9811
10216
|
"upsert_enforcement_rollout",
|
|
10217
|
+
"decionis.seed_policy_pack",
|
|
10218
|
+
"seed_policy_pack",
|
|
9812
10219
|
"decionis.resolve_vertical_pack",
|
|
9813
10220
|
"resolve_vertical_pack",
|
|
9814
10221
|
"decionis.run_shadow_decisioning",
|
|
@@ -9934,6 +10341,10 @@ var McpAuthGuard = class _McpAuthGuard {
|
|
|
9934
10341
|
if (!_McpAuthGuard.isOAuthClientAuth(auth)) return prompts;
|
|
9935
10342
|
return prompts.filter((prompt) => conversationalOAuthPromptNames.has(prompt.name));
|
|
9936
10343
|
}
|
|
10344
|
+
/** Whether an org API key is confined to its own organization for this tool. */
|
|
10345
|
+
static isOrgScopedTool(name) {
|
|
10346
|
+
return orgScopedToolNames.has(name);
|
|
10347
|
+
}
|
|
9937
10348
|
static findTargetOrgIdForTool(name, args) {
|
|
9938
10349
|
if (orgScopedToolNames.has(name)) {
|
|
9939
10350
|
return asString(args.org_id);
|
|
@@ -9984,6 +10395,9 @@ var McpAuthGuard = class _McpAuthGuard {
|
|
|
9984
10395
|
if (name === "decionis.upsert_enforcement_rollout" || name === "upsert_enforcement_rollout") {
|
|
9985
10396
|
return ["decision:write", "decision:*", "org:*"];
|
|
9986
10397
|
}
|
|
10398
|
+
if (name === "decionis.seed_policy_pack" || name === "seed_policy_pack") {
|
|
10399
|
+
return ["policy:write", "policy:*", "org:*"];
|
|
10400
|
+
}
|
|
9987
10401
|
return [];
|
|
9988
10402
|
}
|
|
9989
10403
|
static readAuthorizationForResource(uri) {
|
|
@@ -10090,10 +10504,10 @@ function authorizeResourceRead(auth, uri) {
|
|
|
10090
10504
|
return McpAuthGuard.authorizeResourceRead(auth, uri);
|
|
10091
10505
|
}
|
|
10092
10506
|
|
|
10093
|
-
//
|
|
10507
|
+
// ../../../Decionis/apps/protocol/src/mcp/McpRoutes.ts
|
|
10094
10508
|
import { createHash as createHash4, randomUUID as randomUUID2 } from "crypto";
|
|
10095
10509
|
|
|
10096
|
-
//
|
|
10510
|
+
// ../../../Decionis/packages/shared/src/Connectors/ConnectorRegistry.ts
|
|
10097
10511
|
var SITE = "https://decionis.com";
|
|
10098
10512
|
var connectors = [
|
|
10099
10513
|
// ── Commerce ──────────────────────────────────────────────────────────
|
|
@@ -10127,6 +10541,14 @@ var connectors = [
|
|
|
10127
10541
|
distribution: { download: false, guidedInstall: true, remoteInstall: false },
|
|
10128
10542
|
activation: { method: "marketplace_install", requiresWorkspace: true },
|
|
10129
10543
|
presenceSupport: "planned",
|
|
10544
|
+
failurePosture: {
|
|
10545
|
+
posture: "STRICT",
|
|
10546
|
+
whenUnavailable: "Checkout keeps enforcing the signed policy snapshot already pushed to the store, so an outage changes nothing until that snapshot expires after seven days. After that, or if the snapshot is missing, checkout is blocked.",
|
|
10547
|
+
configurable: 'Each rule has an "If Decionis is unreachable" setting in the app, fail closed by default.',
|
|
10548
|
+
ungovernedMarker: null,
|
|
10549
|
+
evidence: "decionis/Commerce: apps/shopify/extensions/*-hard-gate; app/lib/policies/RuleEnforcement.server.ts",
|
|
10550
|
+
knownGap: "Only the net-margin rule's setting reaches checkout today; the other rules' settings are stored but not applied. A product with no cost on file is margin-checked as if its cost were zero."
|
|
10551
|
+
},
|
|
10130
10552
|
marketplaceListingId: "shopify-app",
|
|
10131
10553
|
providerId: "SHOPIFY"
|
|
10132
10554
|
},
|
|
@@ -10161,6 +10583,14 @@ var connectors = [
|
|
|
10161
10583
|
distribution: { download: false, guidedInstall: true, remoteInstall: false },
|
|
10162
10584
|
activation: { method: "api_key", requiresWorkspace: true },
|
|
10163
10585
|
presenceSupport: "planned",
|
|
10586
|
+
failurePosture: {
|
|
10587
|
+
posture: "BOUNDED_CONTINUITY",
|
|
10588
|
+
whenUnavailable: "If the store cannot reach Decionis, checkout continues by default.",
|
|
10589
|
+
configurable: '"If Decionis is unreachable" in the plugin settings: fail open (the default) or fail closed.',
|
|
10590
|
+
ungovernedMarker: "The order records the decision as bypassed, with the reason.",
|
|
10591
|
+
evidence: "decionis/Commerce: connectors/woo/plugin/includes/checkout/RuntimeClient.php; includes/orders/DossierMetadata.php",
|
|
10592
|
+
knownGap: "An error inside the gate is still answered as allow, so the order proceeds even when fail closed is set. An order with no cost on file proceeds without a margin check."
|
|
10593
|
+
},
|
|
10164
10594
|
marketplaceTarget: "woo",
|
|
10165
10595
|
marketplaceListingId: "woo-plugin",
|
|
10166
10596
|
providerId: "WOO"
|
|
@@ -10177,7 +10607,7 @@ var connectors = [
|
|
|
10177
10607
|
vendor: "eBay",
|
|
10178
10608
|
category: "commerce",
|
|
10179
10609
|
status: "installable",
|
|
10180
|
-
summary: "Margin and
|
|
10610
|
+
summary: "Margin and promotion guardrails for your eBay listings, orders and promotions. Connect with eBay sign-in; it starts in Shadow Mode, with a signed Decision Dossier for every decision.",
|
|
10181
10611
|
capabilities: ["margin-guardrails", "promo-hygiene", "shadow-mode", "signed-decision-dossier"],
|
|
10182
10612
|
decisionsSupported: ["listing-change", "order-fulfillment", "promotion"],
|
|
10183
10613
|
installation: [
|
|
@@ -10196,6 +10626,13 @@ var connectors = [
|
|
|
10196
10626
|
distribution: { download: false, guidedInstall: true, remoteInstall: false },
|
|
10197
10627
|
activation: { method: "oauth", requiresWorkspace: true },
|
|
10198
10628
|
presenceSupport: "planned",
|
|
10629
|
+
failurePosture: {
|
|
10630
|
+
posture: "BOUNDED_CONTINUITY",
|
|
10631
|
+
whenUnavailable: "Listings are left as they are; the monitor never reprices or withdraws a listing without an answer.",
|
|
10632
|
+
configurable: null,
|
|
10633
|
+
ungovernedMarker: "The sweep result reports the listing as observed, with the enforcement error.",
|
|
10634
|
+
evidence: "decionis/Commerce: connectors/adapters/ebay/src/enforcement/Enforcer.ts; connectors/ebay/src/Monitor.ts"
|
|
10635
|
+
},
|
|
10199
10636
|
marketplaceTarget: "ebay",
|
|
10200
10637
|
providerId: "EBAY"
|
|
10201
10638
|
},
|
|
@@ -10248,6 +10685,14 @@ var connectors = [
|
|
|
10248
10685
|
distribution: { download: true, guidedInstall: false, remoteInstall: false },
|
|
10249
10686
|
activation: { method: "enrollment_token", requiresWorkspace: true },
|
|
10250
10687
|
presenceSupport: "planned",
|
|
10688
|
+
failurePosture: {
|
|
10689
|
+
posture: "BOUNDED_CONTINUITY",
|
|
10690
|
+
whenUnavailable: "Checkout continues: the Magento hook is optional with a two-second timeout, and an engine error is answered as success.",
|
|
10691
|
+
configurable: null,
|
|
10692
|
+
ungovernedMarker: "Log lines at checkout; the post-placement sweep records orders it could not check.",
|
|
10693
|
+
evidence: "decionis/Commerce: connectors/adobe/magento-module/etc/webhooks.xml; connectors/adobe/src/App.ts",
|
|
10694
|
+
knownGap: "A skipped checkout check is only logged, not stored as a decision record."
|
|
10695
|
+
},
|
|
10251
10696
|
marketplaceTarget: "adobe-commerce",
|
|
10252
10697
|
providerId: "ADOBE_COMMERCE"
|
|
10253
10698
|
},
|
|
@@ -10259,7 +10704,7 @@ var connectors = [
|
|
|
10259
10704
|
vendor: "Amazon",
|
|
10260
10705
|
category: "commerce",
|
|
10261
10706
|
status: "validated",
|
|
10262
|
-
summary: "Margin and pricing guardrails for Amazon
|
|
10707
|
+
summary: "Margin and pricing guardrails for your Amazon listings and orders. Connect with Login with Amazon; it starts in Shadow Mode.",
|
|
10263
10708
|
capabilities: ["margin-guardrails", "shadow-mode", "signed-decision-dossier"],
|
|
10264
10709
|
decisionsSupported: ["listing-change", "order"],
|
|
10265
10710
|
installation: [],
|
|
@@ -10267,6 +10712,13 @@ var connectors = [
|
|
|
10267
10712
|
distribution: { download: false, guidedInstall: false, remoteInstall: false },
|
|
10268
10713
|
activation: { method: "oauth", requiresWorkspace: true },
|
|
10269
10714
|
presenceSupport: "planned",
|
|
10715
|
+
failurePosture: {
|
|
10716
|
+
posture: "OBSERVE_ONLY",
|
|
10717
|
+
whenUnavailable: "Amazon has no way to hold an order, so Commerce Gate records decisions only. During an outage the order ships untouched.",
|
|
10718
|
+
configurable: null,
|
|
10719
|
+
ungovernedMarker: "The sweep is recorded as failed.",
|
|
10720
|
+
evidence: "decionis/Commerce: connectors/amazon/src/orders/AmazonOrderGate.ts"
|
|
10721
|
+
},
|
|
10270
10722
|
marketplaceTarget: "amazon",
|
|
10271
10723
|
providerId: "AMAZON"
|
|
10272
10724
|
},
|
|
@@ -10288,6 +10740,14 @@ var connectors = [
|
|
|
10288
10740
|
distribution: { download: false, guidedInstall: false, remoteInstall: false },
|
|
10289
10741
|
activation: { method: "oauth", requiresWorkspace: true },
|
|
10290
10742
|
presenceSupport: "planned",
|
|
10743
|
+
failurePosture: {
|
|
10744
|
+
posture: "BOUNDED_CONTINUITY",
|
|
10745
|
+
whenUnavailable: "Orders are released without a margin check, after the buyer-remorse hold where one applies.",
|
|
10746
|
+
configurable: null,
|
|
10747
|
+
ungovernedMarker: null,
|
|
10748
|
+
evidence: "decionis/Commerce: connectors/tiktok/src/interception/OrderInterceptor.ts",
|
|
10749
|
+
knownGap: "Nothing is stored for an order released this way, and the returned detail reads as a missing cost rather than an outage."
|
|
10750
|
+
},
|
|
10291
10751
|
marketplaceTarget: "tiktok",
|
|
10292
10752
|
providerId: "TIKTOK_SHOP"
|
|
10293
10753
|
},
|
|
@@ -10296,19 +10756,46 @@ var connectors = [
|
|
|
10296
10756
|
// verification, margin gate, Acknowledge-Order release/hold — built and
|
|
10297
10757
|
// unit-tested; Solution Provider approval and live seller verification
|
|
10298
10758
|
// remain (shared readiness provenance).
|
|
10759
|
+
// Approved Walmart Marketplace Solution Provider (Specialty Partner —
|
|
10760
|
+
// Orders) with the Decionis Commerce Gate app reviewed and published in
|
|
10761
|
+
// the Seller Center App Store on 2026-09-16 (Walmart's notices). The
|
|
10762
|
+
// Sellers install it in one click from the listing; Walmart sends them to
|
|
10763
|
+
// the registered App Login URL and they authorize the app. The listing
|
|
10764
|
+
// sits behind a seller login and no public directory page exists (checked
|
|
10765
|
+
// 2026-09-22), so the channel names Seller Center itself — which resolves
|
|
10766
|
+
// publicly to Walmart's seller sign-in — and the listing by its name.
|
|
10299
10767
|
slug: "walmart",
|
|
10300
|
-
name: "Decionis for Walmart Marketplace",
|
|
10768
|
+
name: "Decionis Commerce Gate for Walmart Marketplace",
|
|
10301
10769
|
vendor: "Walmart",
|
|
10302
10770
|
category: "commerce",
|
|
10303
|
-
status: "
|
|
10304
|
-
summary: "
|
|
10771
|
+
status: "installable",
|
|
10772
|
+
summary: "Stop loss-making Walmart orders before you acknowledge them: every purchase order clears a margin check (cost of goods, referral fee and shipping) first. Install Decionis Commerce Gate in one click from the Seller Center App Store.",
|
|
10305
10773
|
capabilities: ["fulfillment-circuit-breaker", "margin-guardrails", "signed-decision-dossier"],
|
|
10306
10774
|
decisionsSupported: ["order-acknowledgement"],
|
|
10307
|
-
installation: [
|
|
10775
|
+
installation: [
|
|
10776
|
+
{
|
|
10777
|
+
kind: "marketplace",
|
|
10778
|
+
url: "https://seller.walmart.com/",
|
|
10779
|
+
label: "Walmart Marketplace App Store in Seller Center (seller login): Decionis Commerce Gate \u2014 Policy Controls for Walmart Marketplace"
|
|
10780
|
+
}
|
|
10781
|
+
],
|
|
10308
10782
|
documentation: `${SITE}/marketplace/walmart`,
|
|
10783
|
+
verification: {
|
|
10784
|
+
validatedBy: "Walmart Marketplace (Solution Provider approval; app review and publication)",
|
|
10785
|
+
evidence: "Decionis, Inc. approved as a Walmart Marketplace Solution Provider (Specialty Partner \u2014 Orders) and the Decionis Commerce Gate app validated by the Developer Portal review and published to the Seller Center App Store, all on 2026-09-16 per Walmart's notices. Sellers install it in one click from the listing. The listing is inside Seller Center (seller login); no public directory page on 2026-09-22.",
|
|
10786
|
+
lastValidated: "2026-09-16"
|
|
10787
|
+
},
|
|
10309
10788
|
distribution: { download: false, guidedInstall: false, remoteInstall: false },
|
|
10310
|
-
activation: { method: "
|
|
10789
|
+
activation: { method: "marketplace_install", requiresWorkspace: true },
|
|
10311
10790
|
presenceSupport: "planned",
|
|
10791
|
+
failurePosture: {
|
|
10792
|
+
posture: "BOUNDED_CONTINUITY",
|
|
10793
|
+
whenUnavailable: "Orders are acknowledged without a margin check. Refunds up to the fallback limit proceed, and larger refunds are held until the check is back.",
|
|
10794
|
+
configurable: "The refund fallback limit is set per deployment (1,000 by default); order acknowledgment behaviour is fixed.",
|
|
10795
|
+
ungovernedMarker: "Order Guard records the order as released without a margin check.",
|
|
10796
|
+
evidence: "decionis/Commerce: connectors/walmart/src/interception/OrderInterceptor.ts; src/policy/RefundPolicyGate.ts",
|
|
10797
|
+
knownGap: "An engine fault is recorded with the same wording as a missing cost, and the refund record does not say the fallback limit was used."
|
|
10798
|
+
},
|
|
10312
10799
|
marketplaceTarget: "walmart",
|
|
10313
10800
|
providerId: "WALMART_MARKETPLACE"
|
|
10314
10801
|
},
|
|
@@ -10330,6 +10817,13 @@ var connectors = [
|
|
|
10330
10817
|
distribution: { download: false, guidedInstall: false, remoteInstall: false },
|
|
10331
10818
|
activation: { method: "oauth", requiresWorkspace: true },
|
|
10332
10819
|
presenceSupport: "planned",
|
|
10820
|
+
failurePosture: {
|
|
10821
|
+
posture: "STRICT",
|
|
10822
|
+
whenUnavailable: "Commerce Gate does not release the order; it stays in the seller's own Jumia workflow.",
|
|
10823
|
+
configurable: "release_mode decides whether Commerce Gate releases orders at all (advisory by default).",
|
|
10824
|
+
ungovernedMarker: "The intercept is recorded as observed, or as failed when a release attempt fails.",
|
|
10825
|
+
evidence: "decionis/Commerce: connectors/jumia/src/interception/OrderInterceptor.ts; connectors/adapters/jumia/src/settings/JumiaSettings.ts"
|
|
10826
|
+
},
|
|
10333
10827
|
marketplaceTarget: "jumia",
|
|
10334
10828
|
providerId: "JUMIA"
|
|
10335
10829
|
},
|
|
@@ -10341,7 +10835,7 @@ var connectors = [
|
|
|
10341
10835
|
vendor: "BigCommerce",
|
|
10342
10836
|
category: "commerce",
|
|
10343
10837
|
status: "validated",
|
|
10344
|
-
summary: "Checkout margin gate for BigCommerce headless and Open Checkout storefronts
|
|
10838
|
+
summary: "Checkout margin gate for BigCommerce headless and Open Checkout storefronts. It fails open, so an engine error never blocks a sale.",
|
|
10345
10839
|
capabilities: ["margin-floor-enforcement", "checkout-policy-enforcement"],
|
|
10346
10840
|
decisionsSupported: ["checkout-order"],
|
|
10347
10841
|
installation: [],
|
|
@@ -10349,6 +10843,14 @@ var connectors = [
|
|
|
10349
10843
|
distribution: { download: false, guidedInstall: false, remoteInstall: false },
|
|
10350
10844
|
activation: { method: "api_key", requiresWorkspace: true },
|
|
10351
10845
|
presenceSupport: "planned",
|
|
10846
|
+
failurePosture: {
|
|
10847
|
+
posture: "BOUNDED_CONTINUITY",
|
|
10848
|
+
whenUnavailable: "An engine error is answered as allow and the order proceeds.",
|
|
10849
|
+
configurable: null,
|
|
10850
|
+
ungovernedMarker: "The response says bypassed; nothing is stored.",
|
|
10851
|
+
evidence: "decionis/Commerce: connectors/bigcommerce/src/App.ts",
|
|
10852
|
+
knownGap: "How the storefront handles a timeout is outside the connector repository and is not stated here."
|
|
10853
|
+
},
|
|
10352
10854
|
marketplaceTarget: "bigcommerce"
|
|
10353
10855
|
},
|
|
10354
10856
|
{
|
|
@@ -10360,7 +10862,7 @@ var connectors = [
|
|
|
10360
10862
|
vendor: "Shopware",
|
|
10361
10863
|
category: "commerce",
|
|
10362
10864
|
status: "validated",
|
|
10363
|
-
summary: "Fail-open
|
|
10865
|
+
summary: "Fail-open checkout gate for Shopware 6, with signed webhooks and promotion checks.",
|
|
10364
10866
|
capabilities: [
|
|
10365
10867
|
"margin-floor-enforcement",
|
|
10366
10868
|
"checkout-policy-enforcement",
|
|
@@ -10373,22 +10875,34 @@ var connectors = [
|
|
|
10373
10875
|
distribution: { download: false, guidedInstall: false, remoteInstall: false },
|
|
10374
10876
|
activation: { method: "api_key", requiresWorkspace: true },
|
|
10375
10877
|
presenceSupport: "planned",
|
|
10878
|
+
failurePosture: {
|
|
10879
|
+
posture: "BOUNDED_CONTINUITY",
|
|
10880
|
+
whenUnavailable: "An engine error is answered as allow and the order proceeds.",
|
|
10881
|
+
configurable: null,
|
|
10882
|
+
ungovernedMarker: "The response says bypassed; nothing is stored.",
|
|
10883
|
+
evidence: "decionis/Commerce: connectors/shopware/src/App.ts",
|
|
10884
|
+
knownGap: "How the storefront handles a timeout is outside the connector repository and is not stated here."
|
|
10885
|
+
},
|
|
10376
10886
|
marketplaceTarget: "shopware"
|
|
10377
10887
|
},
|
|
10378
10888
|
// ── Enterprise ────────────────────────────────────────────────────────
|
|
10379
10889
|
{
|
|
10380
10890
|
// SAP PartnerEdge Solution Review approved 2026-06-22 (solution id
|
|
10381
|
-
// 2004368
|
|
10891
|
+
// 2004368; listing evidence now lives in decionis/Commerce
|
|
10892
|
+
// docs/marketplace/sap/solution-hub-listing.md). The PartnerEdge
|
|
10382
10893
|
// solution URL is partner-gated (anonymous fetch 404s — sweep
|
|
10383
|
-
// 2026-08-10), so it is deliberately NOT an install channel here
|
|
10384
|
-
// customer-deployable BTP
|
|
10385
|
-
//
|
|
10894
|
+
// 2026-08-10), so it is deliberately NOT an install channel here.
|
|
10895
|
+
// The CAP application and the customer-deployable BTP kit are
|
|
10896
|
+
// Commerce-owned (decionis/Commerce apps/sap + commerce-dashboard): the
|
|
10897
|
+
// decionis.com channel URLs below 301 to commerce.decionis.com like every
|
|
10898
|
+
// other Commerce-owned row, and this repo no longer ships the kit
|
|
10899
|
+
// artifacts or pins their version (drift-gated in Commerce, not here).
|
|
10900
|
+
// Dual-gate wording from the owning listing copy.
|
|
10386
10901
|
slug: "sap",
|
|
10387
10902
|
name: "Decionis Governed Execution Gate for SAP",
|
|
10388
10903
|
vendor: "SAP",
|
|
10389
10904
|
category: "enterprise",
|
|
10390
10905
|
status: "validated",
|
|
10391
|
-
version: "0.1.0",
|
|
10392
10906
|
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.",
|
|
10393
10907
|
capabilities: [
|
|
10394
10908
|
"dual-gate-execution",
|
|
@@ -10405,29 +10919,31 @@ var connectors = [
|
|
|
10405
10919
|
installation: [
|
|
10406
10920
|
{
|
|
10407
10921
|
// Customer-deployed BTP kit (curated CAP source, mbt build →
|
|
10408
|
-
// cf deploy)
|
|
10409
|
-
//
|
|
10922
|
+
// cf deploy). The kit page, zip, checksum, manifest and SBOM are
|
|
10923
|
+
// served by Commerce; this URL resolves through the reviewed 301 in
|
|
10924
|
+
// CommerceOwnership.mjs (rule 1.1 by redirect, not by local file).
|
|
10410
10925
|
kind: "hosted_download",
|
|
10411
10926
|
url: `${SITE}/marketplace/sap/deployment-kit`,
|
|
10412
10927
|
label: "SAP BTP deployment kit (customer-deployed)"
|
|
10413
10928
|
}
|
|
10414
10929
|
],
|
|
10415
|
-
package: {
|
|
10416
|
-
artifact: "/marketplace/sap/deployment-kit/decionis-sap-deployment-kit-0.1.0.zip",
|
|
10417
|
-
sha256Path: "/marketplace/sap/deployment-kit/decionis-sap-deployment-kit-0.1.0.sha256.txt",
|
|
10418
|
-
manifestPath: "/marketplace/sap/deployment-kit/manifest.json",
|
|
10419
|
-
sbomPath: "/marketplace/sap/deployment-kit/SBOM.json",
|
|
10420
|
-
format: "sap-mta-deployment-kit"
|
|
10421
|
-
},
|
|
10422
10930
|
documentation: `${SITE}/marketplace/sap`,
|
|
10423
10931
|
verification: {
|
|
10424
10932
|
validatedBy: "SAP PartnerEdge Solution Review",
|
|
10425
|
-
evidence: "Solution Review completed and approved
|
|
10933
|
+
evidence: "SAP PartnerEdge Solution Review completed and approved on 22 June 2026 (solution 2004368).",
|
|
10426
10934
|
lastValidated: "2026-06-22"
|
|
10427
10935
|
},
|
|
10428
10936
|
distribution: { download: true, guidedInstall: false, remoteInstall: false },
|
|
10429
10937
|
activation: { method: "enrollment_token", requiresWorkspace: true },
|
|
10430
10938
|
presenceSupport: "planned",
|
|
10939
|
+
failurePosture: {
|
|
10940
|
+
posture: "CUSTOM",
|
|
10941
|
+
whenUnavailable: "If the Decionis gate cannot be reached, a local fallback gate decides with fixed rules (allow, block, delay or escalate), and a request missing required fields is blocked.",
|
|
10942
|
+
configurable: "Set DECIONIS_PROTOCOL_FAIL_CLOSED=1 to block instead.",
|
|
10943
|
+
ungovernedMarker: "The dossier is marked federated: false, with a local id.",
|
|
10944
|
+
evidence: "decionis/Commerce: apps/sap/srv/decionis-client.js; apps/sap/docs/runtime-config.md",
|
|
10945
|
+
knownGap: "The call to the Decionis gate has no timeout."
|
|
10946
|
+
},
|
|
10431
10947
|
providerId: "SAP"
|
|
10432
10948
|
},
|
|
10433
10949
|
{
|
|
@@ -10466,6 +10982,13 @@ var connectors = [
|
|
|
10466
10982
|
distribution: { download: false, guidedInstall: false, remoteInstall: false },
|
|
10467
10983
|
activation: { method: "enrollment_token", requiresWorkspace: true },
|
|
10468
10984
|
presenceSupport: "planned",
|
|
10985
|
+
failurePosture: {
|
|
10986
|
+
posture: "STRICT",
|
|
10987
|
+
whenUnavailable: "The governed Flow action stops and downstream updates are halted, in every mode. The shadow observers only record, after the record is saved.",
|
|
10988
|
+
configurable: null,
|
|
10989
|
+
ungovernedMarker: null,
|
|
10990
|
+
evidence: "apps/servicenow/app/script-includes/DecionisControlPlaneUtils.script.js; DecionisVerifyIntentAction.script.js"
|
|
10991
|
+
},
|
|
10469
10992
|
marketplaceTarget: "servicenow",
|
|
10470
10993
|
providerId: "SERVICENOW"
|
|
10471
10994
|
},
|
|
@@ -10479,7 +11002,7 @@ var connectors = [
|
|
|
10479
11002
|
vendor: "Salesforce",
|
|
10480
11003
|
category: "enterprise",
|
|
10481
11004
|
status: "installable",
|
|
10482
|
-
summary: "
|
|
11005
|
+
summary: "Check Salesforce Flow, Apex and Agentforce actions before they run (allow, hold or escalate), with signed Decision Dossiers on the record. Install the starter package in your org; it starts in Shadow Mode.",
|
|
10483
11006
|
capabilities: [
|
|
10484
11007
|
"pre-execution-action-gate",
|
|
10485
11008
|
"shadow-mode",
|
|
@@ -10503,6 +11026,13 @@ var connectors = [
|
|
|
10503
11026
|
distribution: { download: true, guidedInstall: false, remoteInstall: false },
|
|
10504
11027
|
activation: { method: "api_key", requiresWorkspace: true },
|
|
10505
11028
|
presenceSupport: "planned",
|
|
11029
|
+
failurePosture: {
|
|
11030
|
+
posture: "CUSTOM",
|
|
11031
|
+
whenUnavailable: "The action returns an error message and no decision. A Flow that requires continueAction to be true stops; a Flow that does not check it continues.",
|
|
11032
|
+
configurable: "Your Flow's condition on continueAction.",
|
|
11033
|
+
ungovernedMarker: "errorMessage is set and continueAction is empty.",
|
|
11034
|
+
evidence: "docs/marketplace/salesforce/starter-package/force-app/main/default/classes/DecionisActionGate.cls"
|
|
11035
|
+
},
|
|
10506
11036
|
marketplaceTarget: "salesforce",
|
|
10507
11037
|
marketplaceListingId: "salesforce-app",
|
|
10508
11038
|
providerId: "SALESFORCE"
|
|
@@ -10530,6 +11060,13 @@ var connectors = [
|
|
|
10530
11060
|
distribution: { download: false, guidedInstall: true, remoteInstall: false },
|
|
10531
11061
|
activation: { method: "oauth", requiresWorkspace: true },
|
|
10532
11062
|
presenceSupport: "planned",
|
|
11063
|
+
failurePosture: {
|
|
11064
|
+
posture: "STRICT",
|
|
11065
|
+
whenUnavailable: "The step retries once, then Zapier replays it; later steps in the Zap do not run until Decionis answers.",
|
|
11066
|
+
configurable: null,
|
|
11067
|
+
ungovernedMarker: null,
|
|
11068
|
+
evidence: "packages/zapier-decionis/creates/DecisionDossierClient.js"
|
|
11069
|
+
},
|
|
10533
11070
|
marketplaceListingId: "zapier"
|
|
10534
11071
|
},
|
|
10535
11072
|
{
|
|
@@ -10555,31 +11092,45 @@ var connectors = [
|
|
|
10555
11092
|
documentation: `${SITE}/docs/automation-connectors#make`,
|
|
10556
11093
|
distribution: { download: false, guidedInstall: false, remoteInstall: false },
|
|
10557
11094
|
activation: { method: "oauth", requiresWorkspace: true },
|
|
10558
|
-
presenceSupport: "planned"
|
|
11095
|
+
presenceSupport: "planned",
|
|
11096
|
+
failurePosture: {
|
|
11097
|
+
posture: "CUSTOM",
|
|
11098
|
+
whenUnavailable: "Make connects through its HTTP module. Decionis answers 502, and your scenario's error handling decides whether the next module runs.",
|
|
11099
|
+
configurable: "The error handler on your scenario's HTTP module.",
|
|
11100
|
+
ungovernedMarker: null,
|
|
11101
|
+
evidence: "apps/web/app/docs/automation-connectors/page.tsx (Make recipe); apps/api/src/routes/ProtocolRoutes.ts"
|
|
11102
|
+
}
|
|
10559
11103
|
},
|
|
10560
11104
|
{
|
|
10561
|
-
//
|
|
10562
|
-
// n8n
|
|
11105
|
+
// The n8n community node (n8n-nodes-decionis) was retired on 2026-09-26.
|
|
11106
|
+
// n8n stays a recipe: an HTTP Request node calls the same gate, and the
|
|
11107
|
+
// four example workflows under /examples/n8n use only built-in nodes.
|
|
10563
11108
|
slug: "n8n",
|
|
10564
11109
|
name: "Decionis for n8n",
|
|
10565
11110
|
vendor: "n8n",
|
|
10566
11111
|
category: "automation",
|
|
10567
|
-
status: "
|
|
10568
|
-
|
|
10569
|
-
summary: "Every automation step asks permission before it executes \u2014 install the n8n community node from npm, or start from the HTTP Request recipe and four importable example workflows.",
|
|
11112
|
+
status: "installable",
|
|
11113
|
+
summary: "Every automation step asks permission before it executes \u2014 add an HTTP Request node before the protected step, or start from four importable example workflows that use only built-in nodes.",
|
|
10570
11114
|
capabilities: ["automation-step-governance", "signed-decision-dossier"],
|
|
10571
11115
|
decisionsSupported: ["automation-step"],
|
|
10572
11116
|
installation: [
|
|
10573
11117
|
{
|
|
10574
|
-
kind: "
|
|
10575
|
-
url:
|
|
10576
|
-
label: "
|
|
11118
|
+
kind: "docs",
|
|
11119
|
+
url: `${SITE}/docs/automation-connectors#n8n`,
|
|
11120
|
+
label: "HTTP Request recipe and example workflows"
|
|
10577
11121
|
}
|
|
10578
11122
|
],
|
|
10579
11123
|
documentation: `${SITE}/docs/automation-connectors#n8n`,
|
|
10580
11124
|
distribution: { download: false, guidedInstall: false, remoteInstall: false },
|
|
10581
11125
|
activation: { method: "api_key", requiresWorkspace: true },
|
|
10582
|
-
presenceSupport: "planned"
|
|
11126
|
+
presenceSupport: "planned",
|
|
11127
|
+
failurePosture: {
|
|
11128
|
+
posture: "CUSTOM",
|
|
11129
|
+
whenUnavailable: "n8n connects through its HTTP Request node. Decionis answers 502, and your workflow's error handling decides whether the next node runs.",
|
|
11130
|
+
configurable: "The HTTP Request node's On Error setting, and the IF branch on the outcome.",
|
|
11131
|
+
ungovernedMarker: null,
|
|
11132
|
+
evidence: "apps/web/app/docs/automation-connectors/page.tsx (n8n recipe); apps/api/src/routes/ProtocolRoutes.ts"
|
|
11133
|
+
}
|
|
10583
11134
|
},
|
|
10584
11135
|
// ── Platform ──────────────────────────────────────────────────────────
|
|
10585
11136
|
{
|
|
@@ -10604,6 +11155,13 @@ var connectors = [
|
|
|
10604
11155
|
distribution: { download: false, guidedInstall: false, remoteInstall: false },
|
|
10605
11156
|
activation: { method: "api_key", requiresWorkspace: true },
|
|
10606
11157
|
presenceSupport: "planned",
|
|
11158
|
+
failurePosture: {
|
|
11159
|
+
posture: "OBSERVE_ONLY",
|
|
11160
|
+
whenUnavailable: "Webhooks carry signals in and decisions out; they never hold an action themselves. Senders should retry 5xx answers and timeouts with backoff.",
|
|
11161
|
+
configurable: null,
|
|
11162
|
+
ungovernedMarker: null,
|
|
11163
|
+
evidence: "apps/web/app/docs/webhooks/page.tsx"
|
|
11164
|
+
},
|
|
10607
11165
|
providerId: "WEBHOOK"
|
|
10608
11166
|
},
|
|
10609
11167
|
{
|
|
@@ -10627,10 +11185,17 @@ var connectors = [
|
|
|
10627
11185
|
label: "Docker Hub"
|
|
10628
11186
|
}
|
|
10629
11187
|
],
|
|
10630
|
-
documentation:
|
|
11188
|
+
documentation: "https://decionis.ai/mcp",
|
|
10631
11189
|
distribution: { download: false, guidedInstall: true, remoteInstall: false },
|
|
10632
11190
|
activation: { method: "enrollment_token", requiresWorkspace: true },
|
|
10633
|
-
presenceSupport: "planned"
|
|
11191
|
+
presenceSupport: "planned",
|
|
11192
|
+
failurePosture: {
|
|
11193
|
+
posture: "OBSERVE_ONLY",
|
|
11194
|
+
whenUnavailable: "The extension shows decisions and verifies records offline; it does not hold container actions.",
|
|
11195
|
+
configurable: null,
|
|
11196
|
+
ungovernedMarker: null,
|
|
11197
|
+
evidence: "Registry scope (visibility and offline verification); extension source at github.com/decionis/docker"
|
|
11198
|
+
}
|
|
10634
11199
|
// No providerId: like zapier/make, this surface connects through
|
|
10635
11200
|
// connector_enrollments, never an org_integrations row.
|
|
10636
11201
|
},
|
|
@@ -10659,14 +11224,21 @@ var connectors = [
|
|
|
10659
11224
|
},
|
|
10660
11225
|
{
|
|
10661
11226
|
kind: "docs",
|
|
10662
|
-
url:
|
|
11227
|
+
url: "https://decionis.ai/mcp#hosted",
|
|
10663
11228
|
label: "Hosted connector guide"
|
|
10664
11229
|
}
|
|
10665
11230
|
],
|
|
10666
|
-
documentation:
|
|
11231
|
+
documentation: "https://decionis.ai/mcp",
|
|
10667
11232
|
distribution: { download: false, guidedInstall: true, remoteInstall: false },
|
|
10668
11233
|
activation: { method: "oauth", requiresWorkspace: true },
|
|
10669
|
-
presenceSupport: "planned"
|
|
11234
|
+
presenceSupport: "planned",
|
|
11235
|
+
failurePosture: {
|
|
11236
|
+
posture: "OBSERVE_ONLY",
|
|
11237
|
+
whenUnavailable: "The connector never runs the action itself. If Decionis cannot answer, the tool returns an error and no authority card; what the assistant does next is up to the assistant and you.",
|
|
11238
|
+
configurable: null,
|
|
11239
|
+
ungovernedMarker: "The tool result is marked as an error.",
|
|
11240
|
+
evidence: "apps/protocol/src/mcp/McpTools.ts"
|
|
11241
|
+
}
|
|
10670
11242
|
},
|
|
10671
11243
|
{
|
|
10672
11244
|
// ChatGPT connects through the same hosted MCP OAuth connector: the
|
|
@@ -10694,14 +11266,67 @@ var connectors = [
|
|
|
10694
11266
|
},
|
|
10695
11267
|
{
|
|
10696
11268
|
kind: "docs",
|
|
10697
|
-
url:
|
|
11269
|
+
url: "https://decionis.ai/mcp#hosted",
|
|
10698
11270
|
label: "Hosted connector guide"
|
|
10699
11271
|
}
|
|
10700
11272
|
],
|
|
10701
|
-
documentation:
|
|
11273
|
+
documentation: "https://decionis.ai/mcp",
|
|
10702
11274
|
distribution: { download: false, guidedInstall: true, remoteInstall: false },
|
|
10703
11275
|
activation: { method: "oauth", requiresWorkspace: true },
|
|
10704
|
-
presenceSupport: "planned"
|
|
11276
|
+
presenceSupport: "planned",
|
|
11277
|
+
failurePosture: {
|
|
11278
|
+
posture: "OBSERVE_ONLY",
|
|
11279
|
+
whenUnavailable: "The connector never runs the action itself. If Decionis cannot answer, the tool returns an error and no authority card; what the assistant does next is up to the assistant and you.",
|
|
11280
|
+
configurable: null,
|
|
11281
|
+
ungovernedMarker: "The tool result is marked as an error.",
|
|
11282
|
+
evidence: "apps/protocol/src/mcp/McpTools.ts"
|
|
11283
|
+
}
|
|
11284
|
+
},
|
|
11285
|
+
{
|
|
11286
|
+
// Not a vendor connector: the Node SDK's AuthZEN input adapter, which
|
|
11287
|
+
// carries an enterprise policy decision point's answer into evaluation
|
|
11288
|
+
// as a material signal. `validated` = exercised against a real AuthZEN
|
|
11289
|
+
// 1.0 PDP (Cerbos PDP 0.55.0) on 2026-09-22 with the exchange recorded
|
|
11290
|
+
// and replayed through the starter bundle. The npm channel was added
|
|
11291
|
+
// once @decionis/sdk 0.3.0 (the first version carrying the provider)
|
|
11292
|
+
// was confirmed on the registry: published 2026-09-22T07:23Z, tarball
|
|
11293
|
+
// shasum 37d6915a7a7e273eb51f4baa7b67987d62595b3f.
|
|
11294
|
+
slug: "authzen",
|
|
11295
|
+
name: "AuthZEN input adapter (Node SDK)",
|
|
11296
|
+
vendor: "OpenID AuthZEN 1.0 policy decision points",
|
|
11297
|
+
category: "platform",
|
|
11298
|
+
status: "validated",
|
|
11299
|
+
summary: "Carry an enterprise policy decision point's OpenID AuthZEN 1.0 answer into a Decionis evaluation as a material signal: the PDP decides access, Decionis decides whether this exact execution has authority, and the answer travels inside the signed inputs snapshot.",
|
|
11300
|
+
capabilities: [
|
|
11301
|
+
"upstream-authorization-signal",
|
|
11302
|
+
"authzen-1-0-evaluation",
|
|
11303
|
+
"allow-listed-discovery",
|
|
11304
|
+
"signed-decision-dossier"
|
|
11305
|
+
],
|
|
11306
|
+
decisionsSupported: ["any-evaluate-decision-request", "payment.release (starter bundle)"],
|
|
11307
|
+
installation: [
|
|
11308
|
+
{
|
|
11309
|
+
kind: "npm",
|
|
11310
|
+
url: "https://www.npmjs.com/package/@decionis/sdk",
|
|
11311
|
+
label: "npm install @decionis/sdk (0.3.0 or later)"
|
|
11312
|
+
}
|
|
11313
|
+
],
|
|
11314
|
+
documentation: `${SITE}/docs/authzen-interoperability`,
|
|
11315
|
+
verification: {
|
|
11316
|
+
validatedBy: "Decionis engineering (recorded interoperability run, self-attested)",
|
|
11317
|
+
evidence: "AuthZEN 1.0 discovery and evaluation against Cerbos PDP 0.55.0 recorded on 2026-09-22 (packages/sdk-node/test/fixtures/authzen-cerbos-interop.json) and replayed verbatim through the starter bundle by apps/protocol/test/UpstreamAuthorizationRecordedPdp.test.ts: permit \u2192 ALLOW within the desk limit / ESCALATE above it, deny \u2192 BLOCK; SDK and Protocol digests agree on the real material. Cerbos is the decision point used, not a partner. The provider ships in @decionis/sdk 0.3.0, on npm since 2026-09-22.",
|
|
11318
|
+
lastValidated: "2026-09-22"
|
|
11319
|
+
},
|
|
11320
|
+
distribution: { download: false, guidedInstall: false, remoteInstall: false },
|
|
11321
|
+
activation: { method: "api_key", requiresWorkspace: true },
|
|
11322
|
+
presenceSupport: "planned",
|
|
11323
|
+
failurePosture: {
|
|
11324
|
+
posture: "CUSTOM",
|
|
11325
|
+
whenUnavailable: "AuthZEN feeds Decionis a signal; it is not a gate. If Decionis is down, the SDK call it feeds decides, strict by default. If your PDP is down, no signal is sent and your policy's rule for a missing signal applies; the starter policy holds the action for review.",
|
|
11326
|
+
configurable: "required_signals and on_failure in your policy, and the PDP timeout (five seconds by default).",
|
|
11327
|
+
ungovernedMarker: null,
|
|
11328
|
+
evidence: "packages/sdk-node/src/AuthZenEntitlementProvider.ts; docs/architecture/authzen-input-adapter.md"
|
|
11329
|
+
}
|
|
10705
11330
|
}
|
|
10706
11331
|
];
|
|
10707
11332
|
var ConnectorRegistry = class {
|
|
@@ -10723,7 +11348,36 @@ var CONNECTOR_REGISTRY = ConnectorRegistry.connectors;
|
|
|
10723
11348
|
var getConnector = ConnectorRegistry.bySlug;
|
|
10724
11349
|
var CONNECTOR_SLUGS = ConnectorRegistry.slugs();
|
|
10725
11350
|
|
|
10726
|
-
//
|
|
11351
|
+
// ../../../Decionis/packages/shared/src/Connectors/FailurePosture.ts
|
|
11352
|
+
var FAILURE_POSTURES = {
|
|
11353
|
+
STRICT: {
|
|
11354
|
+
label: "Strict",
|
|
11355
|
+
meaning: "If Decionis cannot be reached, the action does not run. It is refused or held until an evaluation can happen.",
|
|
11356
|
+
appropriateFor: [
|
|
11357
|
+
"Payments and treasury releases",
|
|
11358
|
+
"Privileged infrastructure changes",
|
|
11359
|
+
"Machine-initiated actions with no natural limit on loss"
|
|
11360
|
+
]
|
|
11361
|
+
},
|
|
11362
|
+
BOUNDED_CONTINUITY: {
|
|
11363
|
+
label: "Bounded continuity",
|
|
11364
|
+
meaning: "If Decionis cannot be reached, the action may continue without an evaluation. It is ungoverned, not approved, and it is available only where a surface was configured for it.",
|
|
11365
|
+
appropriateFor: ["A shopper at checkout, where the exposure per order is small and bounded"]
|
|
11366
|
+
},
|
|
11367
|
+
CUSTOM: {
|
|
11368
|
+
label: "Custom",
|
|
11369
|
+
meaning: "The institution sets the behaviour per rule or per signal, for example holding an action for review when one input is unavailable.",
|
|
11370
|
+
appropriateFor: ["Institution-defined rules"]
|
|
11371
|
+
}
|
|
11372
|
+
};
|
|
11373
|
+
var SURFACE_POSTURE_LABEL = {
|
|
11374
|
+
STRICT: FAILURE_POSTURES.STRICT.label,
|
|
11375
|
+
BOUNDED_CONTINUITY: FAILURE_POSTURES.BOUNDED_CONTINUITY.label,
|
|
11376
|
+
CUSTOM: FAILURE_POSTURES.CUSTOM.label,
|
|
11377
|
+
OBSERVE_ONLY: "Observe only"
|
|
11378
|
+
};
|
|
11379
|
+
|
|
11380
|
+
// ../../../Decionis/apps/protocol/src/mcp/McpResources.ts
|
|
10727
11381
|
var McpResources = class {
|
|
10728
11382
|
static buildStaticResources(publicBaseUrl, serviceName, serviceVersion) {
|
|
10729
11383
|
return [
|
|
@@ -11086,7 +11740,7 @@ function readResource(app, uri, options) {
|
|
|
11086
11740
|
return McpResources.readResource(app, uri, options);
|
|
11087
11741
|
}
|
|
11088
11742
|
|
|
11089
|
-
//
|
|
11743
|
+
// ../../../Decionis/apps/protocol/src/mcp/McpPrompts.ts
|
|
11090
11744
|
var McpPrompts = class {
|
|
11091
11745
|
static buildPrompts(publicBaseUrl, authDescription) {
|
|
11092
11746
|
return [
|
|
@@ -11422,7 +12076,7 @@ function buildPrompts(publicBaseUrl, authDescription) {
|
|
|
11422
12076
|
return McpPrompts.buildPrompts(publicBaseUrl, authDescription);
|
|
11423
12077
|
}
|
|
11424
12078
|
|
|
11425
|
-
//
|
|
12079
|
+
// ../../../Decionis/apps/protocol/src/support/Parsing.ts
|
|
11426
12080
|
var Parsing = class {
|
|
11427
12081
|
static asRecord(value) {
|
|
11428
12082
|
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
@@ -11517,7 +12171,7 @@ function parseInstantMs(value) {
|
|
|
11517
12171
|
return Parsing.parseInstantMs(value);
|
|
11518
12172
|
}
|
|
11519
12173
|
|
|
11520
|
-
//
|
|
12174
|
+
// ../../../Decionis/apps/protocol/src/mcp/DecisionConversation.ts
|
|
11521
12175
|
var INTERNAL_CONTEXT_KEYS = /* @__PURE__ */ new Set([
|
|
11522
12176
|
"source_surface",
|
|
11523
12177
|
"source_protocol",
|
|
@@ -11778,7 +12432,7 @@ function buildAuthoritySummary(input) {
|
|
|
11778
12432
|
return DecisionConversation.buildAuthoritySummary(input);
|
|
11779
12433
|
}
|
|
11780
12434
|
|
|
11781
|
-
//
|
|
12435
|
+
// ../../../Decionis/apps/protocol/src/mcp/PresenceMcpIntegration.ts
|
|
11782
12436
|
import { createHash as createHash3, createHmac, timingSafeEqual as timingSafeEqual2 } from "crypto";
|
|
11783
12437
|
var DEFAULT_PRESENCE_BASE_URL = "https://presence.decionis.com";
|
|
11784
12438
|
var DEFAULT_TIMEOUT_MS = 1e4;
|
|
@@ -12135,7 +12789,7 @@ function sanitizePresenceDecisionContext(input) {
|
|
|
12135
12789
|
};
|
|
12136
12790
|
}
|
|
12137
12791
|
|
|
12138
|
-
//
|
|
12792
|
+
// ../../../Decionis/apps/protocol/src/mcp/McpTools.ts
|
|
12139
12793
|
var GET_STARTED_SCENARIOS = [
|
|
12140
12794
|
{
|
|
12141
12795
|
user_question: "Can you send a $250,000 wire to Northstar Components?",
|
|
@@ -13287,7 +13941,7 @@ function findTool(tools, name) {
|
|
|
13287
13941
|
return McpTools.findTool(tools, name);
|
|
13288
13942
|
}
|
|
13289
13943
|
|
|
13290
|
-
//
|
|
13944
|
+
// ../../../Decionis/apps/protocol/src/mcp/McpOriginPolicy.ts
|
|
13291
13945
|
var DEFAULT_MCP_ALLOWED_ORIGINS = [
|
|
13292
13946
|
"https://claude.ai",
|
|
13293
13947
|
"https://chatgpt.com",
|
|
@@ -13321,7 +13975,7 @@ function isMcpOriginAllowed(origin2, allowedOrigins) {
|
|
|
13321
13975
|
return parsed !== null && allowedOrigins.has(parsed);
|
|
13322
13976
|
}
|
|
13323
13977
|
|
|
13324
|
-
//
|
|
13978
|
+
// ../../../Decionis/apps/protocol/src/mcp/McpRoutes.ts
|
|
13325
13979
|
function buildMcpOriginGuard(publicBaseUrl) {
|
|
13326
13980
|
const allowedOrigins = buildMcpAllowedOrigins(publicBaseUrl);
|
|
13327
13981
|
return async (req, reply) => {
|
|
@@ -13529,7 +14183,7 @@ async function handleJsonRpcRequest(app, requestBody, options) {
|
|
|
13529
14183
|
}
|
|
13530
14184
|
const toolStartedAt = process.hrtime.bigint();
|
|
13531
14185
|
const args = asRecord2(params.arguments) ?? {};
|
|
13532
|
-
const authError = authorizeToolInvocation(options.auth, name, args);
|
|
14186
|
+
const authError = authorizeToolInvocation(options.auth, tool.name, args);
|
|
13533
14187
|
if (authError) {
|
|
13534
14188
|
const toolDurationMs2 = durationMs(toolStartedAt);
|
|
13535
14189
|
await recordTelemetryBatch(app, options.telemetry, [
|
|
@@ -13566,7 +14220,10 @@ async function handleJsonRpcRequest(app, requestBody, options) {
|
|
|
13566
14220
|
payload: jsonRpcError(id, authError.code, authError.message)
|
|
13567
14221
|
};
|
|
13568
14222
|
}
|
|
13569
|
-
const result = await handleToolCall(
|
|
14223
|
+
const result = await handleToolCall(
|
|
14224
|
+
tool,
|
|
14225
|
+
bindAuthenticatedOrgId(options.auth, tool.name, args)
|
|
14226
|
+
);
|
|
13570
14227
|
const outcome = canonicalAuthorizationOutcome(result.structuredContent);
|
|
13571
14228
|
const toolDurationMs = durationMs(toolStartedAt);
|
|
13572
14229
|
const terminalEvents = [
|
|
@@ -13777,7 +14434,7 @@ async function handleLegacyToolCall(app, store, auth, body) {
|
|
|
13777
14434
|
};
|
|
13778
14435
|
}
|
|
13779
14436
|
const args = asRecord2(body.input) ?? {};
|
|
13780
|
-
const authError = authorizeToolInvocation(auth,
|
|
14437
|
+
const authError = authorizeToolInvocation(auth, tool.name, args);
|
|
13781
14438
|
if (authError) {
|
|
13782
14439
|
return {
|
|
13783
14440
|
error: "FORBIDDEN",
|
|
@@ -13786,7 +14443,7 @@ async function handleLegacyToolCall(app, store, auth, body) {
|
|
|
13786
14443
|
is_error: true
|
|
13787
14444
|
};
|
|
13788
14445
|
}
|
|
13789
|
-
const result = await handleToolCall(tool, bindAuthenticatedOrgId(auth,
|
|
14446
|
+
const result = await handleToolCall(tool, bindAuthenticatedOrgId(auth, tool.name, args));
|
|
13790
14447
|
return {
|
|
13791
14448
|
output: result.structuredContent ?? { text: result.content[0]?.text ?? "" },
|
|
13792
14449
|
event: {
|
|
@@ -13961,7 +14618,7 @@ function registerProtocolMcpRoutes(app, options) {
|
|
|
13961
14618
|
authorization_servers: [authorizationServerBaseUrl],
|
|
13962
14619
|
bearer_methods_supported: ["header"],
|
|
13963
14620
|
scopes_supported: ["decision:read", "decision:run", "decision:write"],
|
|
13964
|
-
resource_documentation: "https://decionis.
|
|
14621
|
+
resource_documentation: "https://decionis.ai/mcp"
|
|
13965
14622
|
};
|
|
13966
14623
|
const oauthAuthorizationServer = {
|
|
13967
14624
|
issuer: authorizationServerBaseUrl,
|
|
@@ -14013,7 +14670,7 @@ function registerProtocolMcpRoutes(app, options) {
|
|
|
14013
14670
|
}
|
|
14014
14671
|
}
|
|
14015
14672
|
|
|
14016
|
-
//
|
|
14673
|
+
// ../../../Decionis/apps/protocol/src/execution-gating/ExecutionGatingSupport.ts
|
|
14017
14674
|
import { createHash as createHash5, createHmac as createHmac2, randomUUID as randomUUID3, timingSafeEqual as timingSafeEqual3 } from "crypto";
|
|
14018
14675
|
var DEFAULT_POLICY_LIMITS = {
|
|
14019
14676
|
max_single_payment_usd: 2,
|
|
@@ -14140,7 +14797,7 @@ function hashLedgerEntry(input) {
|
|
|
14140
14797
|
return sha256(input);
|
|
14141
14798
|
}
|
|
14142
14799
|
|
|
14143
|
-
//
|
|
14800
|
+
// ../../../Decionis/apps/protocol/src/execution-gating/ExecutionGatingService.ts
|
|
14144
14801
|
var ExecutionGatingService = class {
|
|
14145
14802
|
secret;
|
|
14146
14803
|
tokenTtlSeconds;
|
|
@@ -14381,15 +15038,15 @@ var ExecutionGatingService = class {
|
|
|
14381
15038
|
};
|
|
14382
15039
|
const payload = base64UrlEncode(stableStringify(claims));
|
|
14383
15040
|
const signature = sign(payload, this.secret);
|
|
14384
|
-
const
|
|
14385
|
-
const tokenHash = sha256(
|
|
15041
|
+
const token2 = `exec_tok_${payload}.${signature}`;
|
|
15042
|
+
const tokenHash = sha256(token2);
|
|
14386
15043
|
this.tokens.set(claims.jti, {
|
|
14387
15044
|
claims,
|
|
14388
15045
|
token_hash: tokenHash,
|
|
14389
15046
|
consumed_at: null
|
|
14390
15047
|
});
|
|
14391
15048
|
return {
|
|
14392
|
-
token,
|
|
15049
|
+
token: token2,
|
|
14393
15050
|
claims,
|
|
14394
15051
|
token_hash: tokenHash,
|
|
14395
15052
|
expires_at: new Date(claims.exp * 1e3).toISOString()
|
|
@@ -14424,11 +15081,11 @@ var ExecutionGatingService = class {
|
|
|
14424
15081
|
this.dossiers.set(dossier.dossier_id, dossier);
|
|
14425
15082
|
return dossier;
|
|
14426
15083
|
}
|
|
14427
|
-
parseToken(
|
|
14428
|
-
if (!
|
|
15084
|
+
parseToken(token2) {
|
|
15085
|
+
if (!token2.startsWith("exec_tok_")) {
|
|
14429
15086
|
return { valid: false, reason_codes: ["MALFORMED_EXECUTION_TOKEN"], claims: null };
|
|
14430
15087
|
}
|
|
14431
|
-
const compact =
|
|
15088
|
+
const compact = token2.slice("exec_tok_".length);
|
|
14432
15089
|
const [payload, signature] = compact.split(".");
|
|
14433
15090
|
if (!payload || !signature) {
|
|
14434
15091
|
return { valid: false, reason_codes: ["MALFORMED_EXECUTION_TOKEN"], claims: null };
|
|
@@ -14468,7 +15125,7 @@ var ExecutionGatingService = class {
|
|
|
14468
15125
|
const evaluation = this.evaluatePolicy(request);
|
|
14469
15126
|
const shadow = request.mode === "SHADOW";
|
|
14470
15127
|
const status = evaluation.status;
|
|
14471
|
-
const
|
|
15128
|
+
const token2 = bindExecution && !shadow && status === "ALLOW" ? this.issueToken({ request, decision_id, chain_id, action_hash }) : null;
|
|
14472
15129
|
const ledgerEntry = this.appendLedger({
|
|
14473
15130
|
tenant_id: request.tenant_id,
|
|
14474
15131
|
event_type: status === "ALLOW" ? "tool.execution.allowed" : "tool.execution.blocked",
|
|
@@ -14483,10 +15140,10 @@ var ExecutionGatingService = class {
|
|
|
14483
15140
|
metadata: {
|
|
14484
15141
|
action_hash,
|
|
14485
15142
|
target: request.downstream_target,
|
|
14486
|
-
token_issued: Boolean(
|
|
15143
|
+
token_issued: Boolean(token2)
|
|
14487
15144
|
}
|
|
14488
15145
|
});
|
|
14489
|
-
if (
|
|
15146
|
+
if (token2) {
|
|
14490
15147
|
this.appendLedger({
|
|
14491
15148
|
tenant_id: request.tenant_id,
|
|
14492
15149
|
event_type: "execution.token.issued",
|
|
@@ -14498,7 +15155,7 @@ var ExecutionGatingService = class {
|
|
|
14498
15155
|
amount: request.action.amount,
|
|
14499
15156
|
status: "ISSUED",
|
|
14500
15157
|
reason_codes: ["EXECUTION_TOKEN_ISSUED"],
|
|
14501
|
-
metadata: { token_hash:
|
|
15158
|
+
metadata: { token_hash: token2.token_hash, expires_at: token2.expires_at }
|
|
14502
15159
|
});
|
|
14503
15160
|
}
|
|
14504
15161
|
this.decisions.set(decision_id, {
|
|
@@ -14518,7 +15175,7 @@ var ExecutionGatingService = class {
|
|
|
14518
15175
|
status,
|
|
14519
15176
|
reason_codes: evaluation.reason_codes,
|
|
14520
15177
|
telemetry: evaluation.telemetry,
|
|
14521
|
-
token_hash:
|
|
15178
|
+
token_hash: token2?.token_hash ?? null
|
|
14522
15179
|
});
|
|
14523
15180
|
const responseBase = {
|
|
14524
15181
|
decision_id,
|
|
@@ -14529,15 +15186,15 @@ var ExecutionGatingService = class {
|
|
|
14529
15186
|
should_execute: shadow ? true : status === "ALLOW",
|
|
14530
15187
|
evaluation_mode: request.mode,
|
|
14531
15188
|
authority_classification: shadow ? "OBSERVATIONAL" : "AUTHORITATIVE",
|
|
14532
|
-
execution_eligible:
|
|
15189
|
+
execution_eligible: token2 !== null,
|
|
14533
15190
|
reason_codes: evaluation.reason_codes,
|
|
14534
15191
|
policy_snapshot: POLICY_SNAPSHOT,
|
|
14535
15192
|
risk_score: evaluation.risk_score,
|
|
14536
15193
|
blast_radius: request.action.amount && request.action.amount > 1 ? "medium" : "low",
|
|
14537
15194
|
required_escalation: null,
|
|
14538
15195
|
action_hash,
|
|
14539
|
-
execution_token:
|
|
14540
|
-
execution_token_expires_at:
|
|
15196
|
+
execution_token: token2?.token ?? null,
|
|
15197
|
+
execution_token_expires_at: token2?.expires_at ?? null,
|
|
14541
15198
|
dossier_id: dossier.dossier_id,
|
|
14542
15199
|
dossier_url: `/v1/authority/dossiers/${dossier.dossier_id}`,
|
|
14543
15200
|
ledger_entry_id: ledgerEntry.event_id
|
|
@@ -14555,7 +15212,7 @@ function createExecutionGatingService(options = {}) {
|
|
|
14555
15212
|
return new ExecutionGatingService(options);
|
|
14556
15213
|
}
|
|
14557
15214
|
|
|
14558
|
-
//
|
|
15215
|
+
// ../../../Decionis/apps/protocol/src/execution-gating/ExecutionGatingRoutes.ts
|
|
14559
15216
|
function verificationInputFromBody(body, tokenFallback) {
|
|
14560
15217
|
const input = asRecord4(body);
|
|
14561
15218
|
const target = asRecord4(input.downstream_target);
|
|
@@ -14796,7 +15453,7 @@ function registerExecutionGatingRoutes(app, options) {
|
|
|
14796
15453
|
ExecutionGatingRoutes.register(app, options);
|
|
14797
15454
|
}
|
|
14798
15455
|
|
|
14799
|
-
//
|
|
15456
|
+
// ../../../Decionis/apps/protocol/src/authority/AuthorityPolicyParser.ts
|
|
14800
15457
|
var ROLE_ID = /^[A-Z][A-Z0-9_]{1,63}$/;
|
|
14801
15458
|
var REASON_CODE = /^[A-Z][A-Z0-9_]{1,119}$/;
|
|
14802
15459
|
var METHODS = /* @__PURE__ */ new Set(["WEBAUTHN", "MOBILE_DEVICE", "ACTIVE_LIVENESS"]);
|
|
@@ -14809,7 +15466,8 @@ var AuthorityPolicyParser = class _AuthorityPolicyParser {
|
|
|
14809
15466
|
const verification = _AuthorityPolicyParser.parseVerification(record.verification_requirements);
|
|
14810
15467
|
const resolution = _AuthorityPolicyParser.parseResolution(record.resolution, selector);
|
|
14811
15468
|
const expiresInSeconds = asNumber(record.expires_in_seconds);
|
|
14812
|
-
|
|
15469
|
+
const maxExpiresInSeconds = resolution?.tiers === void 0 ? _AuthorityPolicyParser.MAX_CEREMONY_SECONDS : _AuthorityPolicyParser.MAX_CHAIN_SECONDS;
|
|
15470
|
+
if (!reasonCodes || !selector || !verification || !resolution || expiresInSeconds == null || !Number.isInteger(expiresInSeconds) || expiresInSeconds < 60 || expiresInSeconds > maxExpiresInSeconds) {
|
|
14813
15471
|
return null;
|
|
14814
15472
|
}
|
|
14815
15473
|
return {
|
|
@@ -14820,6 +15478,8 @@ var AuthorityPolicyParser = class _AuthorityPolicyParser {
|
|
|
14820
15478
|
expires_in_seconds: expiresInSeconds
|
|
14821
15479
|
};
|
|
14822
15480
|
}
|
|
15481
|
+
static MAX_CEREMONY_SECONDS = 3600;
|
|
15482
|
+
static MAX_CHAIN_SECONDS = 7 * 24 * 3600;
|
|
14823
15483
|
static policyKeys = /* @__PURE__ */ new Set([
|
|
14824
15484
|
"reason_codes",
|
|
14825
15485
|
"selector",
|
|
@@ -14901,7 +15561,7 @@ var AuthorityPolicyParser = class _AuthorityPolicyParser {
|
|
|
14901
15561
|
const record = asRecord3(input);
|
|
14902
15562
|
if (!_AuthorityPolicyParser.hasOnlyKeys(
|
|
14903
15563
|
record,
|
|
14904
|
-
/* @__PURE__ */ new Set(["quorum", "delegation", "fallback_role_ids"])
|
|
15564
|
+
/* @__PURE__ */ new Set(["quorum", "delegation", "fallback_role_ids", "tiers"])
|
|
14905
15565
|
) || record.quorum !== 1 || record.delegation !== "DISALLOWED" && record.delegation !== "REQUIREMENT_REFRESH" || !Array.isArray(record.fallback_role_ids) || record.fallback_role_ids.length > 10) {
|
|
14906
15566
|
return null;
|
|
14907
15567
|
}
|
|
@@ -14911,12 +15571,46 @@ var AuthorityPolicyParser = class _AuthorityPolicyParser {
|
|
|
14911
15571
|
if (fallbackRoles.length !== record.fallback_role_ids.length || new Set(fallbackRoles).size !== fallbackRoles.length || selector?.kind === "ROLE" && fallbackRoles.includes(selector.role_id)) {
|
|
14912
15572
|
return null;
|
|
14913
15573
|
}
|
|
15574
|
+
const tiers = _AuthorityPolicyParser.parseTiers(record.tiers);
|
|
15575
|
+
if (record.tiers !== void 0 && tiers === null) return null;
|
|
15576
|
+
if (tiers && selector?.kind !== "ROLE") return null;
|
|
14914
15577
|
return {
|
|
14915
15578
|
quorum: 1,
|
|
14916
15579
|
delegation: record.delegation,
|
|
14917
|
-
fallback_role_ids: fallbackRoles
|
|
15580
|
+
fallback_role_ids: fallbackRoles,
|
|
15581
|
+
...tiers ? { tiers } : {}
|
|
14918
15582
|
};
|
|
14919
15583
|
}
|
|
15584
|
+
/** Priority tiers of principals; unique ascending priorities, a principal in one tier only. */
|
|
15585
|
+
static parseTiers(input) {
|
|
15586
|
+
if (input === void 0) return null;
|
|
15587
|
+
if (!Array.isArray(input) || input.length < 1 || input.length > 5) return null;
|
|
15588
|
+
const tiers = [];
|
|
15589
|
+
const seen = /* @__PURE__ */ new Set();
|
|
15590
|
+
for (const value of input) {
|
|
15591
|
+
const tier = asRecord3(value);
|
|
15592
|
+
if (!_AuthorityPolicyParser.hasOnlyKeys(tier, /* @__PURE__ */ new Set(["priority", "principal_ids"]))) {
|
|
15593
|
+
return null;
|
|
15594
|
+
}
|
|
15595
|
+
const priority = asNumber(tier.priority);
|
|
15596
|
+
if (priority == null || !Number.isInteger(priority) || priority < 1 || priority > 5 || tiers.length > 0 && priority <= tiers[tiers.length - 1].priority) {
|
|
15597
|
+
return null;
|
|
15598
|
+
}
|
|
15599
|
+
if (!Array.isArray(tier.principal_ids) || tier.principal_ids.length < 1 || tier.principal_ids.length > 10) {
|
|
15600
|
+
return null;
|
|
15601
|
+
}
|
|
15602
|
+
const principalIds = tier.principal_ids.filter(
|
|
15603
|
+
(id) => typeof id === "string" && id.length >= 1 && id.length <= 200
|
|
15604
|
+
);
|
|
15605
|
+
if (principalIds.length !== tier.principal_ids.length) return null;
|
|
15606
|
+
for (const id of principalIds) {
|
|
15607
|
+
if (seen.has(id)) return null;
|
|
15608
|
+
seen.add(id);
|
|
15609
|
+
}
|
|
15610
|
+
tiers.push({ priority, principal_ids: principalIds });
|
|
15611
|
+
}
|
|
15612
|
+
return tiers;
|
|
15613
|
+
}
|
|
14920
15614
|
static parseRegions(input) {
|
|
14921
15615
|
if (input === void 0) return null;
|
|
14922
15616
|
if (!Array.isArray(input) || input.length < 1 || input.length > 100) return null;
|
|
@@ -14932,10 +15626,10 @@ var AuthorityPolicyParser = class _AuthorityPolicyParser {
|
|
|
14932
15626
|
}
|
|
14933
15627
|
};
|
|
14934
15628
|
|
|
14935
|
-
//
|
|
15629
|
+
// ../../../Decionis/apps/protocol/src/support/Hashing.ts
|
|
14936
15630
|
import { createHash as createHash6 } from "crypto";
|
|
14937
15631
|
|
|
14938
|
-
//
|
|
15632
|
+
// ../../../Decionis/apps/protocol/src/integrity/DossierIntegrity.ts
|
|
14939
15633
|
var DECISION_DOSSIER_JWKS_PATH2 = "/.well-known/decision-dossier-jwks.json";
|
|
14940
15634
|
var DossierIntegrity = class _DossierIntegrity {
|
|
14941
15635
|
static stableJsonStringify(value) {
|
|
@@ -15045,7 +15739,7 @@ function buildDecisionDossierVerificationStatus(input) {
|
|
|
15045
15739
|
return DossierIntegrity.buildDecisionDossierVerificationStatus(input);
|
|
15046
15740
|
}
|
|
15047
15741
|
|
|
15048
|
-
//
|
|
15742
|
+
// ../../../Decionis/apps/protocol/src/support/Hashing.ts
|
|
15049
15743
|
var Hashing = class {
|
|
15050
15744
|
static sha256Hex(input) {
|
|
15051
15745
|
return createHash6("sha256").update(input, "utf8").digest("hex");
|
|
@@ -15073,7 +15767,7 @@ function canonicalizeForHash(value) {
|
|
|
15073
15767
|
return Hashing.canonicalizeForHash(value);
|
|
15074
15768
|
}
|
|
15075
15769
|
|
|
15076
|
-
//
|
|
15770
|
+
// ../../../Decionis/apps/protocol/src/policy-graph/PolicyGraph.ts
|
|
15077
15771
|
var PolicyGraph = class _PolicyGraph {
|
|
15078
15772
|
static sortPolicyBundlesNewestFirst(left, right) {
|
|
15079
15773
|
const leftEffective = parseInstantMs(left.effective_from) ?? Number.MIN_SAFE_INTEGER;
|
|
@@ -15378,6 +16072,14 @@ var PolicyGraph = class _PolicyGraph {
|
|
|
15378
16072
|
* a dotted path is used as-is, so history facts (`history.window`) and
|
|
15379
16073
|
* top-level facts can be required too. Deterministic: derived from the
|
|
15380
16074
|
* bundle alone.
|
|
16075
|
+
*
|
|
16076
|
+
* The one exception is a bare name that IS a reserved root — the runtime
|
|
16077
|
+
* signals an enforcement boundary reports, and the attribution the platform
|
|
16078
|
+
* computes from them. Those live at the top of the fact set, not under
|
|
16079
|
+
* `signals.`, so resolving `workload` to `signals.workload` would make it
|
|
16080
|
+
* permanently missing and every evaluation a fail-safe ESCALATE. A bundle
|
|
16081
|
+
* that means "refuse unless a workload was reported" writes `workload`, and
|
|
16082
|
+
* gets what it meant.
|
|
15381
16083
|
*/
|
|
15382
16084
|
static resolveRequiredSignalPaths(bundle) {
|
|
15383
16085
|
const declared = asRecord3(bundle.payload).required_signals;
|
|
@@ -15387,7 +16089,8 @@ var PolicyGraph = class _PolicyGraph {
|
|
|
15387
16089
|
for (const entry of entries.slice(0, 50)) {
|
|
15388
16090
|
const raw = asString2(entry)?.trim();
|
|
15389
16091
|
if (!raw) continue;
|
|
15390
|
-
const
|
|
16092
|
+
const reservedRoot = raw === RUNTIME_ATTRIBUTION_FACT || RUNTIME_SIGNAL_ROOTS.includes(raw);
|
|
16093
|
+
const path = raw.includes(".") || reservedRoot ? raw : `signals.${raw}`;
|
|
15391
16094
|
if (!paths.includes(path)) paths.push(path);
|
|
15392
16095
|
}
|
|
15393
16096
|
return paths;
|
|
@@ -15465,6 +16168,10 @@ var PolicyGraph = class _PolicyGraph {
|
|
|
15465
16168
|
signals[key] = normalized.value;
|
|
15466
16169
|
if (normalized.provenance) signalProvenance[key] = normalized.provenance;
|
|
15467
16170
|
}
|
|
16171
|
+
const runtimeSignals = RuntimeSignals.parse(context);
|
|
16172
|
+
const runtimeAttribution = RuntimeSignals.attributionOf(
|
|
16173
|
+
runtimeSignals.ok ? runtimeSignals : { boundary: null, workload: null }
|
|
16174
|
+
);
|
|
15468
16175
|
const history = asRecord3(context.history);
|
|
15469
16176
|
const override = asRecord3(context.override);
|
|
15470
16177
|
const evidence = asRecord3(context.evidence);
|
|
@@ -15488,7 +16195,15 @@ var PolicyGraph = class _PolicyGraph {
|
|
|
15488
16195
|
intake: context,
|
|
15489
16196
|
// Reserved fact namespaces — these keys shadow same-named context keys
|
|
15490
16197
|
// (the spread above runs first): signals, signal_provenance, history,
|
|
15491
|
-
// override, evidence, attachments, attachment_count, policy
|
|
16198
|
+
// override, evidence, attachments, attachment_count, policy,
|
|
16199
|
+
// runtime_attribution.
|
|
16200
|
+
//
|
|
16201
|
+
// `runtime_attribution` is the platform's own statement about the
|
|
16202
|
+
// boundary's report, and `platform_verified` on it is the field that
|
|
16203
|
+
// means "Decionis established this" rather than "our gateway said so".
|
|
16204
|
+
// It is computed here and shadows anything of that name a caller sent,
|
|
16205
|
+
// which the request parser refuses outright anyway.
|
|
16206
|
+
[RUNTIME_ATTRIBUTION_FACT]: runtimeAttribution,
|
|
15492
16207
|
signals,
|
|
15493
16208
|
signal_provenance: signalProvenance,
|
|
15494
16209
|
signal_admission: {
|
|
@@ -15915,7 +16630,7 @@ function toEvaluatePolicySnapshot(input) {
|
|
|
15915
16630
|
return PolicyGraph.toEvaluatePolicySnapshot(input);
|
|
15916
16631
|
}
|
|
15917
16632
|
|
|
15918
|
-
//
|
|
16633
|
+
// ../../../Decionis/apps/protocol/src/agent-gateway/AgentTaskPolicyResolver.ts
|
|
15919
16634
|
var PolicyGraphAgentTaskPolicyResolver = class {
|
|
15920
16635
|
constructor(store) {
|
|
15921
16636
|
this.store = store;
|
|
@@ -16083,7 +16798,7 @@ var PolicyGraphAgentTaskPolicyResolver = class {
|
|
|
16083
16798
|
}
|
|
16084
16799
|
};
|
|
16085
16800
|
|
|
16086
|
-
//
|
|
16801
|
+
// ../../../Decionis/apps/protocol/src/agent-gateway/MemoryAgentTaskReservationStore.ts
|
|
16087
16802
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
16088
16803
|
var MemoryAgentTaskReservationStore = class {
|
|
16089
16804
|
reservations = /* @__PURE__ */ new Map();
|
|
@@ -16243,7 +16958,7 @@ function createMemoryAgentTaskReservationStore() {
|
|
|
16243
16958
|
return new MemoryAgentTaskReservationStore();
|
|
16244
16959
|
}
|
|
16245
16960
|
|
|
16246
|
-
//
|
|
16961
|
+
// ../../../Decionis/apps/protocol/src/agent-gateway/AgentTaskCostEstimator.ts
|
|
16247
16962
|
var TOKENS_PER_MILLION = 1e6;
|
|
16248
16963
|
var AgentTaskCostEstimator = class {
|
|
16249
16964
|
project(intent, policy) {
|
|
@@ -16305,7 +17020,7 @@ var AgentTaskCostEstimator = class {
|
|
|
16305
17020
|
}
|
|
16306
17021
|
};
|
|
16307
17022
|
|
|
16308
|
-
//
|
|
17023
|
+
// ../../../Decionis/apps/protocol/src/agent-gateway/AgentTaskIntentParser.ts
|
|
16309
17024
|
import { createHash as createHash7 } from "crypto";
|
|
16310
17025
|
var AgentTaskIntentParser = class _AgentTaskIntentParser {
|
|
16311
17026
|
static parse(input) {
|
|
@@ -16409,7 +17124,7 @@ var AgentTaskIntentParser = class _AgentTaskIntentParser {
|
|
|
16409
17124
|
}
|
|
16410
17125
|
};
|
|
16411
17126
|
|
|
16412
|
-
//
|
|
17127
|
+
// ../../../Decionis/apps/protocol/src/agent-gateway/AgentTaskGatewayService.ts
|
|
16413
17128
|
var AgentTaskGatewayService = class {
|
|
16414
17129
|
constructor(store, policyResolver, authority, estimator = new AgentTaskCostEstimator(), options = {}) {
|
|
16415
17130
|
this.store = store;
|
|
@@ -16595,7 +17310,7 @@ var AgentTaskGatewayService = class {
|
|
|
16595
17310
|
}
|
|
16596
17311
|
};
|
|
16597
17312
|
|
|
16598
|
-
//
|
|
17313
|
+
// ../../../Decionis/apps/protocol/src/agent-gateway/AgentGatewayAuthGuard.ts
|
|
16599
17314
|
import { timingSafeEqual as timingSafeEqual4 } from "crypto";
|
|
16600
17315
|
var AgentGatewayAuthGuard = class {
|
|
16601
17316
|
constructor(lookup, env = process.env) {
|
|
@@ -16648,7 +17363,7 @@ var AgentGatewayAuthGuard = class {
|
|
|
16648
17363
|
}
|
|
16649
17364
|
};
|
|
16650
17365
|
|
|
16651
|
-
//
|
|
17366
|
+
// ../../../Decionis/apps/protocol/src/agent-gateway/AgentProviderProxy.ts
|
|
16652
17367
|
var AgentProviderProxy = class {
|
|
16653
17368
|
constructor(gateway, options = {}) {
|
|
16654
17369
|
this.gateway = gateway;
|
|
@@ -16853,10 +17568,10 @@ var AgentProviderProxy = class {
|
|
|
16853
17568
|
}
|
|
16854
17569
|
};
|
|
16855
17570
|
|
|
16856
|
-
//
|
|
17571
|
+
// ../../../Decionis/apps/protocol/src/agent-gateway/providers/AnthropicProviderAdapter.ts
|
|
16857
17572
|
import { createHash as createHash8 } from "crypto";
|
|
16858
17573
|
|
|
16859
|
-
//
|
|
17574
|
+
// ../../../Decionis/apps/protocol/src/agent-gateway/providers/AgentProviderAdapter.ts
|
|
16860
17575
|
var AgentProviderValues = class _AgentProviderValues {
|
|
16861
17576
|
static asRecord(value) {
|
|
16862
17577
|
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
@@ -16897,7 +17612,7 @@ var AgentProviderValues = class _AgentProviderValues {
|
|
|
16897
17612
|
}
|
|
16898
17613
|
};
|
|
16899
17614
|
|
|
16900
|
-
//
|
|
17615
|
+
// ../../../Decionis/apps/protocol/src/agent-gateway/providers/AnthropicProviderAdapter.ts
|
|
16901
17616
|
var AnthropicProviderAdapter = class {
|
|
16902
17617
|
provider = "anthropic";
|
|
16903
17618
|
operation = "messages.create";
|
|
@@ -16984,7 +17699,7 @@ var AnthropicProviderAdapter = class {
|
|
|
16984
17699
|
}
|
|
16985
17700
|
};
|
|
16986
17701
|
|
|
16987
|
-
//
|
|
17702
|
+
// ../../../Decionis/apps/protocol/src/agent-gateway/providers/OpenAiProviderAdapter.ts
|
|
16988
17703
|
import { createHash as createHash9 } from "crypto";
|
|
16989
17704
|
var OpenAiProviderAdapter = class {
|
|
16990
17705
|
provider = "openai";
|
|
@@ -17083,7 +17798,7 @@ var OpenAiProviderAdapter = class {
|
|
|
17083
17798
|
}
|
|
17084
17799
|
};
|
|
17085
17800
|
|
|
17086
|
-
//
|
|
17801
|
+
// ../../../Decionis/apps/protocol/src/agent-gateway/providers/AgentProviderRegistry.ts
|
|
17087
17802
|
var AgentProviderRegistry = class {
|
|
17088
17803
|
adapters;
|
|
17089
17804
|
constructor(adapters = [
|
|
@@ -17097,7 +17812,7 @@ var AgentProviderRegistry = class {
|
|
|
17097
17812
|
}
|
|
17098
17813
|
};
|
|
17099
17814
|
|
|
17100
|
-
//
|
|
17815
|
+
// ../../../Decionis/apps/protocol/src/agent-gateway/AgentTaskGatewayRoutes.ts
|
|
17101
17816
|
var AgentTaskGatewayRoutes = class {
|
|
17102
17817
|
static register(app, options) {
|
|
17103
17818
|
const auth = new AgentGatewayAuthGuard(options.authLookup);
|
|
@@ -17248,11 +17963,24 @@ var AgentTaskGatewayRoutes = class {
|
|
|
17248
17963
|
}
|
|
17249
17964
|
};
|
|
17250
17965
|
|
|
17251
|
-
//
|
|
17966
|
+
// ../../../Decionis/apps/protocol/src/ProtocolInfo.ts
|
|
17252
17967
|
var PROTOCOL_SERVICE = "decionis-protocol";
|
|
17253
17968
|
var PROTOCOL_VERSION = "1.0.0";
|
|
17254
17969
|
|
|
17255
|
-
//
|
|
17970
|
+
// ../../../Decionis/apps/protocol/src/discovery/GlamaClaimRoutes.ts
|
|
17971
|
+
var GlamaClaimRoutes = class {
|
|
17972
|
+
register(app) {
|
|
17973
|
+
app.get(
|
|
17974
|
+
"/.well-known/glama.json",
|
|
17975
|
+
async (_request, reply) => reply.header("cache-control", "public, max-age=300").send({
|
|
17976
|
+
$schema: "https://glama.ai/mcp/schemas/connector.json",
|
|
17977
|
+
claim: "glama_claim_BUHrLznF-9qs1cZEwwb2AN5CkXK7tNjS"
|
|
17978
|
+
})
|
|
17979
|
+
);
|
|
17980
|
+
}
|
|
17981
|
+
};
|
|
17982
|
+
|
|
17983
|
+
// ../../../Decionis/apps/protocol/src/health/HealthRoutes.ts
|
|
17256
17984
|
function registerHealthRoutes(app, deps) {
|
|
17257
17985
|
const { store } = deps;
|
|
17258
17986
|
app.get("/v1/protocol/health", async () => ({
|
|
@@ -17277,14 +18005,14 @@ function registerHealthRoutes(app, deps) {
|
|
|
17277
18005
|
});
|
|
17278
18006
|
}
|
|
17279
18007
|
|
|
17280
|
-
//
|
|
18008
|
+
// ../../../Decionis/apps/protocol/src/finance-overrides/FinanceOverrideRoutes.ts
|
|
17281
18009
|
import { randomUUID as randomUUID6 } from "crypto";
|
|
17282
18010
|
|
|
17283
|
-
//
|
|
18011
|
+
// ../../../Decionis/apps/protocol/src/validation/ProtocolArtifacts.ts
|
|
17284
18012
|
import Ajv2020 from "ajv/dist/2020.js";
|
|
17285
18013
|
import addFormats from "ajv-formats";
|
|
17286
18014
|
|
|
17287
|
-
//
|
|
18015
|
+
// ../../../Decionis/docs/decionis.protocol.schemas/v1/audit-ledger-entry.schema.json
|
|
17288
18016
|
var audit_ledger_entry_schema_default = {
|
|
17289
18017
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
17290
18018
|
$id: "https://decionis.io/protocol/schemas/v1/audit-ledger-entry.schema.json",
|
|
@@ -17314,7 +18042,8 @@ var audit_ledger_entry_schema_default = {
|
|
|
17314
18042
|
"EXECUTION_STATUS_CHANGED",
|
|
17315
18043
|
"EXPORT_GENERATED",
|
|
17316
18044
|
"ACCESS_GRANTED",
|
|
17317
|
-
"ACCESS_REVOKED"
|
|
18045
|
+
"ACCESS_REVOKED",
|
|
18046
|
+
"LEDGER_FORK_RESOLVED"
|
|
17318
18047
|
]
|
|
17319
18048
|
},
|
|
17320
18049
|
occurred_at: {
|
|
@@ -17445,7 +18174,7 @@ var audit_ledger_entry_schema_default = {
|
|
|
17445
18174
|
]
|
|
17446
18175
|
};
|
|
17447
18176
|
|
|
17448
|
-
//
|
|
18177
|
+
// ../../../Decionis/docs/decionis.protocol.schemas/v1/context-snapshot.schema.json
|
|
17449
18178
|
var context_snapshot_schema_default = {
|
|
17450
18179
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
17451
18180
|
$id: "https://decionis.io/protocol/schemas/v1/context-snapshot.schema.json",
|
|
@@ -17600,7 +18329,7 @@ var context_snapshot_schema_default = {
|
|
|
17600
18329
|
]
|
|
17601
18330
|
};
|
|
17602
18331
|
|
|
17603
|
-
//
|
|
18332
|
+
// ../../../Decionis/docs/decionis.protocol.schemas/v1/decision-resolution.schema.json
|
|
17604
18333
|
var decision_resolution_schema_default = {
|
|
17605
18334
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
17606
18335
|
$id: "https://decionis.io/protocol/schemas/v1/decision-resolution.schema.json",
|
|
@@ -17773,7 +18502,7 @@ var decision_resolution_schema_default = {
|
|
|
17773
18502
|
]
|
|
17774
18503
|
};
|
|
17775
18504
|
|
|
17776
|
-
//
|
|
18505
|
+
// ../../../Decionis/docs/decionis.protocol.schemas/v1/execution-dispatch.schema.json
|
|
17777
18506
|
var execution_dispatch_schema_default = {
|
|
17778
18507
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
17779
18508
|
$id: "https://decionis.io/protocol/schemas/v1/execution-dispatch.schema.json",
|
|
@@ -17892,7 +18621,7 @@ var execution_dispatch_schema_default = {
|
|
|
17892
18621
|
]
|
|
17893
18622
|
};
|
|
17894
18623
|
|
|
17895
|
-
//
|
|
18624
|
+
// ../../../Decionis/docs/decionis.protocol.schemas/v1/policy-bundle.schema.json
|
|
17896
18625
|
var policy_bundle_schema_default = {
|
|
17897
18626
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
17898
18627
|
$id: "https://decionis.io/protocol/schemas/v1/policy-bundle.schema.json",
|
|
@@ -18171,6 +18900,27 @@ var policy_bundle_schema_default = {
|
|
|
18171
18900
|
maxItems: 10,
|
|
18172
18901
|
uniqueItems: true,
|
|
18173
18902
|
items: { type: "string", pattern: "^[A-Z][A-Z0-9_]{1,63}$" }
|
|
18903
|
+
},
|
|
18904
|
+
tiers: {
|
|
18905
|
+
type: "array",
|
|
18906
|
+
minItems: 1,
|
|
18907
|
+
maxItems: 5,
|
|
18908
|
+
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.",
|
|
18909
|
+
items: {
|
|
18910
|
+
type: "object",
|
|
18911
|
+
additionalProperties: false,
|
|
18912
|
+
properties: {
|
|
18913
|
+
priority: { type: "integer", minimum: 1, maximum: 5 },
|
|
18914
|
+
principal_ids: {
|
|
18915
|
+
type: "array",
|
|
18916
|
+
minItems: 1,
|
|
18917
|
+
maxItems: 10,
|
|
18918
|
+
uniqueItems: true,
|
|
18919
|
+
items: { type: "string", minLength: 1, maxLength: 200 }
|
|
18920
|
+
}
|
|
18921
|
+
},
|
|
18922
|
+
required: ["priority", "principal_ids"]
|
|
18923
|
+
}
|
|
18174
18924
|
}
|
|
18175
18925
|
},
|
|
18176
18926
|
required: ["quorum", "delegation", "fallback_role_ids"]
|
|
@@ -18194,7 +18944,8 @@ var policy_bundle_schema_default = {
|
|
|
18194
18944
|
expires_in_seconds: {
|
|
18195
18945
|
type: "integer",
|
|
18196
18946
|
minimum: 60,
|
|
18197
|
-
maximum:
|
|
18947
|
+
maximum: 604800,
|
|
18948
|
+
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."
|
|
18198
18949
|
}
|
|
18199
18950
|
},
|
|
18200
18951
|
required: [
|
|
@@ -18562,7 +19313,7 @@ var policy_bundle_schema_default = {
|
|
|
18562
19313
|
required: ["protocol_version", "bundle_id", "org_id", "version", "effective_from", "rules"]
|
|
18563
19314
|
};
|
|
18564
19315
|
|
|
18565
|
-
//
|
|
19316
|
+
// ../../../Decionis/docs/decionis.protocol.schemas/v1/signal-envelope.schema.json
|
|
18566
19317
|
var signal_envelope_schema_default = {
|
|
18567
19318
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
18568
19319
|
$id: "https://decionis.io/protocol/schemas/v1/signal-envelope.schema.json",
|
|
@@ -18776,7 +19527,7 @@ var signal_envelope_schema_default = {
|
|
|
18776
19527
|
]
|
|
18777
19528
|
};
|
|
18778
19529
|
|
|
18779
|
-
//
|
|
19530
|
+
// ../../../Decionis/apps/protocol/src/validation/ProtocolArtifacts.ts
|
|
18780
19531
|
var ajv = new Ajv2020({ allErrors: true, strict: false });
|
|
18781
19532
|
addFormats(ajv);
|
|
18782
19533
|
var ProtocolArtifacts = class _ProtocolArtifacts {
|
|
@@ -18811,7 +19562,7 @@ function validateProtocolArtifact(artifact, payload) {
|
|
|
18811
19562
|
return ProtocolArtifacts.validate(artifact, payload);
|
|
18812
19563
|
}
|
|
18813
19564
|
|
|
18814
|
-
//
|
|
19565
|
+
// ../../../Decionis/apps/protocol/src/finance-overrides/FinanceOverrideContracts.ts
|
|
18815
19566
|
var FINANCE_OVERRIDE_REASON_CODES = [
|
|
18816
19567
|
"POLICY_EXCEPTION",
|
|
18817
19568
|
"RISK_THRESHOLD_OVERRIDE",
|
|
@@ -18823,7 +19574,7 @@ var FINANCE_OVERRIDE_REASON_CODES = [
|
|
|
18823
19574
|
"MANUAL_VERIFICATION_REQUIRED"
|
|
18824
19575
|
];
|
|
18825
19576
|
|
|
18826
|
-
//
|
|
19577
|
+
// ../../../Decionis/apps/protocol/src/finance-overrides/FinanceOverrides.ts
|
|
18827
19578
|
import { createHash as createHash10, randomUUID as randomUUID5 } from "crypto";
|
|
18828
19579
|
var FinanceOverrides = class {
|
|
18829
19580
|
static parseActorType(value) {
|
|
@@ -19126,7 +19877,7 @@ function appendFinanceOverrideLedgerEvent(store, input) {
|
|
|
19126
19877
|
return FinanceOverrides.appendFinanceOverrideLedgerEvent(store, input);
|
|
19127
19878
|
}
|
|
19128
19879
|
|
|
19129
|
-
//
|
|
19880
|
+
// ../../../Decionis/apps/protocol/src/finance-overrides/FinanceOverrideRoutes.ts
|
|
19130
19881
|
function registerFinanceOverrideRoutes(app, deps) {
|
|
19131
19882
|
const { store } = deps;
|
|
19132
19883
|
app.get("/v1/protocol/finance/override-reason-codes", async () => ({
|
|
@@ -19332,10 +20083,10 @@ function registerFinanceOverrideRoutes(app, deps) {
|
|
|
19332
20083
|
});
|
|
19333
20084
|
}
|
|
19334
20085
|
|
|
19335
|
-
//
|
|
20086
|
+
// ../../../Decionis/apps/protocol/src/evaluate-decision/EvaluateDecisionRoutes.ts
|
|
19336
20087
|
import { createHash as createHash14, randomUUID as randomUUID10 } from "crypto";
|
|
19337
20088
|
|
|
19338
|
-
//
|
|
20089
|
+
// ../../../Decionis/apps/protocol/src/support/Performance.ts
|
|
19339
20090
|
var ProtocolPerformance = class {
|
|
19340
20091
|
static durationMs(startedAt) {
|
|
19341
20092
|
return Number(process.hrtime.bigint() - startedAt) / 1e6;
|
|
@@ -19395,7 +20146,7 @@ function toProtocolPerformanceSnapshot(value) {
|
|
|
19395
20146
|
return ProtocolPerformance.toProtocolPerformanceSnapshot(value);
|
|
19396
20147
|
}
|
|
19397
20148
|
|
|
19398
|
-
//
|
|
20149
|
+
// ../../../Decionis/apps/protocol/src/verticals/affiliate-rewards/AffiliateRewardsPack.ts
|
|
19399
20150
|
var affiliateRewardsVerticalPack = {
|
|
19400
20151
|
key: "affiliate_rewards",
|
|
19401
20152
|
display_name: "Affiliate Rewards",
|
|
@@ -19480,7 +20231,172 @@ var affiliateRewardsVerticalPack = {
|
|
|
19480
20231
|
}
|
|
19481
20232
|
};
|
|
19482
20233
|
|
|
19483
|
-
//
|
|
20234
|
+
// ../../../Decionis/apps/protocol/src/verticals/commerce/CommercePack.ts
|
|
20235
|
+
var commerceVerticalPack = {
|
|
20236
|
+
key: "commerce",
|
|
20237
|
+
display_name: "Commerce Gate",
|
|
20238
|
+
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.",
|
|
20239
|
+
workflow_keys: [
|
|
20240
|
+
"commerce",
|
|
20241
|
+
"commerce_order_release",
|
|
20242
|
+
"commerce_refund_approve",
|
|
20243
|
+
"commerce_refund_request",
|
|
20244
|
+
"commerce_price_change",
|
|
20245
|
+
"commerce_promotion_change",
|
|
20246
|
+
"commerce_inventory_mutation",
|
|
20247
|
+
"commerce_order_acceptance"
|
|
20248
|
+
],
|
|
20249
|
+
default_domain: "COMMERCE",
|
|
20250
|
+
signal_mappings: [
|
|
20251
|
+
{ domain: "COMMERCE", metric_name: "net_margin_percent", source_hint: "commerce_connector" },
|
|
20252
|
+
{ domain: "COMMERCE", metric_name: "available_inventory", source_hint: "commerce_connector" },
|
|
20253
|
+
{ domain: "COMMERCE", metric_name: "refund_amount", source_hint: "commerce_connector" }
|
|
20254
|
+
],
|
|
20255
|
+
policy_bundle: {
|
|
20256
|
+
version: "commerce-v1",
|
|
20257
|
+
rules: [
|
|
20258
|
+
{
|
|
20259
|
+
rule_id: "reject_refund_above_refundable",
|
|
20260
|
+
name: "Reject refunds above the refundable balance",
|
|
20261
|
+
decision_domain: "COMMERCE",
|
|
20262
|
+
when: {
|
|
20263
|
+
all: [{ field: "signals.refund_exceeds_refundable", operator: "EQ", value: true }]
|
|
20264
|
+
},
|
|
20265
|
+
then: { action: "AUTO_REJECT", severity: "urgent", sla_minutes: 60 },
|
|
20266
|
+
priority: 400,
|
|
20267
|
+
enabled: true,
|
|
20268
|
+
rationale: "A refund that exceeds what the order has left to refund is never sent."
|
|
20269
|
+
},
|
|
20270
|
+
{
|
|
20271
|
+
rule_id: "escalate_order_release",
|
|
20272
|
+
name: "A held order is released only by an approver",
|
|
20273
|
+
decision_domain: "COMMERCE",
|
|
20274
|
+
when: {
|
|
20275
|
+
all: [{ field: "workflow_key", operator: "EQ", value: "commerce_order_release" }]
|
|
20276
|
+
},
|
|
20277
|
+
then: { action: "ESCALATE", severity: "elevated", sla_minutes: 240 },
|
|
20278
|
+
priority: 360,
|
|
20279
|
+
enabled: true,
|
|
20280
|
+
rationale: "Releasing an order the gate held is its own decision and needs an approver to prove who made it."
|
|
20281
|
+
},
|
|
20282
|
+
{
|
|
20283
|
+
rule_id: "escalate_large_refund",
|
|
20284
|
+
name: "Escalate refunds above the unattended limit",
|
|
20285
|
+
decision_domain: "COMMERCE",
|
|
20286
|
+
when: { all: [{ field: "signals.refund_amount", operator: "GT", value: 1e3 }] },
|
|
20287
|
+
then: { action: "ESCALATE", severity: "elevated", sla_minutes: 240 },
|
|
20288
|
+
priority: 350,
|
|
20289
|
+
enabled: true,
|
|
20290
|
+
rationale: "A refund above the unattended limit needs a named approver before it is sent."
|
|
20291
|
+
},
|
|
20292
|
+
{
|
|
20293
|
+
rule_id: "review_repeat_refund",
|
|
20294
|
+
name: "Review a second refund on the same line",
|
|
20295
|
+
decision_domain: "COMMERCE",
|
|
20296
|
+
when: { all: [{ field: "signals.prior_refund_count", operator: "GT", value: 0 }] },
|
|
20297
|
+
then: { action: "REQUIRE_REVIEW", severity: "elevated", sla_minutes: 240 },
|
|
20298
|
+
priority: 340,
|
|
20299
|
+
enabled: true,
|
|
20300
|
+
rationale: "A refund on an order line that was already refunded is the double-refund case."
|
|
20301
|
+
},
|
|
20302
|
+
{
|
|
20303
|
+
rule_id: "review_margin_floor",
|
|
20304
|
+
name: "Protect minimum margin",
|
|
20305
|
+
decision_domain: "COMMERCE",
|
|
20306
|
+
when: { all: [{ field: "signals.net_margin_percent", operator: "LT", value: 12 }] },
|
|
20307
|
+
then: { action: "REQUIRE_REVIEW", severity: "elevated", sla_minutes: 240 },
|
|
20308
|
+
priority: 300,
|
|
20309
|
+
enabled: true,
|
|
20310
|
+
rationale: "Review commerce actions that would take net margin below the merchant floor."
|
|
20311
|
+
},
|
|
20312
|
+
{
|
|
20313
|
+
rule_id: "review_inventory_floor",
|
|
20314
|
+
name: "Protect low inventory",
|
|
20315
|
+
decision_domain: "COMMERCE",
|
|
20316
|
+
when: { all: [{ field: "signals.available_inventory", operator: "LT", value: 10 }] },
|
|
20317
|
+
then: { action: "REQUIRE_REVIEW", severity: "elevated", sla_minutes: 240 },
|
|
20318
|
+
priority: 250,
|
|
20319
|
+
enabled: true,
|
|
20320
|
+
rationale: "Review fulfilment when source-of-truth inventory is below the safety floor."
|
|
20321
|
+
},
|
|
20322
|
+
{
|
|
20323
|
+
rule_id: "review_discount_stacking",
|
|
20324
|
+
name: "Review stacked promotions",
|
|
20325
|
+
decision_domain: "COMMERCE",
|
|
20326
|
+
when: { all: [{ field: "signals.discount_count", operator: "GT", value: 1 }] },
|
|
20327
|
+
then: { action: "REQUIRE_REVIEW", severity: "elevated", sla_minutes: 240 },
|
|
20328
|
+
priority: 200,
|
|
20329
|
+
enabled: true,
|
|
20330
|
+
rationale: "Review carts that combine more discount sources than the merchant allows."
|
|
20331
|
+
},
|
|
20332
|
+
{
|
|
20333
|
+
rule_id: "approve_routine_commerce",
|
|
20334
|
+
name: "Approve routine commerce actions",
|
|
20335
|
+
decision_domain: "COMMERCE",
|
|
20336
|
+
when: { all: [{ field: "decision_type", operator: "EXISTS", value: true }] },
|
|
20337
|
+
then: { action: "AUTO_APPROVE", severity: "routine", sla_minutes: 30 },
|
|
20338
|
+
priority: 10,
|
|
20339
|
+
enabled: true,
|
|
20340
|
+
rationale: "A storefront action proceeds when no floor is breached and nothing is held."
|
|
20341
|
+
}
|
|
20342
|
+
]
|
|
20343
|
+
},
|
|
20344
|
+
resolver_overrides: {
|
|
20345
|
+
// Whatever engine scored it, a storefront decision is a commerce decision.
|
|
20346
|
+
domain_by_engine: {
|
|
20347
|
+
finance: "COMMERCE",
|
|
20348
|
+
software: "COMMERCE",
|
|
20349
|
+
procure: "COMMERCE",
|
|
20350
|
+
hiring: "COMMERCE"
|
|
20351
|
+
},
|
|
20352
|
+
intent_domain_hints: [
|
|
20353
|
+
{
|
|
20354
|
+
domain: "COMMERCE",
|
|
20355
|
+
keywords: [
|
|
20356
|
+
"commerce",
|
|
20357
|
+
"order",
|
|
20358
|
+
"refund",
|
|
20359
|
+
"price",
|
|
20360
|
+
"promotion",
|
|
20361
|
+
"discount",
|
|
20362
|
+
"inventory",
|
|
20363
|
+
"listing",
|
|
20364
|
+
"cart",
|
|
20365
|
+
"checkout",
|
|
20366
|
+
"merchant",
|
|
20367
|
+
"storefront",
|
|
20368
|
+
"marketplace"
|
|
20369
|
+
]
|
|
20370
|
+
}
|
|
20371
|
+
],
|
|
20372
|
+
evidence_required_keywords: ["refund", "release"],
|
|
20373
|
+
missing_evidence_fields: ["purchase_order_id"],
|
|
20374
|
+
base_confidence: 0.6,
|
|
20375
|
+
attachment_confidence_bonus: 0.08,
|
|
20376
|
+
intake_confidence_bonus: 0.02,
|
|
20377
|
+
missing_evidence_penalty: 0.2
|
|
20378
|
+
},
|
|
20379
|
+
execution_templates: {
|
|
20380
|
+
SUCCEEDED: [
|
|
20381
|
+
"Apply the storefront change",
|
|
20382
|
+
"Record the decision dossier",
|
|
20383
|
+
"Notify the merchant"
|
|
20384
|
+
],
|
|
20385
|
+
NEEDS_EVIDENCE: ["Attach cost or refund evidence", "Confirm the approver", "Re-run evaluation"],
|
|
20386
|
+
FAILED: [
|
|
20387
|
+
"Hold the order or change",
|
|
20388
|
+
"Escalate to the merchant's approver",
|
|
20389
|
+
"Capture the override reason"
|
|
20390
|
+
]
|
|
20391
|
+
},
|
|
20392
|
+
ui_copy: {
|
|
20393
|
+
recommendation_success: "Proceed with the {domain} action; the merchant's floors hold.",
|
|
20394
|
+
recommendation_needs_evidence: "Attach the cost or refund evidence {domain} needs before approval.",
|
|
20395
|
+
recommendation_failed: "Hold the {domain} action for the merchant's approver."
|
|
20396
|
+
}
|
|
20397
|
+
};
|
|
20398
|
+
|
|
20399
|
+
// ../../../Decionis/apps/protocol/src/verticals/core/CorePack.ts
|
|
19484
20400
|
var coreVerticalPack = {
|
|
19485
20401
|
key: "core",
|
|
19486
20402
|
display_name: "Core Operations",
|
|
@@ -19559,7 +20475,7 @@ var coreVerticalPack = {
|
|
|
19559
20475
|
}
|
|
19560
20476
|
};
|
|
19561
20477
|
|
|
19562
|
-
//
|
|
20478
|
+
// ../../../Decionis/apps/protocol/src/verticals/devops/DevopsPack.ts
|
|
19563
20479
|
var devopsVerticalPack = {
|
|
19564
20480
|
key: "devops",
|
|
19565
20481
|
display_name: "DevOps & CI",
|
|
@@ -19685,7 +20601,7 @@ var devopsVerticalPack = {
|
|
|
19685
20601
|
}
|
|
19686
20602
|
};
|
|
19687
20603
|
|
|
19688
|
-
//
|
|
20604
|
+
// ../../../Decionis/apps/protocol/src/verticals/finance/FinancePack.ts
|
|
19689
20605
|
var financeVerticalPack = {
|
|
19690
20606
|
key: "finance",
|
|
19691
20607
|
display_name: "Financial Decision Authority",
|
|
@@ -19838,7 +20754,7 @@ var financeVerticalPack = {
|
|
|
19838
20754
|
}
|
|
19839
20755
|
};
|
|
19840
20756
|
|
|
19841
|
-
//
|
|
20757
|
+
// ../../../Decionis/apps/protocol/src/verticals/hospitality/HospitalityPack.ts
|
|
19842
20758
|
var hospitalityVerticalPack = {
|
|
19843
20759
|
key: "hospitality",
|
|
19844
20760
|
display_name: "Hospitality Operations",
|
|
@@ -19936,7 +20852,7 @@ var hospitalityVerticalPack = {
|
|
|
19936
20852
|
}
|
|
19937
20853
|
};
|
|
19938
20854
|
|
|
19939
|
-
//
|
|
20855
|
+
// ../../../Decionis/packages/shared/src/Verticals/OpsDualGate.ts
|
|
19940
20856
|
var OpsDualGate = class _OpsDualGate {
|
|
19941
20857
|
static requiredSpendFields = ["amount", "currency", "vendor_id"];
|
|
19942
20858
|
static authorizedRoles = /* @__PURE__ */ new Set([
|
|
@@ -20416,7 +21332,7 @@ function cleanOpsReason(gate) {
|
|
|
20416
21332
|
return OpsDualGate.cleanReason(gate);
|
|
20417
21333
|
}
|
|
20418
21334
|
|
|
20419
|
-
//
|
|
21335
|
+
// ../../../Decionis/apps/protocol/src/verticals/personal/PersonalPack.ts
|
|
20420
21336
|
var personalVerticalPack = {
|
|
20421
21337
|
key: "personal_productivity",
|
|
20422
21338
|
display_name: "Personal Productivity",
|
|
@@ -20522,7 +21438,7 @@ var personalVerticalPack = {
|
|
|
20522
21438
|
}
|
|
20523
21439
|
};
|
|
20524
21440
|
|
|
20525
|
-
//
|
|
21441
|
+
// ../../../Decionis/apps/protocol/src/verticals/salesforce/SalesforcePack.ts
|
|
20526
21442
|
var salesforceVerticalPack = {
|
|
20527
21443
|
key: "salesforce",
|
|
20528
21444
|
display_name: "Salesforce Revenue Execution",
|
|
@@ -20787,7 +21703,7 @@ var salesforceVerticalPack = {
|
|
|
20787
21703
|
}
|
|
20788
21704
|
};
|
|
20789
21705
|
|
|
20790
|
-
//
|
|
21706
|
+
// ../../../Decionis/apps/protocol/src/verticals/sap/SapPack.ts
|
|
20791
21707
|
var sapVerticalPack = {
|
|
20792
21708
|
key: "sap",
|
|
20793
21709
|
display_name: "SAP Execution Authority",
|
|
@@ -21053,7 +21969,7 @@ var sapVerticalPack = {
|
|
|
21053
21969
|
}
|
|
21054
21970
|
};
|
|
21055
21971
|
|
|
21056
|
-
//
|
|
21972
|
+
// ../../../Decionis/apps/protocol/src/verticals/template/TemplatePack.ts
|
|
21057
21973
|
var templateVerticalPack = {
|
|
21058
21974
|
key: "template",
|
|
21059
21975
|
display_name: "Template Vertical Pack",
|
|
@@ -21106,7 +22022,7 @@ var templateVerticalPack = {
|
|
|
21106
22022
|
}
|
|
21107
22023
|
};
|
|
21108
22024
|
|
|
21109
|
-
//
|
|
22025
|
+
// ../../../Decionis/apps/protocol/src/verticals/workday/WorkdayPack.ts
|
|
21110
22026
|
var workdayVerticalPack = {
|
|
21111
22027
|
key: "workday",
|
|
21112
22028
|
display_name: "Workday HR Governance",
|
|
@@ -21406,7 +22322,7 @@ var workdayVerticalPack = {
|
|
|
21406
22322
|
}
|
|
21407
22323
|
};
|
|
21408
22324
|
|
|
21409
|
-
//
|
|
22325
|
+
// ../../../Decionis/apps/protocol/src/verticals/workday-financials/WorkdayFinancialsPack.ts
|
|
21410
22326
|
var workdayFinancialsVerticalPack = {
|
|
21411
22327
|
key: "workday_financials",
|
|
21412
22328
|
display_name: "Workday Financials Circuit Breaker",
|
|
@@ -21627,7 +22543,7 @@ var workdayFinancialsVerticalPack = {
|
|
|
21627
22543
|
}
|
|
21628
22544
|
};
|
|
21629
22545
|
|
|
21630
|
-
//
|
|
22546
|
+
// ../../../Decionis/apps/protocol/src/verticals/workflows/WorkflowPacks.ts
|
|
21631
22547
|
var WorkflowPackFactory = class {
|
|
21632
22548
|
static create(config) {
|
|
21633
22549
|
return {
|
|
@@ -22272,11 +23188,12 @@ var workflowVerticalPacks = [
|
|
|
22272
23188
|
})
|
|
22273
23189
|
];
|
|
22274
23190
|
|
|
22275
|
-
//
|
|
23191
|
+
// ../../../Decionis/apps/protocol/src/verticals/VerticalRegistry.ts
|
|
22276
23192
|
var DEFAULT_VERTICAL_PACK_KEY = "core";
|
|
22277
23193
|
var packRegistry = new Map([
|
|
22278
23194
|
[coreVerticalPack.key, coreVerticalPack],
|
|
22279
23195
|
[affiliateRewardsVerticalPack.key, affiliateRewardsVerticalPack],
|
|
23196
|
+
[commerceVerticalPack.key, commerceVerticalPack],
|
|
22280
23197
|
[devopsVerticalPack.key, devopsVerticalPack],
|
|
22281
23198
|
[financeVerticalPack.key, financeVerticalPack],
|
|
22282
23199
|
[hospitalityVerticalPack.key, hospitalityVerticalPack],
|
|
@@ -22331,7 +23248,7 @@ function requireVerticalPack(key) {
|
|
|
22331
23248
|
return VerticalRegistry.require(key);
|
|
22332
23249
|
}
|
|
22333
23250
|
|
|
22334
|
-
//
|
|
23251
|
+
// ../../../Decionis/apps/protocol/src/verticals/VerticalResolver.ts
|
|
22335
23252
|
var VerticalResolver = class _VerticalResolver {
|
|
22336
23253
|
static async resolveForRequest(input) {
|
|
22337
23254
|
const requested = getVerticalPack(input.requestedPackKey);
|
|
@@ -22377,13 +23294,13 @@ async function resolveVerticalPackForRequest(input) {
|
|
|
22377
23294
|
return VerticalResolver.resolveForRequest(input);
|
|
22378
23295
|
}
|
|
22379
23296
|
|
|
22380
|
-
//
|
|
23297
|
+
// ../../../Decionis/apps/protocol/src/decision-chains/DecisionChains.ts
|
|
22381
23298
|
import { randomUUID as randomUUID7 } from "crypto";
|
|
22382
23299
|
|
|
22383
|
-
//
|
|
23300
|
+
// ../../../Decionis/apps/protocol/src/integrity/DossierProofVerifier.ts
|
|
22384
23301
|
import { createHash as createHash12, verify } from "crypto";
|
|
22385
23302
|
|
|
22386
|
-
//
|
|
23303
|
+
// ../../../Decionis/apps/protocol/src/integrity/DossierProofBundle.ts
|
|
22387
23304
|
import {
|
|
22388
23305
|
createHash as createHash11,
|
|
22389
23306
|
createPrivateKey,
|
|
@@ -22618,7 +23535,7 @@ function buildDecisionDossierPersistedProofBundle(input) {
|
|
|
22618
23535
|
return DossierProofBundle.buildDecisionDossierPersistedProofBundle(input);
|
|
22619
23536
|
}
|
|
22620
23537
|
|
|
22621
|
-
//
|
|
23538
|
+
// ../../../Decionis/apps/protocol/src/integrity/DossierProofVerifier.ts
|
|
22622
23539
|
var PROOF_ARTIFACT_SHAPES = {
|
|
22623
23540
|
portable_artifact: {
|
|
22624
23541
|
document_path: "/portable_artifact",
|
|
@@ -22868,7 +23785,7 @@ function verifyDecisionDossierProofBundle(bundle, dossierPayload) {
|
|
|
22868
23785
|
return DossierProofVerifier.verifyDecisionDossierProofBundle(bundle, dossierPayload);
|
|
22869
23786
|
}
|
|
22870
23787
|
|
|
22871
|
-
//
|
|
23788
|
+
// ../../../Decionis/apps/protocol/src/decision-chains/DecisionChains.ts
|
|
22872
23789
|
var DECISION_CHAIN_EVIDENCE_LIMIT = DECISION_CHAIN_PROJECTION_LIMIT;
|
|
22873
23790
|
var SHA256_HEX = /^[0-9a-f]{64}$/;
|
|
22874
23791
|
var LEDGER_ACTION_ORDER = {
|
|
@@ -23372,7 +24289,8 @@ var DecisionChains = class {
|
|
|
23372
24289
|
valid: input.ledgerVerification.valid,
|
|
23373
24290
|
complete: input.ledgerVerification.complete,
|
|
23374
24291
|
checked: input.ledgerVerification.checked,
|
|
23375
|
-
max_entries: input.ledgerVerification.maxEntries
|
|
24292
|
+
max_entries: input.ledgerVerification.maxEntries,
|
|
24293
|
+
...input.ledgerVerification.orphaned?.length ? { orphaned: input.ledgerVerification.orphaned } : {}
|
|
23376
24294
|
}
|
|
23377
24295
|
} : {},
|
|
23378
24296
|
links,
|
|
@@ -23572,7 +24490,7 @@ function finalizeDecisionChainLinkInput(input) {
|
|
|
23572
24490
|
return DecisionChains.finalizeDecisionChainLinkInput(input);
|
|
23573
24491
|
}
|
|
23574
24492
|
|
|
23575
|
-
//
|
|
24493
|
+
// ../../../Decionis/apps/protocol/src/support/PanDetection.ts
|
|
23576
24494
|
var PanDetection = class _PanDetection {
|
|
23577
24495
|
static UUID_SHAPE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
23578
24496
|
static toDigits(value) {
|
|
@@ -23652,7 +24570,7 @@ function findRawPanPath(value, path, visited = /* @__PURE__ */ new Set()) {
|
|
|
23652
24570
|
return PanDetection.findRawPanPath(value, path, visited);
|
|
23653
24571
|
}
|
|
23654
24572
|
|
|
23655
|
-
//
|
|
24573
|
+
// ../../../Decionis/apps/protocol/src/support/ProtocolUrls.ts
|
|
23656
24574
|
var ProtocolUrls = class {
|
|
23657
24575
|
static getProtocolPublicBaseUrl() {
|
|
23658
24576
|
const raw = process.env.DECIONIS_PROTOCOL_PUBLIC_BASE_URL?.trim() ?? process.env.DECIONIS_PROTOCOL_BASE_URL?.trim() ?? "https://protocol.decionis.com";
|
|
@@ -23663,7 +24581,7 @@ function getProtocolPublicBaseUrl() {
|
|
|
23663
24581
|
return ProtocolUrls.getProtocolPublicBaseUrl();
|
|
23664
24582
|
}
|
|
23665
24583
|
|
|
23666
|
-
//
|
|
24584
|
+
// ../../../Decionis/apps/protocol/src/evaluate-decision/EvaluateDecisionParsing.ts
|
|
23667
24585
|
var EvaluateDecisionParsing = class {
|
|
23668
24586
|
static parseEvaluateMode(value) {
|
|
23669
24587
|
return normalizeEnforcementMode(value);
|
|
@@ -23712,6 +24630,19 @@ var EvaluateDecisionParsing = class {
|
|
|
23712
24630
|
message: "context.authority_requirement is reserved for Decionis-issued policy output"
|
|
23713
24631
|
};
|
|
23714
24632
|
}
|
|
24633
|
+
if (Object.prototype.hasOwnProperty.call(context, RUNTIME_ATTRIBUTION_FACT)) {
|
|
24634
|
+
return {
|
|
24635
|
+
ok: false,
|
|
24636
|
+
message: `context.${RUNTIME_ATTRIBUTION_FACT} is reserved: Decionis computes it from the reported runtime signals, so a caller cannot assert what the platform established`
|
|
24637
|
+
};
|
|
24638
|
+
}
|
|
24639
|
+
const runtimeSignals = RuntimeSignals.parse(context);
|
|
24640
|
+
if (!runtimeSignals.ok) {
|
|
24641
|
+
return {
|
|
24642
|
+
ok: false,
|
|
24643
|
+
message: `${runtimeSignals.path} is invalid (${runtimeSignals.message})`
|
|
24644
|
+
};
|
|
24645
|
+
}
|
|
23715
24646
|
const verticalPack = asString2(record.vertical_pack) ?? asString2(context.vertical_pack);
|
|
23716
24647
|
const workflowKey = asString2(record.workflow_key) ?? asString2(context.workflow_key);
|
|
23717
24648
|
const parsedDecisionChain = parseDecisionChainRequest(record.decision_chain);
|
|
@@ -23943,7 +24874,7 @@ function hydrateCachedEvaluateResponse(existing) {
|
|
|
23943
24874
|
return EvaluateDecisionParsing.hydrateCachedEvaluateResponse(existing);
|
|
23944
24875
|
}
|
|
23945
24876
|
|
|
23946
|
-
//
|
|
24877
|
+
// ../../../Decionis/apps/protocol/src/webex/WebexGovernance.ts
|
|
23947
24878
|
var WebexGovernance = class {
|
|
23948
24879
|
static parseWebexAgentIntentRequest(input, idempotencyHeader) {
|
|
23949
24880
|
const record = asRecord3(input);
|
|
@@ -24281,7 +25212,7 @@ function buildWebexDossierEnhancements(input, response, generatedAt) {
|
|
|
24281
25212
|
return WebexGovernance.buildWebexDossierEnhancements(input, response, generatedAt);
|
|
24282
25213
|
}
|
|
24283
25214
|
|
|
24284
|
-
//
|
|
25215
|
+
// ../../../Decionis/apps/protocol/src/dossiers/DossierBuilder.ts
|
|
24285
25216
|
var DossierBuilder = class _DossierBuilder {
|
|
24286
25217
|
/**
|
|
24287
25218
|
* One canonical, public-safe snapshot shared by proof and authority evidence.
|
|
@@ -24291,6 +25222,7 @@ var DossierBuilder = class _DossierBuilder {
|
|
|
24291
25222
|
*/
|
|
24292
25223
|
static buildInputsSnapshot(input, evaluationId) {
|
|
24293
25224
|
const context = input.context ?? {};
|
|
25225
|
+
const runtimeAttribution = _DossierBuilder.resolveRuntimeAttribution(input);
|
|
24294
25226
|
return {
|
|
24295
25227
|
decision_type: input.decision_type,
|
|
24296
25228
|
channel: input.channel,
|
|
@@ -24304,6 +25236,7 @@ var DossierBuilder = class _DossierBuilder {
|
|
|
24304
25236
|
transaction_type: input.transaction_type,
|
|
24305
25237
|
amount: input.amount,
|
|
24306
25238
|
risk_score: input.risk_score,
|
|
25239
|
+
...runtimeAttribution ? { runtime_attribution: runtimeAttribution } : {},
|
|
24307
25240
|
context_commitment: {
|
|
24308
25241
|
version: "1.0",
|
|
24309
25242
|
canonicalization: "RFC8785/JCS",
|
|
@@ -24393,11 +25326,44 @@ var DossierBuilder = class _DossierBuilder {
|
|
|
24393
25326
|
};
|
|
24394
25327
|
return Object.keys(refs).length > 0 ? refs : null;
|
|
24395
25328
|
}
|
|
25329
|
+
/**
|
|
25330
|
+
* How many signals the decision was evaluated against, for the signed
|
|
25331
|
+
* portable artifact.
|
|
25332
|
+
*
|
|
25333
|
+
* The excluded keys are routing and identity, not inputs to a verdict:
|
|
25334
|
+
* counting them would overstate, in a claim an auditor reads, how much
|
|
25335
|
+
* evidence the decision actually had. The runtime signals an enforcement
|
|
25336
|
+
* boundary reports are the same kind of thing — they say which door the
|
|
25337
|
+
* action came through and what software proposed it, which the artifact
|
|
25338
|
+
* records in its own right rather than as two more signals.
|
|
25339
|
+
*/
|
|
24396
25340
|
static resolvePortableSignalsEvaluated(input) {
|
|
24397
25341
|
const context = asRecord3(input.context);
|
|
24398
|
-
|
|
24399
|
-
|
|
24400
|
-
|
|
25342
|
+
const excluded = /* @__PURE__ */ new Set([
|
|
25343
|
+
"workflow_key",
|
|
25344
|
+
"vertical_pack",
|
|
25345
|
+
"trust_context",
|
|
25346
|
+
...RUNTIME_SIGNAL_ROOTS
|
|
25347
|
+
]);
|
|
25348
|
+
return asNumber(context.signals_evaluated) ?? Object.keys(context).filter((key) => !excluded.has(key)).length;
|
|
25349
|
+
}
|
|
25350
|
+
/**
|
|
25351
|
+
* The boundary that admitted the action and the artifact that proposed it,
|
|
25352
|
+
* as the report reached the authority, with the platform's own statement
|
|
25353
|
+
* about how far that report goes.
|
|
25354
|
+
*
|
|
25355
|
+
* This is the one place raw context values enter the dossier, and it is
|
|
25356
|
+
* deliberate: the evidence chain the Decision Dossier exists to carry runs
|
|
25357
|
+
* from artifact provenance through workload identity to the effect, and a
|
|
25358
|
+
* digest of the whole context cannot answer *which boundary admitted this*
|
|
25359
|
+
* offline. Every field here is an identifier, a digest or a level the
|
|
25360
|
+
* operator's own manifest set; the producer keeps the container, pod and
|
|
25361
|
+
* node out of what it binds, so none of them can arrive.
|
|
25362
|
+
*/
|
|
25363
|
+
static resolveRuntimeAttribution(input) {
|
|
25364
|
+
const parsed = RuntimeSignals.parse(asRecord3(input.context));
|
|
25365
|
+
if (!parsed.ok) return null;
|
|
25366
|
+
return RuntimeSignals.evidenceOf(RuntimeSignals.attributionOf(parsed));
|
|
24401
25367
|
}
|
|
24402
25368
|
static buildPortableDecisionDossierCore(input) {
|
|
24403
25369
|
const protocolEnvelope = classifyAuthorityProtocolEnvelope(
|
|
@@ -24670,7 +25636,7 @@ function buildDecisionInputsSnapshot(input, evaluationId) {
|
|
|
24670
25636
|
return DossierBuilder.buildInputsSnapshot(input, evaluationId);
|
|
24671
25637
|
}
|
|
24672
25638
|
|
|
24673
|
-
//
|
|
25639
|
+
// ../../../Decionis/apps/protocol/src/reproduce/ReproduceDecision.ts
|
|
24674
25640
|
var POLICY_GRAPH_1_1_SEMANTICS = {
|
|
24675
25641
|
protocol_version: "1.1",
|
|
24676
25642
|
evaluator_version: "policy-graph/1.1",
|
|
@@ -25101,7 +26067,7 @@ async function reproduceDecisionFromDossierPayload(input) {
|
|
|
25101
26067
|
});
|
|
25102
26068
|
}
|
|
25103
26069
|
|
|
25104
|
-
//
|
|
26070
|
+
// ../../../Decionis/apps/protocol/src/support/FeatureFlags.ts
|
|
25105
26071
|
var FeatureFlags = class {
|
|
25106
26072
|
static parseFeatureFlagAllowlist(raw) {
|
|
25107
26073
|
return new Set(
|
|
@@ -25128,7 +26094,7 @@ function resolveFeatureFlagState(flag) {
|
|
|
25128
26094
|
return FeatureFlags.resolveFeatureFlagState(flag);
|
|
25129
26095
|
}
|
|
25130
26096
|
|
|
25131
|
-
//
|
|
26097
|
+
// ../../../Decionis/apps/protocol/src/evaluate-decision/EvaluateDecisionGovernance.ts
|
|
25132
26098
|
var DOCKER_DESKTOP_GOVERNED_LIMIT = 25;
|
|
25133
26099
|
var EvaluateDecisionGovernance = class _EvaluateDecisionGovernance {
|
|
25134
26100
|
/**
|
|
@@ -25246,7 +26212,7 @@ function resolveEvaluateRolloutPolicy(store, input) {
|
|
|
25246
26212
|
return EvaluateDecisionGovernance.resolveEvaluateRolloutPolicy(store, input);
|
|
25247
26213
|
}
|
|
25248
26214
|
|
|
25249
|
-
//
|
|
26215
|
+
// ../../../Decionis/apps/protocol/src/evaluate-decision/EvaluateDecisionResolution.ts
|
|
25250
26216
|
import { createHash as createHash13, randomUUID as randomUUID8 } from "crypto";
|
|
25251
26217
|
var POLICY_BUNDLE_UNRESOLVED_SENTINEL_ID = "00000000-0000-0000-0000-000000000000";
|
|
25252
26218
|
var EvaluateDecisionResolution = class {
|
|
@@ -25446,9 +26412,10 @@ function appendEvaluateDecisionLedgerEvent(store, input) {
|
|
|
25446
26412
|
return EvaluateDecisionResolution.appendEvaluateDecisionLedgerEvent(store, input);
|
|
25447
26413
|
}
|
|
25448
26414
|
|
|
25449
|
-
//
|
|
26415
|
+
// ../../../Decionis/apps/protocol/src/authority/AuthorityRequirementIssuer.ts
|
|
25450
26416
|
import { randomBytes, randomUUID as randomUUID9 } from "crypto";
|
|
25451
26417
|
var AuthorityRequirementIssuer = class _AuthorityRequirementIssuer {
|
|
26418
|
+
static MANAGED_CEREMONY_LIFETIME_MS = 5 * 6e4;
|
|
25452
26419
|
requirementId;
|
|
25453
26420
|
nonce;
|
|
25454
26421
|
constructor(dependencies = {}) {
|
|
@@ -25480,10 +26447,12 @@ var AuthorityRequirementIssuer = class _AuthorityRequirementIssuer {
|
|
|
25480
26447
|
const intentExpiresAtMs = Date.parse(
|
|
25481
26448
|
typeof agentSafe.expires_at === "string" ? agentSafe.expires_at : ""
|
|
25482
26449
|
);
|
|
26450
|
+
const chained = authorityPolicy.resolution.tiers !== void 0;
|
|
25483
26451
|
const expiresAt = new Date(
|
|
25484
26452
|
Math.min(
|
|
25485
26453
|
issuedAtMs + authorityPolicy.expires_in_seconds * 1e3,
|
|
25486
|
-
Number.isFinite(intentExpiresAtMs) ? intentExpiresAtMs : Number.POSITIVE_INFINITY
|
|
26454
|
+
Number.isFinite(intentExpiresAtMs) ? intentExpiresAtMs : Number.POSITIVE_INFINITY,
|
|
26455
|
+
managedEscalationId && !chained ? issuedAtMs + _AuthorityRequirementIssuer.MANAGED_CEREMONY_LIFETIME_MS : Number.POSITIVE_INFINITY
|
|
25487
26456
|
)
|
|
25488
26457
|
).toISOString();
|
|
25489
26458
|
return AuthorityRequirementSchema.parse({
|
|
@@ -25507,7 +26476,13 @@ var AuthorityRequirementIssuer = class _AuthorityRequirementIssuer {
|
|
|
25507
26476
|
},
|
|
25508
26477
|
resolution: {
|
|
25509
26478
|
...authorityPolicy.resolution,
|
|
25510
|
-
fallback_role_ids: [...authorityPolicy.resolution.fallback_role_ids]
|
|
26479
|
+
fallback_role_ids: [...authorityPolicy.resolution.fallback_role_ids],
|
|
26480
|
+
...authorityPolicy.resolution.tiers ? {
|
|
26481
|
+
tiers: authorityPolicy.resolution.tiers.map((tier) => ({
|
|
26482
|
+
priority: tier.priority,
|
|
26483
|
+
principal_ids: [...tier.principal_ids]
|
|
26484
|
+
}))
|
|
26485
|
+
} : {}
|
|
25511
26486
|
},
|
|
25512
26487
|
originator: {
|
|
25513
26488
|
organization_id: input.request.org_id,
|
|
@@ -25650,7 +26625,7 @@ var AuthorityRequirementIssuer = class _AuthorityRequirementIssuer {
|
|
|
25650
26625
|
}
|
|
25651
26626
|
};
|
|
25652
26627
|
|
|
25653
|
-
//
|
|
26628
|
+
// ../../../Decionis/apps/protocol/src/execution-binding/ExecutionBindingBuilder.ts
|
|
25654
26629
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
25655
26630
|
var ExecutionBindingBuilder = class _ExecutionBindingBuilder {
|
|
25656
26631
|
static build(input) {
|
|
@@ -25878,7 +26853,7 @@ function normalizeDigest(value) {
|
|
|
25878
26853
|
return /^sha256:[0-9a-f]{64}$/.test(normalized) ? normalized : null;
|
|
25879
26854
|
}
|
|
25880
26855
|
|
|
25881
|
-
//
|
|
26856
|
+
// ../../../Decionis/apps/protocol/src/decision-chains/SequenceContextProvider.ts
|
|
25882
26857
|
var SEQUENCE_CONTEXT_SCHEMA_VERSION = "1.0";
|
|
25883
26858
|
var SEQUENCE_CONTEXT_KEY = "sequence";
|
|
25884
26859
|
function actionFromLink(link) {
|
|
@@ -25967,7 +26942,7 @@ function withSequenceContext(context, sequence) {
|
|
|
25967
26942
|
};
|
|
25968
26943
|
}
|
|
25969
26944
|
|
|
25970
|
-
//
|
|
26945
|
+
// ../../../Decionis/apps/protocol/src/evaluate-decision/EvaluateDecisionRoutes.ts
|
|
25971
26946
|
function registerEvaluateDecisionRoutes(app, deps) {
|
|
25972
26947
|
const { store } = deps;
|
|
25973
26948
|
const authorityRequirementIssuer = new AuthorityRequirementIssuer();
|
|
@@ -26438,6 +27413,12 @@ function registerEvaluateDecisionRoutes(app, deps) {
|
|
|
26438
27413
|
}
|
|
26439
27414
|
}
|
|
26440
27415
|
app.log.error({ err }, "Evaluate-decision execution failed");
|
|
27416
|
+
if (err instanceof ProtocolStoreValidationError && err.code === AUDIT_LEDGER_NOT_APPENDABLE) {
|
|
27417
|
+
return reply.code(500).send({
|
|
27418
|
+
error: AUDIT_LEDGER_NOT_APPENDABLE,
|
|
27419
|
+
message: "Failed to evaluate decision: the organisation's audit ledger has no unique head and refuses appends until it is repaired"
|
|
27420
|
+
});
|
|
27421
|
+
}
|
|
26441
27422
|
return reply.code(500).send({
|
|
26442
27423
|
error: "EVALUATION_FAILED",
|
|
26443
27424
|
message: "Failed to evaluate decision"
|
|
@@ -26474,7 +27455,7 @@ function registerEvaluateDecisionRoutes(app, deps) {
|
|
|
26474
27455
|
app.post("/v1/protocol/decision-dossiers/reproduce", reproduceDecisionHandler);
|
|
26475
27456
|
}
|
|
26476
27457
|
|
|
26477
|
-
//
|
|
27458
|
+
// ../../../Decionis/apps/protocol/src/webex/WebexRoutes.ts
|
|
26478
27459
|
function registerWebexRoutes(app, deps) {
|
|
26479
27460
|
const { store } = deps;
|
|
26480
27461
|
const evaluateWebexAgentIntentHandler = async (req, reply) => {
|
|
@@ -26644,13 +27625,13 @@ function registerWebexRoutes(app, deps) {
|
|
|
26644
27625
|
app.post("/v1/protocol/webex/agent-intents/evaluate", evaluateWebexAgentIntentHandler);
|
|
26645
27626
|
}
|
|
26646
27627
|
|
|
26647
|
-
//
|
|
27628
|
+
// ../../../Decionis/apps/protocol/src/surface-verify/SapVerifyRoutes.ts
|
|
26648
27629
|
import { randomUUID as randomUUID11 } from "crypto";
|
|
26649
27630
|
|
|
26650
|
-
//
|
|
27631
|
+
// ../../../Decionis/apps/protocol/src/verticals/sap/SapSurface.ts
|
|
26651
27632
|
import { createHash as createHash15 } from "crypto";
|
|
26652
27633
|
|
|
26653
|
-
//
|
|
27634
|
+
// ../../../Decionis/apps/protocol/src/verticals/shared/DuplicateDetection.ts
|
|
26654
27635
|
var DuplicateDetection = class _DuplicateDetection {
|
|
26655
27636
|
/**
|
|
26656
27637
|
* Vendor + invoice/amount fingerprint for duplicate-payment detection, or null.
|
|
@@ -26704,7 +27685,7 @@ async function deriveDuplicateFacts(input) {
|
|
|
26704
27685
|
return DuplicateDetection.deriveFacts(input);
|
|
26705
27686
|
}
|
|
26706
27687
|
|
|
26707
|
-
//
|
|
27688
|
+
// ../../../Decionis/apps/protocol/src/verticals/sap/SapSurface.ts
|
|
26708
27689
|
var REQUIRED_STATE_FIELDS = ["amount", "currency", "vendor_id", "cost_center"];
|
|
26709
27690
|
var AUTHORIZED_ROLES = /* @__PURE__ */ new Set(["ProcurementManager", "TreasuryHead", "Controller", "CFO"]);
|
|
26710
27691
|
var PO_TREASURY_THRESHOLD = 5e4;
|
|
@@ -27033,7 +28014,7 @@ async function deriveSapDuplicateFacts(input) {
|
|
|
27033
28014
|
return SapSurface.deriveDuplicateFacts(input);
|
|
27034
28015
|
}
|
|
27035
28016
|
|
|
27036
|
-
//
|
|
28017
|
+
// ../../../Decionis/apps/protocol/src/surface-verify/SurfaceVerifyShared.ts
|
|
27037
28018
|
var SAP_DEFAULT_ORG_ID = "5ab00000-0000-4000-8000-000000000001";
|
|
27038
28019
|
var SAP_VERIFY_BASE_URL = "https://verify.decionis.com";
|
|
27039
28020
|
var OPS_DEFAULT_ORG_ID = "09500000-0000-4000-8000-000000000001";
|
|
@@ -27041,7 +28022,7 @@ var WORKDAY_DEFAULT_ORG_ID = "d0d00000-0000-4000-8000-000000000001";
|
|
|
27041
28022
|
var WORKDAY_FIN_DEFAULT_ORG_ID = "d0f00000-0000-4000-8000-000000000001";
|
|
27042
28023
|
var DUPLICATE_LOOKBACK_DAYS = 90;
|
|
27043
28024
|
|
|
27044
|
-
//
|
|
28025
|
+
// ../../../Decionis/apps/protocol/src/surface-verify/SapVerifyRoutes.ts
|
|
27045
28026
|
function registerSapVerifyRoutes(app, deps) {
|
|
27046
28027
|
const { store } = deps;
|
|
27047
28028
|
const protocolAuthLookup = deps.authLookup ?? null;
|
|
@@ -27145,10 +28126,10 @@ function registerSapVerifyRoutes(app, deps) {
|
|
|
27145
28126
|
);
|
|
27146
28127
|
}
|
|
27147
28128
|
|
|
27148
|
-
//
|
|
28129
|
+
// ../../../Decionis/apps/protocol/src/surface-verify/SalesforceVerifyRoutes.ts
|
|
27149
28130
|
import { randomUUID as randomUUID12 } from "crypto";
|
|
27150
28131
|
|
|
27151
|
-
//
|
|
28132
|
+
// ../../../Decionis/apps/protocol/src/verticals/salesforce/SalesforceSurface.ts
|
|
27152
28133
|
import { createHash as createHash16 } from "crypto";
|
|
27153
28134
|
var MATNR_MAX_LENGTH = 18;
|
|
27154
28135
|
var MANUAL_DISCOUNT_THRESHOLD_PCT = 15;
|
|
@@ -27460,162 +28441,7 @@ function resolveSalesforceMode(payload) {
|
|
|
27460
28441
|
return SalesforceSurface.resolveMode(payload);
|
|
27461
28442
|
}
|
|
27462
28443
|
|
|
27463
|
-
//
|
|
27464
|
-
var FETCH_TIMEOUT_MS = 2500;
|
|
27465
|
-
var DEFAULTS = {
|
|
27466
|
-
servicePath: "/sap/opu/odata/sap/API_PRODUCT_SRV",
|
|
27467
|
-
entitySet: "A_ProductValuationArea",
|
|
27468
|
-
skuProperty: "Product",
|
|
27469
|
-
costProperty: "StandardPrice"
|
|
27470
|
-
};
|
|
27471
|
-
var SapCostBasis = class _SapCostBasis {
|
|
27472
|
-
/**
|
|
27473
|
-
* Resolve the S/4HANA OData cost destination. With `orgId`, a per-org override in
|
|
27474
|
-
* `DECIONIS_SAP_SOR_BY_ORG` wins (multi-tenant); otherwise the global env destination
|
|
27475
|
-
* is used. Returns null when neither is configured.
|
|
27476
|
-
*/
|
|
27477
|
-
static resolveConfig(env = process.env, orgId) {
|
|
27478
|
-
const o = _SapCostBasis.readPerOrgCostOverride(env, orgId);
|
|
27479
|
-
const baseUrl = String(o?.url ?? env.DECIONIS_SAP_SOR_URL ?? "").trim();
|
|
27480
|
-
if (!baseUrl) return null;
|
|
27481
|
-
return {
|
|
27482
|
-
baseUrl: baseUrl.replace(/\/$/, ""),
|
|
27483
|
-
token: String(o?.token ?? env.DECIONIS_SAP_SOR_TOKEN ?? "").trim() || null,
|
|
27484
|
-
servicePath: String(
|
|
27485
|
-
o?.servicePath ?? env.DECIONIS_SAP_SOR_SERVICE_PATH ?? DEFAULTS.servicePath
|
|
27486
|
-
).replace(/\/$/, ""),
|
|
27487
|
-
entitySet: String(o?.entitySet ?? env.DECIONIS_SAP_SOR_ENTITY ?? DEFAULTS.entitySet),
|
|
27488
|
-
skuProperty: String(
|
|
27489
|
-
o?.skuProperty ?? env.DECIONIS_SAP_SOR_SKU_PROPERTY ?? DEFAULTS.skuProperty
|
|
27490
|
-
),
|
|
27491
|
-
costProperty: String(
|
|
27492
|
-
o?.costProperty ?? env.DECIONIS_SAP_SOR_COST_PROPERTY ?? DEFAULTS.costProperty
|
|
27493
|
-
)
|
|
27494
|
-
};
|
|
27495
|
-
}
|
|
27496
|
-
/** The destination is operator-configured, but require TLS and reject internal hosts. */
|
|
27497
|
-
static isSafeUrl(rawUrl) {
|
|
27498
|
-
let url;
|
|
27499
|
-
try {
|
|
27500
|
-
url = new URL(rawUrl);
|
|
27501
|
-
} catch {
|
|
27502
|
-
return false;
|
|
27503
|
-
}
|
|
27504
|
-
if (url.protocol !== "https:") return false;
|
|
27505
|
-
const h = url.hostname.toLowerCase().replace(/^\[|\]$/g, "");
|
|
27506
|
-
if (h === "localhost" || h === "127.0.0.1" || h === "::1" || h === "169.254.169.254" || // cloud metadata
|
|
27507
|
-
h.endsWith(".local") || h.endsWith(".internal") || h.startsWith("10.") || h.startsWith("192.168.") || /^172\.(1[6-9]|2\d|3[01])\./.test(h)) {
|
|
27508
|
-
return false;
|
|
27509
|
-
}
|
|
27510
|
-
return true;
|
|
27511
|
-
}
|
|
27512
|
-
static buildCostQueryUrl(config, skus) {
|
|
27513
|
-
const filter = skus.map((sku) => `${config.skuProperty} eq ${_SapCostBasis.odataString(sku)}`).join(" or ");
|
|
27514
|
-
const params = new URLSearchParams({
|
|
27515
|
-
$select: `${config.skuProperty},${config.costProperty}`,
|
|
27516
|
-
$filter: filter,
|
|
27517
|
-
$format: "json"
|
|
27518
|
-
});
|
|
27519
|
-
return `${config.baseUrl}${config.servicePath}/${config.entitySet}?${params.toString()}`;
|
|
27520
|
-
}
|
|
27521
|
-
/**
|
|
27522
|
-
* Returns SKU → SAP cost (or null when SAP can't confirm it). Every requested SKU
|
|
27523
|
-
* is present in the map. Fail-safe: returns all-null on SSRF rejection, missing
|
|
27524
|
-
* transport, non-2xx, or error.
|
|
27525
|
-
*/
|
|
27526
|
-
static async fetchCostBasis(config, skus, options = {}) {
|
|
27527
|
-
const result = /* @__PURE__ */ new Map();
|
|
27528
|
-
const unique = [...new Set(skus.filter(Boolean))];
|
|
27529
|
-
for (const sku of unique) result.set(sku, null);
|
|
27530
|
-
if (unique.length === 0) return result;
|
|
27531
|
-
if (!_SapCostBasis.isSafeUrl(config.baseUrl)) return result;
|
|
27532
|
-
const transport = options.transport ?? globalThis.fetch;
|
|
27533
|
-
if (!transport) return result;
|
|
27534
|
-
const controller = new AbortController();
|
|
27535
|
-
const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
|
|
27536
|
-
try {
|
|
27537
|
-
const res = await transport(_SapCostBasis.buildCostQueryUrl(config, unique), {
|
|
27538
|
-
method: "GET",
|
|
27539
|
-
headers: {
|
|
27540
|
-
accept: "application/json",
|
|
27541
|
-
...config.token ? { authorization: `Bearer ${config.token}` } : {}
|
|
27542
|
-
},
|
|
27543
|
-
signal: controller.signal
|
|
27544
|
-
});
|
|
27545
|
-
if (!res.ok) return result;
|
|
27546
|
-
const rows = _SapCostBasis.extractRows(await res.json());
|
|
27547
|
-
for (const row of rows) {
|
|
27548
|
-
const sku = row[config.skuProperty];
|
|
27549
|
-
if (typeof sku !== "string" || !result.has(sku)) continue;
|
|
27550
|
-
const cost = Number(row[config.costProperty]);
|
|
27551
|
-
result.set(sku, Number.isFinite(cost) ? cost : null);
|
|
27552
|
-
}
|
|
27553
|
-
} catch {
|
|
27554
|
-
} finally {
|
|
27555
|
-
clearTimeout(timer);
|
|
27556
|
-
}
|
|
27557
|
-
return result;
|
|
27558
|
-
}
|
|
27559
|
-
/**
|
|
27560
|
-
* Override each order line's `cost_basis` with the SAP cost when available; lines
|
|
27561
|
-
* SAP can't confirm keep their existing (payload) cost. Pure.
|
|
27562
|
-
*/
|
|
27563
|
-
static applyCostBasis(payload, costMap) {
|
|
27564
|
-
const items = Array.isArray(payload.order_items) ? payload.order_items : [];
|
|
27565
|
-
return {
|
|
27566
|
-
...payload,
|
|
27567
|
-
order_items: items.map((it) => {
|
|
27568
|
-
const matnr = String(it.matnr ?? "");
|
|
27569
|
-
const sapCost = matnr ? costMap.get(matnr) : null;
|
|
27570
|
-
return sapCost != null ? { ...it, cost_basis: sapCost } : it;
|
|
27571
|
-
})
|
|
27572
|
-
};
|
|
27573
|
-
}
|
|
27574
|
-
/** True when at least one SKU got an authoritative SAP cost. */
|
|
27575
|
-
static hasResolvedCost(costMap) {
|
|
27576
|
-
for (const value of costMap.values()) if (value != null) return true;
|
|
27577
|
-
return false;
|
|
27578
|
-
}
|
|
27579
|
-
/** Per-org SAP destination override from `DECIONIS_SAP_SOR_BY_ORG` (JSON keyed by org id). */
|
|
27580
|
-
static readPerOrgCostOverride(env, orgId) {
|
|
27581
|
-
if (!orgId) return null;
|
|
27582
|
-
const raw = env.DECIONIS_SAP_SOR_BY_ORG;
|
|
27583
|
-
if (!raw) return null;
|
|
27584
|
-
try {
|
|
27585
|
-
const map = JSON.parse(raw);
|
|
27586
|
-
const entry = map && typeof map === "object" ? map[orgId] : null;
|
|
27587
|
-
return entry && typeof entry === "object" ? entry : null;
|
|
27588
|
-
} catch {
|
|
27589
|
-
return null;
|
|
27590
|
-
}
|
|
27591
|
-
}
|
|
27592
|
-
static odataString(value) {
|
|
27593
|
-
return `'${value.replace(/'/g, "''")}'`;
|
|
27594
|
-
}
|
|
27595
|
-
/** OData v2 (`d.results`) and v4 (`value`) both supported. */
|
|
27596
|
-
static extractRows(json) {
|
|
27597
|
-
if (!json || typeof json !== "object") return [];
|
|
27598
|
-
const v2 = json.d?.results;
|
|
27599
|
-
if (Array.isArray(v2)) return v2;
|
|
27600
|
-
const v4 = json.value;
|
|
27601
|
-
if (Array.isArray(v4)) return v4;
|
|
27602
|
-
return [];
|
|
27603
|
-
}
|
|
27604
|
-
};
|
|
27605
|
-
function resolveSapCostConfig(env = process.env, orgId) {
|
|
27606
|
-
return SapCostBasis.resolveConfig(env, orgId);
|
|
27607
|
-
}
|
|
27608
|
-
async function fetchSapCostBasis(config, skus, options = {}) {
|
|
27609
|
-
return SapCostBasis.fetchCostBasis(config, skus, options);
|
|
27610
|
-
}
|
|
27611
|
-
function applySapCostBasis(payload, costMap) {
|
|
27612
|
-
return SapCostBasis.applyCostBasis(payload, costMap);
|
|
27613
|
-
}
|
|
27614
|
-
function hasResolvedCost(costMap) {
|
|
27615
|
-
return SapCostBasis.hasResolvedCost(costMap);
|
|
27616
|
-
}
|
|
27617
|
-
|
|
27618
|
-
// ../protocol/src/surface-verify/SalesforceVerifyRoutes.ts
|
|
28444
|
+
// ../../../Decionis/apps/protocol/src/surface-verify/SalesforceVerifyRoutes.ts
|
|
27619
28445
|
function registerSalesforceVerifyRoutes(app, deps) {
|
|
27620
28446
|
const { store } = deps;
|
|
27621
28447
|
const protocolAuthLookup = deps.authLookup ?? null;
|
|
@@ -27657,26 +28483,10 @@ function registerSalesforceVerifyRoutes(app, deps) {
|
|
|
27657
28483
|
const candidateOrg = authedOrgId || asString2(ctx.org_id)?.trim() || process.env.DECIONIS_SALESFORCE_ORG_ID?.trim() || SAP_DEFAULT_ORG_ID;
|
|
27658
28484
|
const orgId = isLikelyUuid(candidateOrg) ? candidateOrg : SAP_DEFAULT_ORG_ID;
|
|
27659
28485
|
await ensureSalesforcePolicyBundle(orgId);
|
|
27660
|
-
let evalPayload = payload;
|
|
27661
|
-
let costBasisSource = "payload";
|
|
27662
|
-
if (gate === "execution_authority") {
|
|
27663
|
-
const costConfig = resolveSapCostConfig(process.env, orgId);
|
|
27664
|
-
if (costConfig) {
|
|
27665
|
-
try {
|
|
27666
|
-
const skus = (payload.order_items ?? []).map((it) => String(it.matnr ?? "").trim()).filter(Boolean);
|
|
27667
|
-
const costMap = await fetchSapCostBasis(costConfig, skus);
|
|
27668
|
-
if (hasResolvedCost(costMap)) {
|
|
27669
|
-
evalPayload = applySapCostBasis(payload, costMap);
|
|
27670
|
-
costBasisSource = "sap";
|
|
27671
|
-
}
|
|
27672
|
-
} catch {
|
|
27673
|
-
}
|
|
27674
|
-
}
|
|
27675
|
-
}
|
|
27676
28486
|
const evalRes = await injectInternalProtocolRoute(app, {
|
|
27677
28487
|
method: "POST",
|
|
27678
28488
|
url: "/v1/protocol/evaluate-decision",
|
|
27679
|
-
payload: buildSalesforceEvaluateRequest(
|
|
28489
|
+
payload: buildSalesforceEvaluateRequest(payload, gate, orgId)
|
|
27680
28490
|
});
|
|
27681
28491
|
if (evalRes.statusCode !== 200) {
|
|
27682
28492
|
return reply.code(502).send({
|
|
@@ -27717,11 +28527,19 @@ function registerSalesforceVerifyRoutes(app, deps) {
|
|
|
27717
28527
|
ledger_entry_hash: response.ledger_entry_hash ?? null,
|
|
27718
28528
|
decision_chain: response.decision_chain ?? null,
|
|
27719
28529
|
idempotent_replay: Boolean(response.idempotent_replay),
|
|
27720
|
-
cost_basis_source:
|
|
28530
|
+
cost_basis_source: "payload",
|
|
27721
28531
|
federated: true,
|
|
27722
28532
|
pipeline: true
|
|
27723
28533
|
});
|
|
27724
28534
|
};
|
|
28535
|
+
app.post(
|
|
28536
|
+
"/v1/protocol/surfaces/salesforce/state-admission/verify",
|
|
28537
|
+
(req, reply) => handleSalesforceGate("state_admission", req, reply)
|
|
28538
|
+
);
|
|
28539
|
+
app.post(
|
|
28540
|
+
"/v1/protocol/surfaces/salesforce/execution-authority/verify",
|
|
28541
|
+
(req, reply) => handleSalesforceGate("execution_authority", req, reply)
|
|
28542
|
+
);
|
|
27725
28543
|
app.post(
|
|
27726
28544
|
"/salesforce/state-admission/verify",
|
|
27727
28545
|
(req, reply) => handleSalesforceGate("state_admission", req, reply)
|
|
@@ -27740,10 +28558,10 @@ function registerSalesforceVerifyRoutes(app, deps) {
|
|
|
27740
28558
|
);
|
|
27741
28559
|
}
|
|
27742
28560
|
|
|
27743
|
-
//
|
|
28561
|
+
// ../../../Decionis/apps/protocol/src/surface-verify/OpsVerifyRoutes.ts
|
|
27744
28562
|
import { randomUUID as randomUUID13 } from "crypto";
|
|
27745
28563
|
|
|
27746
|
-
//
|
|
28564
|
+
// ../../../Decionis/apps/protocol/src/verticals/ops/OpsSurface.ts
|
|
27747
28565
|
import { createHash as createHash17 } from "crypto";
|
|
27748
28566
|
var OpsSurface = class _OpsSurface {
|
|
27749
28567
|
/**
|
|
@@ -27821,7 +28639,7 @@ async function deriveOpsDuplicateFacts(input) {
|
|
|
27821
28639
|
return OpsSurface.deriveDuplicateFacts(input);
|
|
27822
28640
|
}
|
|
27823
28641
|
|
|
27824
|
-
//
|
|
28642
|
+
// ../../../Decionis/apps/protocol/src/surface-verify/OpsVerifyRoutes.ts
|
|
27825
28643
|
function registerOpsVerifyRoutes(app, deps) {
|
|
27826
28644
|
const { store } = deps;
|
|
27827
28645
|
const protocolAuthLookup = deps.authLookup ?? null;
|
|
@@ -27925,10 +28743,10 @@ function registerOpsVerifyRoutes(app, deps) {
|
|
|
27925
28743
|
);
|
|
27926
28744
|
}
|
|
27927
28745
|
|
|
27928
|
-
//
|
|
28746
|
+
// ../../../Decionis/apps/protocol/src/surface-verify/WorkdayVerifyRoutes.ts
|
|
27929
28747
|
import { randomUUID as randomUUID14 } from "crypto";
|
|
27930
28748
|
|
|
27931
|
-
//
|
|
28749
|
+
// ../../../Decionis/apps/protocol/src/verticals/workday/WorkdaySurface.ts
|
|
27932
28750
|
import { createHash as createHash18 } from "crypto";
|
|
27933
28751
|
var AUTHORIZED_HR_ROLES = /* @__PURE__ */ new Set([
|
|
27934
28752
|
"HRBusinessPartner",
|
|
@@ -28281,7 +29099,7 @@ async function deriveWorkdayDuplicateFacts(input) {
|
|
|
28281
29099
|
return WorkdaySurface.deriveDuplicateFacts(input);
|
|
28282
29100
|
}
|
|
28283
29101
|
|
|
28284
|
-
//
|
|
29102
|
+
// ../../../Decionis/apps/protocol/src/surface-verify/WorkdayVerifyRoutes.ts
|
|
28285
29103
|
function registerWorkdayVerifyRoutes(app, deps) {
|
|
28286
29104
|
const { store } = deps;
|
|
28287
29105
|
const protocolAuthLookup = deps.authLookup ?? null;
|
|
@@ -28387,10 +29205,10 @@ function registerWorkdayVerifyRoutes(app, deps) {
|
|
|
28387
29205
|
);
|
|
28388
29206
|
}
|
|
28389
29207
|
|
|
28390
|
-
//
|
|
29208
|
+
// ../../../Decionis/apps/protocol/src/surface-verify/WorkdayFinancialsVerifyRoutes.ts
|
|
28391
29209
|
import { randomUUID as randomUUID15 } from "crypto";
|
|
28392
29210
|
|
|
28393
|
-
//
|
|
29211
|
+
// ../../../Decionis/apps/protocol/src/verticals/workday-financials/WorkdayFinancialsSurface.ts
|
|
28394
29212
|
import { createHash as createHash19 } from "crypto";
|
|
28395
29213
|
var AUTHORIZED_FINANCE_ROLES = /* @__PURE__ */ new Set([
|
|
28396
29214
|
"PayrollAdministrator",
|
|
@@ -28742,7 +29560,7 @@ async function deriveWorkdayFinancialsDuplicateFacts(input) {
|
|
|
28742
29560
|
return WorkdayFinancialsSurface.deriveDuplicateFacts(input);
|
|
28743
29561
|
}
|
|
28744
29562
|
|
|
28745
|
-
//
|
|
29563
|
+
// ../../../Decionis/apps/protocol/src/surface-verify/WorkdayFinancialsVerifyRoutes.ts
|
|
28746
29564
|
function registerWorkdayFinancialsVerifyRoutes(app, deps) {
|
|
28747
29565
|
const { store } = deps;
|
|
28748
29566
|
const protocolAuthLookup = deps.authLookup ?? null;
|
|
@@ -28850,7 +29668,7 @@ function registerWorkdayFinancialsVerifyRoutes(app, deps) {
|
|
|
28850
29668
|
);
|
|
28851
29669
|
}
|
|
28852
29670
|
|
|
28853
|
-
//
|
|
29671
|
+
// ../../../Decionis/apps/protocol/src/surface-verify/SurfaceDecisionRoutes.ts
|
|
28854
29672
|
import { randomUUID as randomUUID16 } from "crypto";
|
|
28855
29673
|
function registerSurfaceDecisionRoutes(app, deps) {
|
|
28856
29674
|
const { store } = deps;
|
|
@@ -28961,7 +29779,7 @@ function registerSurfaceDecisionRoutes(app, deps) {
|
|
|
28961
29779
|
app.post("/v1/protocol/surfaces/decisions", handleSurfaceDecision);
|
|
28962
29780
|
}
|
|
28963
29781
|
|
|
28964
|
-
//
|
|
29782
|
+
// ../../../Decionis/apps/protocol/src/enforcement/EnforcementRolloutRoutes.ts
|
|
28965
29783
|
var EnforcementRolloutParsing = class {
|
|
28966
29784
|
static parseEnforcementRolloutMutation(input) {
|
|
28967
29785
|
const record = asRecord3(input);
|
|
@@ -29062,7 +29880,7 @@ function registerEnforcementRolloutRoutes(app, deps) {
|
|
|
29062
29880
|
});
|
|
29063
29881
|
}
|
|
29064
29882
|
|
|
29065
|
-
//
|
|
29883
|
+
// ../../../Decionis/apps/protocol/src/integrity/ProofPacket.ts
|
|
29066
29884
|
var VERIFY_STEPS = [
|
|
29067
29885
|
"Canonicalize each proof-bundle artifact's source document with that artifact's declared canonicalization_profile (RFC8785/JCS or DECIONIS_SORTED_JSON_V1); historical artifacts without a profile use DECIONIS_SORTED_JSON_V1.",
|
|
29068
29886
|
"Recompute SHA-256 over the canonical bytes and confirm it matches canonical_document_sha256.",
|
|
@@ -29240,7 +30058,7 @@ function buildDecisionChainProofPacket(input) {
|
|
|
29240
30058
|
return ProofPacket.buildDecisionChainProofPacket(input);
|
|
29241
30059
|
}
|
|
29242
30060
|
|
|
29243
|
-
//
|
|
30061
|
+
// ../../../Decionis/apps/protocol/src/dossiers/ProofPacketAuth.ts
|
|
29244
30062
|
var ProofPacketAuth = class {
|
|
29245
30063
|
static async authorizeProofPacketRead(req, orgId, authLookup) {
|
|
29246
30064
|
if (hasValidInternalCredential(req, resolveInternalSecrets())) return null;
|
|
@@ -29288,7 +30106,7 @@ async function authorizeProofPacketWrite(req, orgId, authLookup) {
|
|
|
29288
30106
|
return null;
|
|
29289
30107
|
}
|
|
29290
30108
|
|
|
29291
|
-
//
|
|
30109
|
+
// ../../../Decionis/apps/protocol/src/interop/scitt/aac-v04/AgentActionCapsuleV04.ts
|
|
29292
30110
|
import { createHash as createHash20 } from "crypto";
|
|
29293
30111
|
var AAC_V04_SPEC_VERSION = "draft-mih-scitt-agent-action-capsule-04";
|
|
29294
30112
|
var AAC_V04_FORMAT_VERSION = "4";
|
|
@@ -29863,10 +30681,10 @@ function verifyAgentActionCapsuleV04Class1(value, options) {
|
|
|
29863
30681
|
}
|
|
29864
30682
|
}
|
|
29865
30683
|
|
|
29866
|
-
//
|
|
30684
|
+
// ../../../Decionis/apps/protocol/src/interop/scitt/cose/ProducerEnvelope.ts
|
|
29867
30685
|
import { createPublicKey as createPublicKey2, verify as verifySignature } from "crypto";
|
|
29868
30686
|
|
|
29869
|
-
//
|
|
30687
|
+
// ../../../Decionis/apps/protocol/src/interop/scitt/cose/Cbor.ts
|
|
29870
30688
|
function concat(parts) {
|
|
29871
30689
|
const length = parts.reduce((total, part) => total + part.length, 0);
|
|
29872
30690
|
const output = new Uint8Array(length);
|
|
@@ -30013,7 +30831,7 @@ function decodeCbor(bytes2) {
|
|
|
30013
30831
|
return decoded;
|
|
30014
30832
|
}
|
|
30015
30833
|
|
|
30016
|
-
//
|
|
30834
|
+
// ../../../Decionis/apps/protocol/src/interop/scitt/cose/ProducerEnvelope.ts
|
|
30017
30835
|
var AAC_PRODUCER_ENVELOPE_CONTENT_TYPE = "application/agent-action-capsule-id";
|
|
30018
30836
|
var AAC_PRODUCER_ENVELOPE_MEDIA_TYPE = "application/cose";
|
|
30019
30837
|
function rawCapsuleId(capsuleId) {
|
|
@@ -30149,7 +30967,7 @@ function verifyAgentActionCapsuleProducerEnvelope(envelope, capsuleId) {
|
|
|
30149
30967
|
};
|
|
30150
30968
|
}
|
|
30151
30969
|
|
|
30152
|
-
//
|
|
30970
|
+
// ../../../Decionis/apps/protocol/src/interop/scitt/aac-v04/DossierMapper.ts
|
|
30153
30971
|
import { createHash as createHash21 } from "crypto";
|
|
30154
30972
|
function digest(value) {
|
|
30155
30973
|
return createHash21("sha256").update(jcsCanonicalize(value), "utf8").digest("hex");
|
|
@@ -30379,7 +31197,7 @@ function decisionDossierReference(dossier) {
|
|
|
30379
31197
|
};
|
|
30380
31198
|
}
|
|
30381
31199
|
|
|
30382
|
-
//
|
|
31200
|
+
// ../../../Decionis/apps/protocol/src/integrity/DossierLedgerAnchor.ts
|
|
30383
31201
|
function normalizedSha256(value) {
|
|
30384
31202
|
if (typeof value !== "string") return null;
|
|
30385
31203
|
const candidate = value.trim().toLowerCase();
|
|
@@ -30400,7 +31218,9 @@ async function verifyDossierLedgerAnchor(input) {
|
|
|
30400
31218
|
reason: "LEDGER_CONTINUITY_UNVERIFIED",
|
|
30401
31219
|
ledger_entry_id: ledgerEntryId,
|
|
30402
31220
|
declared_entry_hash: declaredHash,
|
|
30403
|
-
stored_entry_hash: null
|
|
31221
|
+
stored_entry_hash: null,
|
|
31222
|
+
ledger_membership: null,
|
|
31223
|
+
orphan_resolution_entry_id: null
|
|
30404
31224
|
};
|
|
30405
31225
|
}
|
|
30406
31226
|
if (!ledgerEntryId || !isLikelyUuid(ledgerEntryId) || !declaredHash) {
|
|
@@ -30414,7 +31234,9 @@ async function verifyDossierLedgerAnchor(input) {
|
|
|
30414
31234
|
reason: "ANCHOR_MISSING_OR_MALFORMED",
|
|
30415
31235
|
ledger_entry_id: ledgerEntryId,
|
|
30416
31236
|
declared_entry_hash: declaredHash,
|
|
30417
|
-
stored_entry_hash: null
|
|
31237
|
+
stored_entry_hash: null,
|
|
31238
|
+
ledger_membership: null,
|
|
31239
|
+
orphan_resolution_entry_id: null
|
|
30418
31240
|
};
|
|
30419
31241
|
}
|
|
30420
31242
|
const row = await input.store.getAuditLedgerEntry({
|
|
@@ -30432,7 +31254,9 @@ async function verifyDossierLedgerAnchor(input) {
|
|
|
30432
31254
|
reason: "ANCHOR_NOT_FOUND",
|
|
30433
31255
|
ledger_entry_id: ledgerEntryId,
|
|
30434
31256
|
declared_entry_hash: declaredHash,
|
|
30435
|
-
stored_entry_hash: null
|
|
31257
|
+
stored_entry_hash: null,
|
|
31258
|
+
ledger_membership: null,
|
|
31259
|
+
orphan_resolution_entry_id: null
|
|
30436
31260
|
};
|
|
30437
31261
|
}
|
|
30438
31262
|
const storedHash = normalizedSha256(row.entry_hash);
|
|
@@ -30459,11 +31283,13 @@ async function verifyDossierLedgerAnchor(input) {
|
|
|
30459
31283
|
reason,
|
|
30460
31284
|
ledger_entry_id: ledgerEntryId,
|
|
30461
31285
|
declared_entry_hash: declaredHash,
|
|
30462
|
-
stored_entry_hash: storedHash
|
|
31286
|
+
stored_entry_hash: storedHash,
|
|
31287
|
+
ledger_membership: row.ledger_membership ?? "canonical",
|
|
31288
|
+
orphan_resolution_entry_id: row.ledger_membership === "orphaned" ? row.orphan_resolution_entry_id ?? null : null
|
|
30463
31289
|
};
|
|
30464
31290
|
}
|
|
30465
31291
|
|
|
30466
|
-
//
|
|
31292
|
+
// ../../../Decionis/apps/protocol/src/decision-chains/DecisionChainRoutes.ts
|
|
30467
31293
|
var DEFAULT_DECISION_CHAIN_LEDGER_VERIFICATION_LIMIT = 5e3;
|
|
30468
31294
|
var MAX_DECISION_CHAIN_LEDGER_VERIFICATION_LIMIT = 5e4;
|
|
30469
31295
|
function resolveDecisionChainLedgerVerificationLimit(env = process.env) {
|
|
@@ -30571,7 +31397,8 @@ function registerDecisionChainRoutes(app, deps) {
|
|
|
30571
31397
|
valid: ledger.valid,
|
|
30572
31398
|
complete: ledger.complete,
|
|
30573
31399
|
checked: ledger.checked,
|
|
30574
|
-
maxEntries: ledgerVerificationLimit
|
|
31400
|
+
maxEntries: ledgerVerificationLimit,
|
|
31401
|
+
...ledger.orphaned ? { orphaned: ledger.orphaned } : {}
|
|
30575
31402
|
},
|
|
30576
31403
|
proofVerifications: new Map(
|
|
30577
31404
|
[...proofByDossierId].map(([dossierId, result]) => [
|
|
@@ -30633,7 +31460,8 @@ function registerDecisionChainRoutes(app, deps) {
|
|
|
30633
31460
|
valid: ledger.valid,
|
|
30634
31461
|
complete: ledger.complete,
|
|
30635
31462
|
checked: ledger.checked,
|
|
30636
|
-
maxEntries: ledgerVerificationLimit
|
|
31463
|
+
maxEntries: ledgerVerificationLimit,
|
|
31464
|
+
...ledger.orphaned ? { orphaned: ledger.orphaned } : {}
|
|
30637
31465
|
}
|
|
30638
31466
|
})
|
|
30639
31467
|
);
|
|
@@ -30686,14 +31514,15 @@ function registerDecisionChainRoutes(app, deps) {
|
|
|
30686
31514
|
valid: ledger.valid,
|
|
30687
31515
|
complete: ledger.complete,
|
|
30688
31516
|
checked: ledger.checked,
|
|
30689
|
-
maxEntries: ledgerVerificationLimit
|
|
31517
|
+
maxEntries: ledgerVerificationLimit,
|
|
31518
|
+
...ledger.orphaned ? { orphaned: ledger.orphaned } : {}
|
|
30690
31519
|
}
|
|
30691
31520
|
})
|
|
30692
31521
|
);
|
|
30693
31522
|
});
|
|
30694
31523
|
}
|
|
30695
31524
|
|
|
30696
|
-
//
|
|
31525
|
+
// ../../../Decionis/apps/protocol/src/dossiers/DossierCapsuleExport.ts
|
|
30697
31526
|
function parentDossierIds(payload) {
|
|
30698
31527
|
const direct = asRecord3(payload.decision_chain);
|
|
30699
31528
|
const nested = asRecord3(asRecord3(payload.routing_decision).decision_chain);
|
|
@@ -30742,7 +31571,7 @@ async function buildDossierAgentActionCapsuleV04Export(input) {
|
|
|
30742
31571
|
return { dossier, capsule, parent_capsule: parentCapsule, class_1: class1 };
|
|
30743
31572
|
}
|
|
30744
31573
|
|
|
30745
|
-
//
|
|
31574
|
+
// ../../../Decionis/apps/protocol/src/dossiers/DossierRoutes.ts
|
|
30746
31575
|
function registerDossierRoutes(app, deps) {
|
|
30747
31576
|
const { store } = deps;
|
|
30748
31577
|
const protocolAuthLookup = deps.authLookup ?? null;
|
|
@@ -30985,7 +31814,7 @@ function registerDossierRoutes(app, deps) {
|
|
|
30985
31814
|
);
|
|
30986
31815
|
}
|
|
30987
31816
|
|
|
30988
|
-
//
|
|
31817
|
+
// ../../../Decionis/apps/protocol/src/policy-graph/PolicyDecisionRegister.ts
|
|
30989
31818
|
function asRecord7(value) {
|
|
30990
31819
|
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
30991
31820
|
}
|
|
@@ -31171,7 +32000,7 @@ async function loadPolicyDecisionRegister(input) {
|
|
|
31171
32000
|
});
|
|
31172
32001
|
}
|
|
31173
32002
|
|
|
31174
|
-
//
|
|
32003
|
+
// ../../../Decionis/apps/protocol/src/policy-graph/PolicyDecisionRegisterRoutes.ts
|
|
31175
32004
|
var MAX_BUNDLE_LOOKBACK = 500;
|
|
31176
32005
|
var DEFAULT_BUNDLE_LOOKBACK = 100;
|
|
31177
32006
|
function registerPolicyDecisionRegisterRoutes(app, deps) {
|
|
@@ -31203,7 +32032,7 @@ function registerPolicyDecisionRegisterRoutes(app, deps) {
|
|
|
31203
32032
|
});
|
|
31204
32033
|
}
|
|
31205
32034
|
|
|
31206
|
-
//
|
|
32035
|
+
// ../../../Decionis/apps/protocol/src/artifacts/ArtifactIngestion.ts
|
|
31207
32036
|
import { createHash as createHash22, randomUUID as randomUUID17 } from "crypto";
|
|
31208
32037
|
var ArtifactIngestion = class {
|
|
31209
32038
|
static createArtifactPayloads(request, shadow, resolvedVerticalPack, previousLedgerHash) {
|
|
@@ -31432,6 +32261,19 @@ var ArtifactIngestion = class {
|
|
|
31432
32261
|
issues: validation.issues
|
|
31433
32262
|
});
|
|
31434
32263
|
}
|
|
32264
|
+
if (kind === "audit_ledger_entry" && validation.value.event_type === LEDGER_FORK_RESOLVED_EVENT_TYPE) {
|
|
32265
|
+
return reply.code(400).send({
|
|
32266
|
+
error: "VALIDATION_ERROR",
|
|
32267
|
+
message: `${LEDGER_FORK_RESOLVED_EVENT_TYPE} is reserved for the ledger fork repair command`,
|
|
32268
|
+
issues: [
|
|
32269
|
+
{
|
|
32270
|
+
path: "/event_type",
|
|
32271
|
+
keyword: "reserved",
|
|
32272
|
+
message: "written only by the operator fork-resolution command"
|
|
32273
|
+
}
|
|
32274
|
+
]
|
|
32275
|
+
});
|
|
32276
|
+
}
|
|
31435
32277
|
if (kind === "signal_envelope") {
|
|
31436
32278
|
const semantic = asRecord3(validation.value.semantic);
|
|
31437
32279
|
if (Object.keys(semantic).length > 0) {
|
|
@@ -31503,7 +32345,7 @@ function ingestArtifact(app, reply, store, kind, payload) {
|
|
|
31503
32345
|
return ArtifactIngestion.ingestArtifact(app, reply, store, kind, payload);
|
|
31504
32346
|
}
|
|
31505
32347
|
|
|
31506
|
-
//
|
|
32348
|
+
// ../../../Decionis/apps/protocol/src/artifacts/ArtifactRoutes.ts
|
|
31507
32349
|
function registerArtifactRoutes(app, deps) {
|
|
31508
32350
|
const { store } = deps;
|
|
31509
32351
|
app.post(
|
|
@@ -31595,7 +32437,7 @@ function registerArtifactRoutes(app, deps) {
|
|
|
31595
32437
|
});
|
|
31596
32438
|
}
|
|
31597
32439
|
|
|
31598
|
-
//
|
|
32440
|
+
// ../../../Decionis/apps/protocol/src/marketplaces/MarketplaceProfiles.ts
|
|
31599
32441
|
var commonContracts = [
|
|
31600
32442
|
"signal_envelope",
|
|
31601
32443
|
"context_snapshot",
|
|
@@ -32026,10 +32868,11 @@ var readiness = {
|
|
|
32026
32868
|
// core COGS, HPOS order CRUD, and the signed dossier were verified end
|
|
32027
32869
|
// to end on a staging store — including an admin-enabled ENFORCEMENT
|
|
32028
32870
|
// block — before the listing went live (shared readiness provenance).
|
|
32029
|
-
// The previous PLANNED states predated the public listing.
|
|
32871
|
+
// The previous PLANNED states predated the public listing. In production
|
|
32872
|
+
// since 2026-09-26 (Festus); each store still starts in Shadow Mode.
|
|
32030
32873
|
adapter_state: "LIVE",
|
|
32031
32874
|
docs_state: "LIVE",
|
|
32032
|
-
launch_state: "
|
|
32875
|
+
launch_state: "LIVE",
|
|
32033
32876
|
next_milestone: "WordPress.org listing is live and self-serve; grow installs and collect the first live-store enforcement evidence for the listing's proof section"
|
|
32034
32877
|
},
|
|
32035
32878
|
jumia: {
|
|
@@ -32068,7 +32911,7 @@ function getMarketplaceReadiness(target) {
|
|
|
32068
32911
|
return MarketplaceProfiles.getReadiness(target);
|
|
32069
32912
|
}
|
|
32070
32913
|
|
|
32071
|
-
//
|
|
32914
|
+
// ../../../Decionis/apps/protocol/src/marketplaces/MarketplaceContracts.ts
|
|
32072
32915
|
var PROTOCOL_MARKETPLACE_TARGETS = [
|
|
32073
32916
|
"atlassian",
|
|
32074
32917
|
"microsoft",
|
|
@@ -32090,7 +32933,7 @@ var PROTOCOL_MARKETPLACE_TARGETS = [
|
|
|
32090
32933
|
"jumia"
|
|
32091
32934
|
];
|
|
32092
32935
|
|
|
32093
|
-
//
|
|
32936
|
+
// ../../../Decionis/apps/protocol/src/marketplaces/MarketplaceRoutes.ts
|
|
32094
32937
|
var MarketplaceRouteParsing = class {
|
|
32095
32938
|
static parseMarketplaceTarget(input) {
|
|
32096
32939
|
const value = asString2(input)?.toLowerCase();
|
|
@@ -32167,7 +33010,7 @@ function registerMarketplaceRoutes(app) {
|
|
|
32167
33010
|
});
|
|
32168
33011
|
}
|
|
32169
33012
|
|
|
32170
|
-
//
|
|
33013
|
+
// ../../../Decionis/apps/protocol/src/verticals/VerticalRoutes.ts
|
|
32171
33014
|
import { randomUUID as randomUUID18 } from "crypto";
|
|
32172
33015
|
var VerticalRouteParsing = class {
|
|
32173
33016
|
static parseVerticalPackMutation(input) {
|
|
@@ -32324,10 +33167,10 @@ function registerVerticalRoutes(app, deps) {
|
|
|
32324
33167
|
});
|
|
32325
33168
|
}
|
|
32326
33169
|
|
|
32327
|
-
//
|
|
33170
|
+
// ../../../Decionis/apps/protocol/src/shadow/ShadowRoutes.ts
|
|
32328
33171
|
import { createHash as createHash23 } from "crypto";
|
|
32329
33172
|
|
|
32330
|
-
//
|
|
33173
|
+
// ../../../Decionis/apps/protocol/src/shadow/ShadowDecisioning.ts
|
|
32331
33174
|
var ShadowDecisioning = class {
|
|
32332
33175
|
static parseShadowRequest(input) {
|
|
32333
33176
|
const record = asRecord3(input);
|
|
@@ -32462,7 +33305,7 @@ function buildShadowDecision(request, resolvedVerticalPack) {
|
|
|
32462
33305
|
return ShadowDecisioning.buildShadowDecision(request, resolvedVerticalPack);
|
|
32463
33306
|
}
|
|
32464
33307
|
|
|
32465
|
-
//
|
|
33308
|
+
// ../../../Decionis/apps/protocol/src/shadow/ShadowReports.ts
|
|
32466
33309
|
var ShadowReports = class {
|
|
32467
33310
|
static shadowExecutionActionFromOutcome(outcome) {
|
|
32468
33311
|
if (outcome === "APPROVE") return "CONTINUE";
|
|
@@ -32614,7 +33457,7 @@ function parseShadowEvaluateDecisionReportsQuery(input) {
|
|
|
32614
33457
|
return ShadowReports.parseShadowEvaluateDecisionReportsQuery(input);
|
|
32615
33458
|
}
|
|
32616
33459
|
|
|
32617
|
-
//
|
|
33460
|
+
// ../../../Decionis/apps/protocol/src/shadow/ShadowRoutes.ts
|
|
32618
33461
|
function registerShadowRoutes(app, deps) {
|
|
32619
33462
|
const { store } = deps;
|
|
32620
33463
|
app.get("/v1/protocol/shadow/evaluate-decision/reports", async (req, reply) => {
|
|
@@ -32747,7 +33590,7 @@ function registerShadowRoutes(app, deps) {
|
|
|
32747
33590
|
});
|
|
32748
33591
|
}
|
|
32749
33592
|
|
|
32750
|
-
//
|
|
33593
|
+
// ../../../Decionis/apps/protocol/src/execution-binding/ExecutionRevalidationState.ts
|
|
32751
33594
|
import { createHash as createHash24 } from "crypto";
|
|
32752
33595
|
var ExecutionRevalidationState = class _ExecutionRevalidationState {
|
|
32753
33596
|
static async resolve(input) {
|
|
@@ -32960,7 +33803,7 @@ function normalizeDigest2(value) {
|
|
|
32960
33803
|
return /^sha256:[0-9a-f]{64}$/.test(normalized) ? normalized : null;
|
|
32961
33804
|
}
|
|
32962
33805
|
|
|
32963
|
-
//
|
|
33806
|
+
// ../../../Decionis/apps/protocol/src/execution-binding/ExecutionRevalidationRoutes.ts
|
|
32964
33807
|
function registerExecutionRevalidationRoutes(app, deps) {
|
|
32965
33808
|
const internalSecrets = deps.internalSecret === void 0 && deps.internalSecretPrevious === void 0 ? resolveInternalSecrets() : {
|
|
32966
33809
|
current: deps.internalSecret ?? null,
|
|
@@ -33054,7 +33897,7 @@ function registerExecutionRevalidationRoutes(app, deps) {
|
|
|
33054
33897
|
});
|
|
33055
33898
|
}
|
|
33056
33899
|
|
|
33057
|
-
//
|
|
33900
|
+
// ../../../Decionis/apps/protocol/src/interop/scitt/registration/ScittSignedStatement.ts
|
|
33058
33901
|
import { createPublicKey as createPublicKey3, verify as verifySignature2 } from "crypto";
|
|
33059
33902
|
var SCITT_SIGNED_STATEMENT_MEDIA_TYPE = "application/scitt-statement+cose";
|
|
33060
33903
|
var SCITT_RECEIPT_MEDIA_TYPE = "application/scitt-receipt+cose";
|
|
@@ -33173,7 +34016,7 @@ function verifyScittCapsuleIdSignedStatement(statement, capsuleId) {
|
|
|
33173
34016
|
};
|
|
33174
34017
|
}
|
|
33175
34018
|
|
|
33176
|
-
//
|
|
34019
|
+
// ../../../Decionis/apps/protocol/src/interop/scitt/registration/ScittRegistrationService.ts
|
|
33177
34020
|
function origin(value) {
|
|
33178
34021
|
try {
|
|
33179
34022
|
const url = new URL(value);
|
|
@@ -33366,7 +34209,7 @@ var ScittRegistrationService = class {
|
|
|
33366
34209
|
}
|
|
33367
34210
|
};
|
|
33368
34211
|
|
|
33369
|
-
//
|
|
34212
|
+
// ../../../Decionis/apps/protocol/src/app.ts
|
|
33370
34213
|
function buildProtocolApp(options) {
|
|
33371
34214
|
const app = Fastify({
|
|
33372
34215
|
logger: options?.logger ?? true
|
|
@@ -33413,6 +34256,7 @@ function buildProtocolApp(options) {
|
|
|
33413
34256
|
const protocolAuthLookup = options?.mcpAuthLookup ?? null;
|
|
33414
34257
|
registerInternalAccessGuard(app, process.env, protocolAuthLookup);
|
|
33415
34258
|
registerHealthRoutes(app, { store });
|
|
34259
|
+
new GlamaClaimRoutes().register(app);
|
|
33416
34260
|
registerFinanceOverrideRoutes(app, { store });
|
|
33417
34261
|
registerEvaluateDecisionRoutes(app, { store });
|
|
33418
34262
|
registerWebexRoutes(app, { store });
|
|
@@ -33929,4 +34773,4 @@ toad-cache/dist/toad-cache.cjs:
|
|
|
33929
34773
|
* @version 3.7.0
|
|
33930
34774
|
*)
|
|
33931
34775
|
*/
|
|
33932
|
-
//# sourceMappingURL=chunk-
|
|
34776
|
+
//# sourceMappingURL=chunk-5Q6BCK32.js.map
|