@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.
@@ -29,9 +29,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
29
29
  mod
30
30
  ));
31
31
 
32
- // ../../node_modules/.pnpm/fastify-plugin@6.0.0/node_modules/fastify-plugin/lib/getPluginName.js
32
+ // ../../../Decionis/node_modules/.pnpm/fastify-plugin@6.0.0/node_modules/fastify-plugin/lib/getPluginName.js
33
33
  var require_getPluginName = __commonJS({
34
- "../../node_modules/.pnpm/fastify-plugin@6.0.0/node_modules/fastify-plugin/lib/getPluginName.js"(exports, module) {
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
- // ../../node_modules/.pnpm/fastify-plugin@6.0.0/node_modules/fastify-plugin/lib/toCamelCase.js
57
+ // ../../../Decionis/node_modules/.pnpm/fastify-plugin@6.0.0/node_modules/fastify-plugin/lib/toCamelCase.js
58
58
  var require_toCamelCase = __commonJS({
59
- "../../node_modules/.pnpm/fastify-plugin@6.0.0/node_modules/fastify-plugin/lib/toCamelCase.js"(exports, module) {
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
- // ../../node_modules/.pnpm/fastify-plugin@6.0.0/node_modules/fastify-plugin/index.js
72
+ // ../../../Decionis/node_modules/.pnpm/fastify-plugin@6.0.0/node_modules/fastify-plugin/index.js
73
73
  var require_fastify_plugin = __commonJS({
74
- "../../node_modules/.pnpm/fastify-plugin@6.0.0/node_modules/fastify-plugin/index.js"(exports, module) {
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
- // ../../node_modules/.pnpm/toad-cache@3.7.0/node_modules/toad-cache/dist/toad-cache.cjs
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
- "../../node_modules/.pnpm/toad-cache@3.7.0/node_modules/toad-cache/dist/toad-cache.cjs"(exports) {
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
- // ../../node_modules/.pnpm/@fastify+cors@11.3.0/node_modules/@fastify/cors/vary.js
805
+ // ../../../Decionis/node_modules/.pnpm/@fastify+cors@11.3.0/node_modules/@fastify/cors/vary.js
806
806
  var require_vary = __commonJS({
807
- "../../node_modules/.pnpm/@fastify+cors@11.3.0/node_modules/@fastify/cors/vary.js"(exports, module) {
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
- // ../../node_modules/.pnpm/@fastify+cors@11.3.0/node_modules/@fastify/cors/index.js
886
+ // ../../../Decionis/node_modules/.pnpm/@fastify+cors@11.3.0/node_modules/@fastify/cors/index.js
887
887
  var require_cors = __commonJS({
888
- "../../node_modules/.pnpm/@fastify+cors@11.3.0/node_modules/@fastify/cors/index.js"(exports, module) {
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
- // ../protocol/src/app.ts
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
- // ../protocol/src/store/MemoryProtocolStore.ts
1136
+ // ../../../Decionis/apps/protocol/src/store/MemoryProtocolStore.ts
1137
1137
  import { randomUUID } from "crypto";
1138
1138
 
1139
- // ../../packages/shared/src/Domain/DomainEnums.ts
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
- // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/external.js
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
- // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/util.js
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
- // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/ZodError.js
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
- // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/locales/en.js
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
- // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/errors.js
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
- // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js
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
- // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.js
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
- // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js
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
- // ../../packages/shared/src/Domain/DomainSchemas.ts
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
- // ../../packages/shared/src/Decisioning/AiIntentContracts.ts
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
- // ../../packages/shared/src/Decisioning/ExecutionBinding.ts
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
- // ../../packages/shared/src/Decisioning/DecisionDossierIntegrity.ts
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
- // ../../packages/shared/src/Decisioning/DecisioningContracts.ts
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
- // ../../packages/shared/src/Decisioning/SnapshotValidity.ts
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
- // ../../packages/shared/src/Decisioning/EnforcementMode.ts
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
- // ../../packages/shared/src/Decisioning/PolicyResolution.ts
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
- // ../../packages/shared/src/Decisioning/EffectEvidence.ts
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
- // ../../packages/shared/src/Decisioning/SemanticSignals.ts
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
- // ../../packages/shared/src/Decisioning/UpstreamAuthorization.ts
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
- // ../../packages/shared/src/Decisioning/AuthoritySemantics.ts
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
- // ../../packages/shared/src/Decisioning/ExecutionRevalidation.ts
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
- // ../../packages/shared/src/Decisioning/ReasonCodes.ts
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
- // ../../packages/shared/src/Authority/AuthorityRequirement.ts
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
- // ../../packages/shared/src/Marketplaces.ts
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
- // EventBridge + Bedrock guards, PrivateLink endpoint, and Marketplace
7293
- // metering/entitlement are built (docs/brief/decionis.aws.md Phase 0-2); listing not yet GA.
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: "pilot_ready"
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). A live
7406
- // seller verification remains before per-seller enforcement (shadow-first).
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: "pilot_ready"
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
- // ../../packages/shared/src/Patterns/ExecutionPatternClassifier.ts
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
- // ../../packages/shared/src/PolicyPacks/PolicyPackRegistry.ts
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
- // ../../packages/shared/src/capital/CapitalContracts.ts
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
- // ../../packages/shared/src/capital/CapitalCopy.ts
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
- // ../../packages/shared/src/capital/CapitalCards.ts
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
- // ../../packages/shared/src/Microsoft/MicrosoftDecisionDossier.ts
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
- // ../../packages/shared/src/Procure/ProcureContracts.ts
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
- // ../../packages/shared/src/Procure/ProcureDsl.ts
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
- // ../../packages/shared/src/Sidecar/SidecarContracts.ts
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
- // ../protocol/src/ledger/LedgerChain.ts
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
- // ../protocol/src/store/StoreContracts.ts
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
- constructor(message, issues) {
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
- // ../protocol/src/store/DecisionDossierImmutability.ts
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
- // ../protocol/src/store/StoreHelpers.ts
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
- // ../protocol/src/store/MemoryProtocolStore.ts
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 currentHead = Array.from(this.auditLedgerChainById.values()).filter((row) => row.org_id === orgId).sort(_MemoryProtocolStore.compareCanonicalLedgerRows).at(-1);
9081
- const bound = bindLedgerEntryToPrevious(payload, currentHead?.entry_hash ?? null);
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
- return verifyLedgerChain(
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
- // ../protocol/src/auth/McpAuth.ts
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
- // ../protocol/src/mcp/McpContracts.ts
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
- // ../protocol/src/http/InternalAccessGuard.ts
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
- // ../protocol/src/http/InternalRouteInvoker.ts
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
- // ../protocol/src/mcp/McpSupport.ts
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
- // ../protocol/src/mcp/McpAuthGuard.ts
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
- // ../protocol/src/mcp/McpRoutes.ts
10507
+ // ../../../Decionis/apps/protocol/src/mcp/McpRoutes.ts
10094
10508
  import { createHash as createHash4, randomUUID as randomUUID2 } from "crypto";
10095
10509
 
10096
- // ../../packages/shared/src/Connectors/ConnectorRegistry.ts
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 promo-hygiene guardrails for eBay Sell-API listings, orders, and promotions \u2014 eBay OAuth connect, production-approved, shadow-mode dossiers with enforcement pending write-scope approval.",
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 SP-API listings and orders \u2014 Login with Amazon connect, shadow-mode first while live seller validation completes.",
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: "validated",
10304
- summary: "Post-purchase fulfillment circuit breaker for Walmart Marketplace \u2014 purchase orders clear a margin gate (COGS + referral fee + shipping) before Acknowledge-Order release.",
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: "oauth", requiresWorkspace: true },
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 \u2014 built and unit-tested, pending validation against a live store.",
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 synchronous checkout gate for Shopware 6 \u2014 App System registration handshake, shop-signed webhooks, and promo-hygiene checks, pending validation against a live store.",
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, docs/marketplace/sap/solution-hub-listing.md). The PartnerEdge
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; the
10384
- // customer-deployable BTP deployment kit ships next. Dual-gate wording
10385
- // from the owning listing copy.
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) — shipped in the same change that makes the URL resolve
10409
- // (rule 1.1 by construction).
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 2026-06-22 (SAP PartnerEdge solution id 2004368); SAP Store content listing is the next, contract-gated step.",
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: "Pre-execution Action Gate for Salesforce \u2014 Flow, Apex, and Agentforce actions checked before they run (allow / hold / escalate) with signed Decision Dossiers on the record. Customer-deployed starter package, shadow-first rollout.",
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
- // Community node published on npm (registry sweep 2026-08-10:
10562
- // n8n-nodes-decionis@0.1.0).
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: "production",
10568
- version: "0.1.0",
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: "npm",
10575
- url: "https://www.npmjs.com/package/n8n-nodes-decionis",
10576
- label: "n8n community node on npm"
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: `${SITE}/docs/protocol-mcp`,
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: `${SITE}/docs/protocol-mcp#try-hosted`,
11227
+ url: "https://decionis.ai/mcp#hosted",
10663
11228
  label: "Hosted connector guide"
10664
11229
  }
10665
11230
  ],
10666
- documentation: `${SITE}/docs/protocol-mcp`,
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: `${SITE}/docs/protocol-mcp#try-hosted`,
11269
+ url: "https://decionis.ai/mcp#hosted",
10698
11270
  label: "Hosted connector guide"
10699
11271
  }
10700
11272
  ],
10701
- documentation: `${SITE}/docs/protocol-mcp`,
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
- // ../protocol/src/mcp/McpResources.ts
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
- // ../protocol/src/mcp/McpPrompts.ts
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
- // ../protocol/src/support/Parsing.ts
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
- // ../protocol/src/mcp/DecisionConversation.ts
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
- // ../protocol/src/mcp/PresenceMcpIntegration.ts
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
- // ../protocol/src/mcp/McpTools.ts
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
- // ../protocol/src/mcp/McpOriginPolicy.ts
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
- // ../protocol/src/mcp/McpRoutes.ts
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(tool, bindAuthenticatedOrgId(options.auth, name, args));
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, body.tool_name, args);
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, body.tool_name, args));
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.com/docs/protocol-mcp"
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
- // ../protocol/src/execution-gating/ExecutionGatingSupport.ts
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
- // ../protocol/src/execution-gating/ExecutionGatingService.ts
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 token = `exec_tok_${payload}.${signature}`;
14385
- const tokenHash = sha256(token);
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(token) {
14428
- if (!token.startsWith("exec_tok_")) {
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 = token.slice("exec_tok_".length);
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 token = bindExecution && !shadow && status === "ALLOW" ? this.issueToken({ request, decision_id, chain_id, action_hash }) : null;
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(token)
15143
+ token_issued: Boolean(token2)
14487
15144
  }
14488
15145
  });
14489
- if (token) {
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: token.token_hash, expires_at: token.expires_at }
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: token?.token_hash ?? null
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: token !== null,
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: token?.token ?? null,
14540
- execution_token_expires_at: token?.expires_at ?? null,
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
- // ../protocol/src/execution-gating/ExecutionGatingRoutes.ts
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
- // ../protocol/src/authority/AuthorityPolicyParser.ts
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
- if (!reasonCodes || !selector || !verification || !resolution || expiresInSeconds == null || !Number.isInteger(expiresInSeconds) || expiresInSeconds < 60 || expiresInSeconds > 3600) {
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
- // ../protocol/src/support/Hashing.ts
15629
+ // ../../../Decionis/apps/protocol/src/support/Hashing.ts
14936
15630
  import { createHash as createHash6 } from "crypto";
14937
15631
 
14938
- // ../protocol/src/integrity/DossierIntegrity.ts
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
- // ../protocol/src/support/Hashing.ts
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
- // ../protocol/src/policy-graph/PolicyGraph.ts
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 path = raw.includes(".") ? raw : `signals.${raw}`;
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
- // ../protocol/src/agent-gateway/AgentTaskPolicyResolver.ts
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
- // ../protocol/src/agent-gateway/MemoryAgentTaskReservationStore.ts
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
- // ../protocol/src/agent-gateway/AgentTaskCostEstimator.ts
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
- // ../protocol/src/agent-gateway/AgentTaskIntentParser.ts
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
- // ../protocol/src/agent-gateway/AgentTaskGatewayService.ts
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
- // ../protocol/src/agent-gateway/AgentGatewayAuthGuard.ts
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
- // ../protocol/src/agent-gateway/AgentProviderProxy.ts
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
- // ../protocol/src/agent-gateway/providers/AnthropicProviderAdapter.ts
17571
+ // ../../../Decionis/apps/protocol/src/agent-gateway/providers/AnthropicProviderAdapter.ts
16857
17572
  import { createHash as createHash8 } from "crypto";
16858
17573
 
16859
- // ../protocol/src/agent-gateway/providers/AgentProviderAdapter.ts
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
- // ../protocol/src/agent-gateway/providers/AnthropicProviderAdapter.ts
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
- // ../protocol/src/agent-gateway/providers/OpenAiProviderAdapter.ts
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
- // ../protocol/src/agent-gateway/providers/AgentProviderRegistry.ts
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
- // ../protocol/src/agent-gateway/AgentTaskGatewayRoutes.ts
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
- // ../protocol/src/ProtocolInfo.ts
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
- // ../protocol/src/health/HealthRoutes.ts
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
- // ../protocol/src/finance-overrides/FinanceOverrideRoutes.ts
18008
+ // ../../../Decionis/apps/protocol/src/finance-overrides/FinanceOverrideRoutes.ts
17281
18009
  import { randomUUID as randomUUID6 } from "crypto";
17282
18010
 
17283
- // ../protocol/src/validation/ProtocolArtifacts.ts
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
- // ../../docs/decionis.protocol.schemas/v1/audit-ledger-entry.schema.json
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
- // ../../docs/decionis.protocol.schemas/v1/context-snapshot.schema.json
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
- // ../../docs/decionis.protocol.schemas/v1/decision-resolution.schema.json
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
- // ../../docs/decionis.protocol.schemas/v1/execution-dispatch.schema.json
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
- // ../../docs/decionis.protocol.schemas/v1/policy-bundle.schema.json
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: 3600
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
- // ../../docs/decionis.protocol.schemas/v1/signal-envelope.schema.json
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
- // ../protocol/src/validation/ProtocolArtifacts.ts
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
- // ../protocol/src/finance-overrides/FinanceOverrideContracts.ts
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
- // ../protocol/src/finance-overrides/FinanceOverrides.ts
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
- // ../protocol/src/finance-overrides/FinanceOverrideRoutes.ts
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
- // ../protocol/src/evaluate-decision/EvaluateDecisionRoutes.ts
20086
+ // ../../../Decionis/apps/protocol/src/evaluate-decision/EvaluateDecisionRoutes.ts
19336
20087
  import { createHash as createHash14, randomUUID as randomUUID10 } from "crypto";
19337
20088
 
19338
- // ../protocol/src/support/Performance.ts
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
- // ../protocol/src/verticals/affiliate-rewards/AffiliateRewardsPack.ts
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
- // ../protocol/src/verticals/core/CorePack.ts
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
- // ../protocol/src/verticals/devops/DevopsPack.ts
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
- // ../protocol/src/verticals/finance/FinancePack.ts
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
- // ../protocol/src/verticals/hospitality/HospitalityPack.ts
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
- // ../../packages/shared/src/Verticals/OpsDualGate.ts
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
- // ../protocol/src/verticals/personal/PersonalPack.ts
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
- // ../protocol/src/verticals/salesforce/SalesforcePack.ts
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
- // ../protocol/src/verticals/sap/SapPack.ts
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
- // ../protocol/src/verticals/template/TemplatePack.ts
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
- // ../protocol/src/verticals/workday/WorkdayPack.ts
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
- // ../protocol/src/verticals/workday-financials/WorkdayFinancialsPack.ts
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
- // ../protocol/src/verticals/workflows/WorkflowPacks.ts
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
- // ../protocol/src/verticals/VerticalRegistry.ts
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
- // ../protocol/src/verticals/VerticalResolver.ts
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
- // ../protocol/src/decision-chains/DecisionChains.ts
23297
+ // ../../../Decionis/apps/protocol/src/decision-chains/DecisionChains.ts
22381
23298
  import { randomUUID as randomUUID7 } from "crypto";
22382
23299
 
22383
- // ../protocol/src/integrity/DossierProofVerifier.ts
23300
+ // ../../../Decionis/apps/protocol/src/integrity/DossierProofVerifier.ts
22384
23301
  import { createHash as createHash12, verify } from "crypto";
22385
23302
 
22386
- // ../protocol/src/integrity/DossierProofBundle.ts
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
- // ../protocol/src/integrity/DossierProofVerifier.ts
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
- // ../protocol/src/decision-chains/DecisionChains.ts
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
- // ../protocol/src/support/PanDetection.ts
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
- // ../protocol/src/support/ProtocolUrls.ts
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
- // ../protocol/src/evaluate-decision/EvaluateDecisionParsing.ts
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
- // ../protocol/src/webex/WebexGovernance.ts
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
- // ../protocol/src/dossiers/DossierBuilder.ts
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
- return asNumber(context.signals_evaluated) ?? Object.keys(context).filter(
24399
- (key) => key !== "workflow_key" && key !== "vertical_pack" && key !== "trust_context"
24400
- ).length;
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
- // ../protocol/src/reproduce/ReproduceDecision.ts
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
- // ../protocol/src/support/FeatureFlags.ts
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
- // ../protocol/src/evaluate-decision/EvaluateDecisionGovernance.ts
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
- // ../protocol/src/evaluate-decision/EvaluateDecisionResolution.ts
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
- // ../protocol/src/authority/AuthorityRequirementIssuer.ts
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
- // ../protocol/src/execution-binding/ExecutionBindingBuilder.ts
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
- // ../protocol/src/decision-chains/SequenceContextProvider.ts
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
- // ../protocol/src/evaluate-decision/EvaluateDecisionRoutes.ts
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
- // ../protocol/src/webex/WebexRoutes.ts
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
- // ../protocol/src/surface-verify/SapVerifyRoutes.ts
27628
+ // ../../../Decionis/apps/protocol/src/surface-verify/SapVerifyRoutes.ts
26648
27629
  import { randomUUID as randomUUID11 } from "crypto";
26649
27630
 
26650
- // ../protocol/src/verticals/sap/SapSurface.ts
27631
+ // ../../../Decionis/apps/protocol/src/verticals/sap/SapSurface.ts
26651
27632
  import { createHash as createHash15 } from "crypto";
26652
27633
 
26653
- // ../protocol/src/verticals/shared/DuplicateDetection.ts
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
- // ../protocol/src/verticals/sap/SapSurface.ts
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
- // ../protocol/src/surface-verify/SurfaceVerifyShared.ts
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
- // ../protocol/src/surface-verify/SapVerifyRoutes.ts
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
- // ../protocol/src/surface-verify/SalesforceVerifyRoutes.ts
28129
+ // ../../../Decionis/apps/protocol/src/surface-verify/SalesforceVerifyRoutes.ts
27149
28130
  import { randomUUID as randomUUID12 } from "crypto";
27150
28131
 
27151
- // ../protocol/src/verticals/salesforce/SalesforceSurface.ts
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
- // ../protocol/src/verticals/salesforce/SapCostBasis.ts
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(evalPayload, gate, orgId)
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: costBasisSource,
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
- // ../protocol/src/surface-verify/OpsVerifyRoutes.ts
28561
+ // ../../../Decionis/apps/protocol/src/surface-verify/OpsVerifyRoutes.ts
27744
28562
  import { randomUUID as randomUUID13 } from "crypto";
27745
28563
 
27746
- // ../protocol/src/verticals/ops/OpsSurface.ts
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
- // ../protocol/src/surface-verify/OpsVerifyRoutes.ts
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
- // ../protocol/src/surface-verify/WorkdayVerifyRoutes.ts
28746
+ // ../../../Decionis/apps/protocol/src/surface-verify/WorkdayVerifyRoutes.ts
27929
28747
  import { randomUUID as randomUUID14 } from "crypto";
27930
28748
 
27931
- // ../protocol/src/verticals/workday/WorkdaySurface.ts
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
- // ../protocol/src/surface-verify/WorkdayVerifyRoutes.ts
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
- // ../protocol/src/surface-verify/WorkdayFinancialsVerifyRoutes.ts
29208
+ // ../../../Decionis/apps/protocol/src/surface-verify/WorkdayFinancialsVerifyRoutes.ts
28391
29209
  import { randomUUID as randomUUID15 } from "crypto";
28392
29210
 
28393
- // ../protocol/src/verticals/workday-financials/WorkdayFinancialsSurface.ts
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
- // ../protocol/src/surface-verify/WorkdayFinancialsVerifyRoutes.ts
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
- // ../protocol/src/surface-verify/SurfaceDecisionRoutes.ts
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
- // ../protocol/src/enforcement/EnforcementRolloutRoutes.ts
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
- // ../protocol/src/integrity/ProofPacket.ts
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
- // ../protocol/src/dossiers/ProofPacketAuth.ts
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
- // ../protocol/src/interop/scitt/aac-v04/AgentActionCapsuleV04.ts
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
- // ../protocol/src/interop/scitt/cose/ProducerEnvelope.ts
30684
+ // ../../../Decionis/apps/protocol/src/interop/scitt/cose/ProducerEnvelope.ts
29867
30685
  import { createPublicKey as createPublicKey2, verify as verifySignature } from "crypto";
29868
30686
 
29869
- // ../protocol/src/interop/scitt/cose/Cbor.ts
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
- // ../protocol/src/interop/scitt/cose/ProducerEnvelope.ts
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
- // ../protocol/src/interop/scitt/aac-v04/DossierMapper.ts
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
- // ../protocol/src/integrity/DossierLedgerAnchor.ts
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
- // ../protocol/src/decision-chains/DecisionChainRoutes.ts
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
- // ../protocol/src/dossiers/DossierCapsuleExport.ts
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
- // ../protocol/src/dossiers/DossierRoutes.ts
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
- // ../protocol/src/policy-graph/PolicyDecisionRegister.ts
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
- // ../protocol/src/policy-graph/PolicyDecisionRegisterRoutes.ts
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
- // ../protocol/src/artifacts/ArtifactIngestion.ts
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
- // ../protocol/src/artifacts/ArtifactRoutes.ts
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
- // ../protocol/src/marketplaces/MarketplaceProfiles.ts
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: "BUILDING",
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
- // ../protocol/src/marketplaces/MarketplaceContracts.ts
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
- // ../protocol/src/marketplaces/MarketplaceRoutes.ts
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
- // ../protocol/src/verticals/VerticalRoutes.ts
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
- // ../protocol/src/shadow/ShadowRoutes.ts
33170
+ // ../../../Decionis/apps/protocol/src/shadow/ShadowRoutes.ts
32328
33171
  import { createHash as createHash23 } from "crypto";
32329
33172
 
32330
- // ../protocol/src/shadow/ShadowDecisioning.ts
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
- // ../protocol/src/shadow/ShadowReports.ts
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
- // ../protocol/src/shadow/ShadowRoutes.ts
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
- // ../protocol/src/execution-binding/ExecutionRevalidationState.ts
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
- // ../protocol/src/execution-binding/ExecutionRevalidationRoutes.ts
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
- // ../protocol/src/interop/scitt/registration/ScittSignedStatement.ts
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
- // ../protocol/src/interop/scitt/registration/ScittRegistrationService.ts
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
- // ../protocol/src/app.ts
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-NF5JL6QR.js.map
34776
+ //# sourceMappingURL=chunk-5Q6BCK32.js.map