@inf-monkeys-tech/monkeys 1.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/lib/contracts/declarative-control-http.d.ts +55903 -73794
  2. package/lib/contracts/declarative-control-http.d.ts.map +1 -1
  3. package/lib/contracts/declarative-control-http.js +703 -544
  4. package/lib/contracts/declarative-control-http.js.map +1 -1
  5. package/lib/contracts/declarative-control.d.ts +1623 -3
  6. package/lib/contracts/declarative-control.d.ts.map +1 -1
  7. package/lib/contracts/declarative-control.js +2107 -1136
  8. package/lib/contracts/declarative-control.js.map +1 -1
  9. package/lib/contracts/render.d.ts +591 -1
  10. package/lib/contracts/render.d.ts.map +1 -1
  11. package/lib/contracts/render.js +331 -134
  12. package/lib/contracts/render.js.map +1 -1
  13. package/lib/contracts/tenant.d.ts +3 -3
  14. package/lib/contracts/theme.d.ts +1 -1
  15. package/lib/esm/contracts/index.mjs +1872 -409
  16. package/lib/esm/contracts/index.mjs.map +1 -1
  17. package/lib/esm/index.mjs +3028 -672
  18. package/lib/esm/index.mjs.map +1 -1
  19. package/lib/esm/runtime/index.mjs +3016 -670
  20. package/lib/esm/runtime/index.mjs.map +1 -1
  21. package/lib/esm/schemas/index.mjs +1866 -412
  22. package/lib/esm/schemas/index.mjs.map +1 -1
  23. package/lib/json-schema/overlay-node.schema.json +602 -0
  24. package/lib/json-schema/page-runtime-bundle.schema.json +602 -0
  25. package/lib/json-schema/page.schema.json +5619 -11743
  26. package/lib/json-schema/render-node.schema.json +602 -0
  27. package/lib/json-schema/render-tree.schema.json +602 -0
  28. package/lib/runtime/declarative-control-compiler.d.ts +52 -27
  29. package/lib/runtime/declarative-control-compiler.d.ts.map +1 -1
  30. package/lib/runtime/declarative-control-compiler.js +858 -366
  31. package/lib/runtime/declarative-control-compiler.js.map +1 -1
  32. package/lib/schemas/index.d.ts +787 -2335
  33. package/lib/schemas/index.d.ts.map +1 -1
  34. package/lib/schemas/index.js +100 -99
  35. package/lib/schemas/index.js.map +1 -1
  36. package/package.json +1 -1
@@ -1,22 +1,23 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.resolveWorkbenchEntry = exports.validateWorkbenchRuntimeSet = exports.compileNavigationRuntimeBundle = exports.compileWorkbenchRuntimeBundle = exports.compilePageRuntimeBundle = exports.materializeRouteSpacePath = exports.matchCompiledRouteClaim = exports.compileRouteClaims = exports.compiledRouteClaimsOverlap = exports.accessPolicyChainImplies = exports.parseExactDesignCapabilityCatalogArtifact = exports.parseExactProductDeclarativeCapabilityRegistration = exports.compileDesignCapabilityCatalogArtifact = exports.designCapabilityCatalogArtifactHash = exports.declarativeProductResourceRevisionHash = exports.declarativeProductResourceSourceHash = exports.declarativeRouteSpaceRevisionHash = exports.declarativeRouteSpaceSourceHash = exports.declarativeCreateTemplateRevisionHash = exports.declarativeCreateTemplateSourceHash = exports.compileDeclarativeWorkbenchCatalog = exports.compileDeclarativeRouteOwnerIndex = exports.permissionAlternativePolicyAllows = exports.parseExactLegacyRouteTakeoverAuthorization = exports.legacyRouteTakeoverAuthorizationHash = exports.compileLegacyRouteTakeoverAuthorization = exports.declarativeWorkbenchCatalogProjectionId = exports.declarativeRouteOwnerIndexProjectionId = exports.declarativeRuntimeProjectionId = exports.canonicalContentHash = exports.sameRevisionRef = exports.sameStableRef = exports.revisionRefKey = exports.stableRefKey = exports.DeclarativeControlCompilationError = void 0;
3
+ exports.resolveWorkbenchEntry = exports.validateWorkbenchRuntimeSet = exports.compileNavigationRuntimeBundle = exports.compileWorkbenchRuntimeBundle = exports.compilePageRuntimeBundle = exports.resolvePage = exports.materializeRouteSpacePath = exports.matchCompiledRouteClaim = exports.compileRouteClaims = exports.compiledRouteClaimsOverlap = exports.accessPolicyChainImplies = exports.parseExactDesignCapabilityCatalogArtifact = exports.parseExactProductDeclarativeCapabilityRegistration = exports.compileDesignCapabilityCatalogArtifact = exports.designCapabilityCatalogArtifactHash = exports.declarativeProductResourceRevisionHash = exports.declarativeProductResourceSourceHash = exports.declarativeRouteSpaceRevisionHash = exports.declarativeRouteSpaceSourceHash = exports.declarativeCreateTemplateRevisionHash = exports.declarativeCreateTemplateSourceHash = exports.compileDeclarativeWorkbenchCatalog = exports.compileDeclarativeRouteOwnerIndex = exports.permissionAlternativePolicyAllows = exports.parseExactLegacyRouteTakeoverAuthorization = exports.legacyRouteTakeoverAuthorizationHash = exports.compileLegacyRouteTakeoverAuthorization = exports.declarativeWorkbenchCatalogProjectionId = exports.declarativeRouteOwnerIndexProjectionId = exports.declarativeRuntimeProjectionId = exports.canonicalContentHash = exports.sameRevisionRef = exports.sameStableRef = exports.revisionRefKey = exports.stableRefKey = exports.DeclarativeControlCompilationError = void 0;
4
4
  const common_1 = require("../contracts/common");
5
5
  const declarative_control_http_1 = require("../contracts/declarative-control-http");
6
6
  const render_tree_compiler_1 = require("./render-tree-compiler");
7
+ const page_expression_1 = require("../contracts/page-expression");
7
8
  const declarative_control_1 = require("../contracts/declarative-control");
8
9
  class DeclarativeControlCompilationError extends Error {
9
10
  constructor(code, path, message) {
10
11
  super(`${code} at ${path}: ${message}`);
11
12
  this.code = code;
12
13
  this.path = path;
13
- this.name = 'DeclarativeControlCompilationError';
14
+ this.name = "DeclarativeControlCompilationError";
14
15
  }
15
16
  }
16
17
  exports.DeclarativeControlCompilationError = DeclarativeControlCompilationError;
17
18
  const scopedIdentityKey = (reference) => `${reference.kind}:${reference.id}:${reference.ownerRepo}`;
18
- const scopeKey = (scope) => `${scopedIdentityKey(scope.tenantRef)}:${scopedIdentityKey(scope.dataSpaceRef)}:${scope.teamRef ? scopedIdentityKey(scope.teamRef) : ''}`;
19
- const stableRefKey = (reference) => `${reference.visibility}:${reference.tenantScope ? scopeKey(reference.tenantScope) : ''}:${reference.kind}:${reference.id}:${reference.ownerRepo}`;
19
+ const scopeKey = (scope) => `${scopedIdentityKey(scope.tenantRef)}:${scopedIdentityKey(scope.dataSpaceRef)}:${scope.teamRef ? scopedIdentityKey(scope.teamRef) : ""}`;
20
+ const stableRefKey = (reference) => `${reference.visibility}:${reference.tenantScope ? scopeKey(reference.tenantScope) : ""}:${reference.kind}:${reference.id}:${reference.ownerRepo}`;
20
21
  exports.stableRefKey = stableRefKey;
21
22
  const revisionRefKey = (reference) => `${(0, exports.stableRefKey)(reference)}@${reference.revision}:v${reference.schemaVersion}:${reference.contentHash.toLowerCase()}`;
22
23
  exports.revisionRefKey = revisionRefKey;
@@ -28,35 +29,41 @@ const assertUniqueRegistryKeys = (keys, path) => {
28
29
  const seen = new Set();
29
30
  keys.forEach((key, index) => {
30
31
  if (seen.has(key)) {
31
- throw new DeclarativeControlCompilationError('REGISTRY_CONFLICT', `${path}[${index}]`, `Duplicate registry identity: ${key}`);
32
+ throw new DeclarativeControlCompilationError("REGISTRY_CONFLICT", `${path}[${index}]`, `Duplicate registry identity: ${key}`);
32
33
  }
33
34
  seen.add(key);
34
35
  });
35
36
  };
36
37
  const stableSerialize = (value) => {
37
38
  if (value === undefined)
38
- return 'null';
39
- if (value === null || typeof value !== 'object')
40
- return JSON.stringify(value) ?? 'null';
39
+ return "null";
40
+ if (value === null || typeof value !== "object")
41
+ return JSON.stringify(value) ?? "null";
41
42
  if (Array.isArray(value))
42
- return `[${value.map((item) => stableSerialize(item)).join(',')}]`;
43
+ return `[${value.map((item) => stableSerialize(item)).join(",")}]`;
43
44
  const record = value;
44
45
  return `{${Object.keys(record)
45
46
  .filter((key) => record[key] !== undefined)
46
47
  .sort()
47
48
  .map((key) => `${JSON.stringify(key)}:${stableSerialize(record[key])}`)
48
- .join(',')}}`;
49
+ .join(",")}}`;
49
50
  };
50
- const SHA256_INITIAL = [0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19];
51
+ const SHA256_INITIAL = [
52
+ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c,
53
+ 0x1f83d9ab, 0x5be0cd19,
54
+ ];
51
55
  const SHA256_ROUND = [
52
- 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98,
53
- 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
54
- 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8,
55
- 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
56
- 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819,
57
- 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
58
- 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7,
59
- 0xc67178f2,
56
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
57
+ 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
58
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
59
+ 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
60
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
61
+ 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
62
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
63
+ 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
64
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
65
+ 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
66
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
60
67
  ];
61
68
  const rotateRight = (value, amount) => (value >>> amount) | (value << (32 - amount));
62
69
  const sha256Hex = (value) => {
@@ -77,14 +84,19 @@ const sha256Hex = (value) => {
77
84
  for (let index = 0; index < 16; index += 1) {
78
85
  const start = offset + index * 4;
79
86
  words[index] =
80
- ((source[start] << 24) | (source[start + 1] << 16) | (source[start + 2] << 8) | source[start + 3]) >>> 0;
87
+ ((source[start] << 24) |
88
+ (source[start + 1] << 16) |
89
+ (source[start + 2] << 8) |
90
+ source[start + 3]) >>>
91
+ 0;
81
92
  }
82
93
  for (let index = 16; index < 64; index += 1) {
83
94
  const previous = words[index - 15];
84
95
  const recent = words[index - 2];
85
96
  const small0 = rotateRight(previous, 7) ^ rotateRight(previous, 18) ^ (previous >>> 3);
86
97
  const small1 = rotateRight(recent, 17) ^ rotateRight(recent, 19) ^ (recent >>> 10);
87
- words[index] = (words[index - 16] + small0 + words[index - 7] + small1) >>> 0;
98
+ words[index] =
99
+ (words[index - 16] + small0 + words[index - 7] + small1) >>> 0;
88
100
  }
89
101
  let [a, b, c, d, e, f, g, h] = hash;
90
102
  for (let index = 0; index < 64; index += 1) {
@@ -112,7 +124,7 @@ const sha256Hex = (value) => {
112
124
  hash[6] = (hash[6] + g) >>> 0;
113
125
  hash[7] = (hash[7] + h) >>> 0;
114
126
  }
115
- return hash.map((part) => part.toString(16).padStart(8, '0')).join('');
127
+ return hash.map((part) => part.toString(16).padStart(8, "0")).join("");
116
128
  };
117
129
  const canonicalContentHash = (value) => sha256Hex(stableSerialize(value));
118
130
  exports.canonicalContentHash = canonicalContentHash;
@@ -126,7 +138,9 @@ exports.declarativeRuntimeProjectionId = declarativeRuntimeProjectionId;
126
138
  /** Names the rebuildable route-owner index for one tenant environment surface. */
127
139
  const declarativeRouteOwnerIndexProjectionId = (tenantScope, environmentRef, surface) => `dri:${(0, exports.canonicalContentHash)({
128
140
  tenantScope: {
129
- teamRef: tenantScope.teamRef ? { kind: tenantScope.teamRef.kind, id: tenantScope.teamRef.id } : null,
141
+ teamRef: tenantScope.teamRef
142
+ ? { kind: tenantScope.teamRef.kind, id: tenantScope.teamRef.id }
143
+ : null,
130
144
  },
131
145
  environmentRef,
132
146
  surface,
@@ -134,7 +148,9 @@ const declarativeRouteOwnerIndexProjectionId = (tenantScope, environmentRef, sur
134
148
  exports.declarativeRouteOwnerIndexProjectionId = declarativeRouteOwnerIndexProjectionId;
135
149
  const declarativeWorkbenchCatalogProjectionId = (tenantScope, environmentRef, surface) => `dwc:${(0, exports.canonicalContentHash)({
136
150
  tenantScope: {
137
- teamRef: tenantScope.teamRef ? { kind: tenantScope.teamRef.kind, id: tenantScope.teamRef.id } : null,
151
+ teamRef: tenantScope.teamRef
152
+ ? { kind: tenantScope.teamRef.kind, id: tenantScope.teamRef.id }
153
+ : null,
138
154
  },
139
155
  environmentRef,
140
156
  surface,
@@ -144,7 +160,7 @@ const takeoverHashSource = (authorization) => authorization;
144
160
  const compileLegacyRouteTakeoverAuthorization = (input) => {
145
161
  const unsigned = {
146
162
  ...input,
147
- contract: 'LegacyRouteTakeoverAuthorization',
163
+ contract: "LegacyRouteTakeoverAuthorization",
148
164
  schemaVersion: 1,
149
165
  };
150
166
  return deepFreeze(declarative_control_1.LegacyRouteTakeoverAuthorizationSchema.parse({
@@ -159,7 +175,7 @@ const parseExactLegacyRouteTakeoverAuthorization = (input) => {
159
175
  const parsed = declarative_control_1.LegacyRouteTakeoverAuthorizationSchema.parse(input);
160
176
  const { contentHash, ...unsigned } = parsed;
161
177
  if (contentHash !== (0, exports.legacyRouteTakeoverAuthorizationHash)(unsigned)) {
162
- throw new DeclarativeControlCompilationError('ROUTE_TAKEOVER_INVALID', 'contentHash', 'Legacy route takeover authorization content hash is not exact.');
178
+ throw new DeclarativeControlCompilationError("ROUTE_TAKEOVER_INVALID", "contentHash", "Legacy route takeover authorization content hash is not exact.");
163
179
  }
164
180
  return deepFreeze(parsed);
165
181
  };
@@ -179,7 +195,7 @@ const compileDeclarativeRouteOwnerIndex = (input) => {
179
195
  return leftKey.localeCompare(rightKey);
180
196
  });
181
197
  const unsigned = {
182
- contract: 'DeclarativeRouteOwnerIndex',
198
+ contract: "DeclarativeRouteOwnerIndex",
183
199
  schemaVersion: 1,
184
200
  tenantScope: declarative_control_1.TenantScopeSchema.parse(input.tenantScope),
185
201
  environmentRef: declarative_control_1.StableRefSchema.parse(input.environmentRef),
@@ -197,9 +213,10 @@ exports.compileDeclarativeRouteOwnerIndex = compileDeclarativeRouteOwnerIndex;
197
213
  const compileDeclarativeWorkbenchCatalog = (input) => {
198
214
  const entries = input.entries
199
215
  .map((entry) => ({ ...entry }))
200
- .sort((left, right) => left.order - right.order || left.workbenchId.localeCompare(right.workbenchId));
216
+ .sort((left, right) => left.order - right.order ||
217
+ left.workbenchId.localeCompare(right.workbenchId));
201
218
  const unsigned = {
202
- contract: 'DeclarativeWorkbenchCatalog',
219
+ contract: "DeclarativeWorkbenchCatalog",
203
220
  schemaVersion: 1,
204
221
  tenantScope: declarative_control_1.TenantScopeSchema.parse(input.tenantScope),
205
222
  environmentRef: declarative_control_1.StableRefSchema.parse(input.environmentRef),
@@ -227,7 +244,7 @@ exports.declarativeProductResourceSourceHash = declarativeProductResourceSourceH
227
244
  const declarativeProductResourceRevisionHash = (registration) => (0, exports.canonicalContentHash)(registration.document);
228
245
  exports.declarativeProductResourceRevisionHash = declarativeProductResourceRevisionHash;
229
246
  const designCapabilityCatalogHashSource = (input) => ({
230
- contract: 'DesignCapabilityCatalogArtifact',
247
+ contract: "DesignCapabilityCatalogArtifact",
231
248
  schemaVersion: 1,
232
249
  sourceRef: input.sourceRef,
233
250
  entries: input.entries,
@@ -243,22 +260,28 @@ const compileDesignCapabilityCatalogArtifact = (input) => {
243
260
  const { registrationRevisionRef: _registrationRevisionRef, sourceContentHash: _sourceContentHash, ...unsignedRegistration } = registration;
244
261
  const registrationHash = (0, exports.canonicalContentHash)(unsignedRegistration);
245
262
  if (registration.capabilityRevisionRef.id !== entry.manifest.id ||
246
- registration.capabilityRevisionRef.ownerRepo !== entry.manifest.ownerRepo ||
247
- String(registration.capabilityRevisionRef.revision) !== String(entry.manifest.capabilityVersion) ||
248
- registration.capabilityRevisionRef.contentHash !== (0, exports.canonicalContentHash)(entry.manifest) ||
263
+ registration.capabilityRevisionRef.ownerRepo !==
264
+ entry.manifest.ownerRepo ||
265
+ String(registration.capabilityRevisionRef.revision) !==
266
+ String(entry.manifest.capabilityVersion) ||
267
+ registration.capabilityRevisionRef.contentHash !==
268
+ (0, exports.canonicalContentHash)(entry.manifest) ||
249
269
  registration.providerRevisionRef.id !== entry.provider.providerId ||
250
270
  registration.providerRevisionRef.ownerRepo !== entry.provider.ownerRepo ||
251
- String(registration.providerRevisionRef.revision) !== String(entry.provider.providerVersion) ||
252
- registration.providerRevisionRef.contentHash !== (0, exports.canonicalContentHash)(entry.provider) ||
271
+ String(registration.providerRevisionRef.revision) !==
272
+ String(entry.provider.providerVersion) ||
273
+ registration.providerRevisionRef.contentHash !==
274
+ (0, exports.canonicalContentHash)(entry.provider) ||
253
275
  registration.sourceContentHash !== registrationHash ||
254
276
  registration.registrationRevisionRef.contentHash !== registrationHash) {
255
- throw new DeclarativeControlCompilationError('DESIGN_CATALOG_INVALID', `entries[${index}]`, 'Design capability manifest, provider and authoring registration are not exact.');
277
+ throw new DeclarativeControlCompilationError("DESIGN_CATALOG_INVALID", `entries[${index}]`, "Design capability manifest, provider and authoring registration are not exact.");
256
278
  }
257
279
  registration.schemaDocuments.forEach((schema, schemaIndex) => {
258
- if (schema.schemaRevisionRef.ownerRepo !== 'monkeys-design' ||
259
- schema.schemaRevisionRef.visibility !== 'global' ||
260
- schema.schemaRevisionRef.contentHash !== (0, exports.canonicalContentHash)(schema.document)) {
261
- throw new DeclarativeControlCompilationError('DESIGN_CATALOG_INVALID', `entries[${index}].declarativeRegistration.schemaDocuments[${schemaIndex}]`, 'Design Schema documents require exact global monkeys-design authority.');
280
+ if (schema.schemaRevisionRef.ownerRepo !== "monkeys-design" ||
281
+ schema.schemaRevisionRef.visibility !== "global" ||
282
+ schema.schemaRevisionRef.contentHash !==
283
+ (0, exports.canonicalContentHash)(schema.document)) {
284
+ throw new DeclarativeControlCompilationError("DESIGN_CATALOG_INVALID", `entries[${index}].declarativeRegistration.schemaDocuments[${schemaIndex}]`, "Design Schema documents require exact global monkeys-design authority.");
262
285
  }
263
286
  });
264
287
  });
@@ -267,16 +290,16 @@ const compileDesignCapabilityCatalogArtifact = (input) => {
267
290
  entries,
268
291
  });
269
292
  const sourceRevisionRef = declarative_control_1.RevisionRefSchema.parse({
270
- kind: 'design-capability-catalog',
293
+ kind: "design-capability-catalog",
271
294
  id: input.sourceRef,
272
- ownerRepo: 'monkeys-design',
273
- visibility: 'global',
295
+ ownerRepo: "monkeys-design",
296
+ visibility: "global",
274
297
  revision: input.revision,
275
298
  schemaVersion: 1,
276
299
  contentHash: sourceContentHash,
277
300
  });
278
301
  return deepFreeze(declarative_control_http_1.DesignCapabilityCatalogArtifactSchema.parse({
279
- contract: 'DesignCapabilityCatalogArtifact',
302
+ contract: "DesignCapabilityCatalogArtifact",
280
303
  schemaVersion: 1,
281
304
  sourceRef: input.sourceRef,
282
305
  sourceRevisionRef,
@@ -290,15 +313,20 @@ const parseExactProductDeclarativeCapabilityRegistration = (input) => {
290
313
  const entry = declarative_control_http_1.ProductDeclarativeCapabilityRegistrationSchema.parse(input);
291
314
  const registration = entry.declarativeRegistration;
292
315
  const { registrationRevisionRef: _registrationRevisionRef, sourceContentHash: _sourceContentHash, ...unsignedRegistration } = registration;
293
- if (registration.capabilityRevisionRef.contentHash !== (0, exports.canonicalContentHash)(entry.manifest) ||
294
- registration.providerRevisionRef.contentHash !== (0, exports.canonicalContentHash)(entry.provider) ||
295
- registration.sourceContentHash !== (0, exports.canonicalContentHash)(unsignedRegistration) ||
296
- registration.registrationRevisionRef.contentHash !== registration.sourceContentHash) {
297
- throw new DeclarativeControlCompilationError('PRODUCT_CAPABILITY_CATALOG_INVALID', 'declarativeRegistration', 'Product capability manifest, provider and authoring registration are not exact.');
316
+ if (registration.capabilityRevisionRef.contentHash !==
317
+ (0, exports.canonicalContentHash)(entry.manifest) ||
318
+ registration.providerRevisionRef.contentHash !==
319
+ (0, exports.canonicalContentHash)(entry.provider) ||
320
+ registration.sourceContentHash !==
321
+ (0, exports.canonicalContentHash)(unsignedRegistration) ||
322
+ registration.registrationRevisionRef.contentHash !==
323
+ registration.sourceContentHash) {
324
+ throw new DeclarativeControlCompilationError("PRODUCT_CAPABILITY_CATALOG_INVALID", "declarativeRegistration", "Product capability manifest, provider and authoring registration are not exact.");
298
325
  }
299
326
  registration.schemaDocuments.forEach((schema, schemaIndex) => {
300
- if (schema.schemaRevisionRef.contentHash !== (0, exports.canonicalContentHash)(schema.document)) {
301
- throw new DeclarativeControlCompilationError('PRODUCT_CAPABILITY_CATALOG_INVALID', `declarativeRegistration.schemaDocuments[${schemaIndex}]`, 'Product capability Schema document does not match its exact RevisionRef.');
327
+ if (schema.schemaRevisionRef.contentHash !==
328
+ (0, exports.canonicalContentHash)(schema.document)) {
329
+ throw new DeclarativeControlCompilationError("PRODUCT_CAPABILITY_CATALOG_INVALID", `declarativeRegistration.schemaDocuments[${schemaIndex}]`, "Product capability Schema document does not match its exact RevisionRef.");
302
330
  }
303
331
  });
304
332
  return deepFreeze(entry);
@@ -313,25 +341,26 @@ const parseExactDesignCapabilityCatalogArtifact = (input) => {
313
341
  });
314
342
  if (parsed.sourceContentHash !== expected.sourceContentHash ||
315
343
  !(0, exports.sameRevisionRef)(parsed.sourceRevisionRef, expected.sourceRevisionRef)) {
316
- throw new DeclarativeControlCompilationError('DESIGN_CATALOG_INVALID', 'sourceRevisionRef', 'Design capability catalog artifact provenance or content hash is not exact.');
344
+ throw new DeclarativeControlCompilationError("DESIGN_CATALOG_INVALID", "sourceRevisionRef", "Design capability catalog artifact provenance or content hash is not exact.");
317
345
  }
318
346
  return deepFreeze(parsed);
319
347
  };
320
348
  exports.parseExactDesignCapabilityCatalogArtifact = parseExactDesignCapabilityCatalogArtifact;
321
349
  const deepFreeze = (value) => {
322
- if (value === null || typeof value !== 'object' || Object.isFrozen(value))
350
+ if (value === null || typeof value !== "object" || Object.isFrozen(value))
323
351
  return value;
324
352
  Object.values(value).forEach((child) => deepFreeze(child));
325
353
  return Object.freeze(value);
326
354
  };
327
355
  const assertTenantCompatible = (reference, scope, path) => {
328
- if (reference.visibility === 'tenant' && scopeKey(reference.tenantScope) !== scopeKey(scope)) {
329
- throw new DeclarativeControlCompilationError('CROSS_TENANT_REFERENCE', path, `Reference ${reference.kind}/${reference.id} belongs to another tenant scope.`);
356
+ if (reference.visibility === "tenant" &&
357
+ scopeKey(reference.tenantScope) !== scopeKey(scope)) {
358
+ throw new DeclarativeControlCompilationError("CROSS_TENANT_REFERENCE", path, `Reference ${reference.kind}/${reference.id} belongs to another tenant scope.`);
330
359
  }
331
360
  };
332
361
  const assertSameTenantScope = (candidate, expected, path) => {
333
362
  if (scopeKey(candidate) !== scopeKey(expected)) {
334
- throw new DeclarativeControlCompilationError('CROSS_TENANT_REFERENCE', path, 'Record and release tenant scopes do not match.');
363
+ throw new DeclarativeControlCompilationError("CROSS_TENANT_REFERENCE", path, "Record and release tenant scopes do not match.");
335
364
  }
336
365
  };
337
366
  const stableFromRevision = (reference) => declarative_control_1.StableRefSchema.parse({
@@ -343,7 +372,7 @@ const stableFromRevision = (reference) => declarative_control_1.StableRefSchema.
343
372
  });
344
373
  const assertRevisionIdentity = (reference, expectedKind, expectedId, scope, path) => {
345
374
  if (reference.kind !== expectedKind || reference.id !== expectedId) {
346
- throw new DeclarativeControlCompilationError('REVISION_MISMATCH', path, `Expected ${expectedKind}/${expectedId}, received ${reference.kind}/${reference.id}.`);
375
+ throw new DeclarativeControlCompilationError("REVISION_MISMATCH", path, `Expected ${expectedKind}/${expectedId}, received ${reference.kind}/${reference.id}.`);
347
376
  }
348
377
  assertTenantCompatible(reference, scope, path);
349
378
  };
@@ -353,28 +382,28 @@ const requireDependencies = (snapshot, required) => {
353
382
  for (const dependency of required) {
354
383
  const key = dependencyKey(dependency.role, dependency.revisionRef);
355
384
  if (!available.has(key)) {
356
- throw new DeclarativeControlCompilationError('DEPENDENCY_MISSING', 'dependencySnapshot', `Missing exact ${dependency.role} dependency ${(0, exports.revisionRefKey)(dependency.revisionRef)}.`);
385
+ throw new DeclarativeControlCompilationError("DEPENDENCY_MISSING", "dependencySnapshot", `Missing exact ${dependency.role} dependency ${(0, exports.revisionRefKey)(dependency.revisionRef)}.`);
357
386
  }
358
387
  }
359
388
  };
360
389
  const assertDependencyScopes = (snapshot, scope) => snapshot.forEach((dependency, index) => assertTenantCompatible(dependency.revisionRef, scope, `dependencySnapshot[${index}].revisionRef`));
361
390
  const requireReleaseReady = (release) => {
362
- if (release.operation === 'deactivate') {
363
- throw new DeclarativeControlCompilationError('RELEASE_OPERATION_INVALID', 'operation', 'A deactivation Release cannot produce an active runtime bundle.');
391
+ if (release.operation === "deactivate") {
392
+ throw new DeclarativeControlCompilationError("RELEASE_OPERATION_INVALID", "operation", "A deactivation Release cannot produce an active runtime bundle.");
364
393
  }
365
- if (release.evidence.validation.result !== 'pass') {
366
- throw new DeclarativeControlCompilationError('RELEASE_VALIDATION_FAILED', 'evidence.validation.result', 'Runtime bundles require a passing release validation result.');
394
+ if (release.evidence.validation.result !== "pass") {
395
+ throw new DeclarativeControlCompilationError("RELEASE_VALIDATION_FAILED", "evidence.validation.result", "Runtime bundles require a passing release validation result.");
367
396
  }
368
397
  };
369
398
  const refSet = (values) => new Set(values.map(exports.stableRefKey));
370
399
  const chainRequiresAll = (policies, field) => {
371
- if (field === 'permissionAllOf') {
400
+ if (field === "permissionAllOf") {
372
401
  return new Set(policies.flatMap((policy) => [
373
402
  ...policy.permissionAllOf,
374
403
  ...(policy.permissionAnyOf.length === 1 ? policy.permissionAnyOf : []),
375
404
  ]));
376
405
  }
377
- if (field === 'groupAllOf') {
406
+ if (field === "groupAllOf") {
378
407
  return refSet(policies.flatMap((policy) => [
379
408
  ...policy.groupAllOf,
380
409
  ...(policy.groupAnyOf.length === 1 ? policy.groupAnyOf : []),
@@ -397,17 +426,17 @@ const accessPolicyChainImplies = (policyInputs, targetInput) => {
397
426
  const target = declarative_control_1.AccessPolicySchema.parse(targetInput);
398
427
  if (target.authenticated && !policies.some((policy) => policy.authenticated))
399
428
  return false;
400
- const permissionAll = chainRequiresAll(policies, 'permissionAllOf');
429
+ const permissionAll = chainRequiresAll(policies, "permissionAllOf");
401
430
  if (target.permissionAllOf.some((permission) => !permissionAll.has(permission)))
402
431
  return false;
403
432
  if (!chainImpliesAny(policies, new Set(target.permissionAnyOf), permissionAll, (policy) => policy.permissionAnyOf))
404
433
  return false;
405
- const groupAll = chainRequiresAll(policies, 'groupAllOf');
434
+ const groupAll = chainRequiresAll(policies, "groupAllOf");
406
435
  if (target.groupAllOf.some((group) => !groupAll.has((0, exports.stableRefKey)(group))))
407
436
  return false;
408
437
  if (!chainImpliesAny(policies, refSet(target.groupAnyOf), groupAll, (policy) => policy.groupAnyOf.map(exports.stableRefKey)))
409
438
  return false;
410
- const conditionAll = chainRequiresAll(policies, 'conditionAllOf');
439
+ const conditionAll = chainRequiresAll(policies, "conditionAllOf");
411
440
  if (target.conditionAllOf.some((condition) => !conditionAll.has((0, exports.revisionRefKey)(condition))))
412
441
  return false;
413
442
  return true;
@@ -417,22 +446,26 @@ const normalizePath = (path, routeSpace) => {
417
446
  let normalized = path;
418
447
  if (!routeSpace.caseSensitive) {
419
448
  normalized = normalized
420
- .split('/')
421
- .map((segment) => (segment.startsWith(':') ? segment : segment.toLowerCase()))
422
- .join('/');
449
+ .split("/")
450
+ .map((segment) => segment.startsWith(":") ? segment : segment.toLowerCase())
451
+ .join("/");
423
452
  }
424
- if (routeSpace.trailingSlash === 'remove' && normalized.length > 1)
425
- normalized = normalized.replace(/\/+$/, '');
426
- if (routeSpace.trailingSlash === 'require' && normalized.length > 1 && !normalized.endsWith('/'))
427
- normalized += '/';
453
+ if (routeSpace.trailingSlash === "remove" && normalized.length > 1)
454
+ normalized = normalized.replace(/\/+$/, "");
455
+ if (routeSpace.trailingSlash === "require" &&
456
+ normalized.length > 1 &&
457
+ !normalized.endsWith("/"))
458
+ normalized += "/";
428
459
  return normalized;
429
460
  };
430
461
  const acceptedTrailingSlashStates = (claim) => {
431
- if (claim.matcher.trailingSlash === 'remove')
462
+ if (claim.matcher.trailingSlash === "remove")
432
463
  return new Set([false, true]);
433
- if (claim.matcher.trailingSlash === 'require')
464
+ if (claim.matcher.trailingSlash === "require")
434
465
  return new Set([true]);
435
- return new Set([claim.normalizedPath.length > 1 && claim.normalizedPath.endsWith('/')]);
466
+ return new Set([
467
+ claim.normalizedPath.length > 1 && claim.normalizedPath.endsWith("/"),
468
+ ]);
436
469
  };
437
470
  const routeSegmentParameter = (segment) => segment.match(/^[:$]([A-Za-z][A-Za-z0-9_-]*)$/)?.[1];
438
471
  const parameterTypeFor = (claim, name) => claim.matcher.parameters.find((parameter) => parameter.name === name)?.type;
@@ -441,8 +474,8 @@ const compiledRouteClaimsOverlap = (leftInput, rightInput) => {
441
474
  const right = declarative_control_1.CompiledRouteClaimSchema.parse(rightInput);
442
475
  if (![...acceptedTrailingSlashStates(left)].some((state) => acceptedTrailingSlashStates(right).has(state)))
443
476
  return false;
444
- const leftSegments = left.normalizedPath.split('/').filter(Boolean);
445
- const rightSegments = right.normalizedPath.split('/').filter(Boolean);
477
+ const leftSegments = left.normalizedPath.split("/").filter(Boolean);
478
+ const rightSegments = right.normalizedPath.split("/").filter(Boolean);
446
479
  if (leftSegments.length !== rightSegments.length)
447
480
  return false;
448
481
  return leftSegments.every((leftSegment, index) => {
@@ -466,16 +499,22 @@ const compiledRouteClaimsOverlap = (leftInput, rightInput) => {
466
499
  const rightType = parameterTypeFor(right, rightParameter);
467
500
  if (!leftType || !rightType)
468
501
  return false;
469
- return !(leftType === 'integer' && rightType === 'uuid') && !(leftType === 'uuid' && rightType === 'integer');
502
+ return (!(leftType === "integer" && rightType === "uuid") &&
503
+ !(leftType === "uuid" && rightType === "integer"));
470
504
  });
471
505
  };
472
506
  exports.compiledRouteClaimsOverlap = compiledRouteClaimsOverlap;
473
507
  const compileRouteClaims = (input) => {
474
508
  const embeddedTakeovers = input.claims.flatMap((claim) => {
475
- const authorization = 'legacyRouteTakeoverAuthorization' in claim ? claim.legacyRouteTakeoverAuthorization : undefined;
509
+ const authorization = "legacyRouteTakeoverAuthorization" in claim
510
+ ? claim.legacyRouteTakeoverAuthorization
511
+ : undefined;
476
512
  return authorization ? [authorization] : [];
477
513
  });
478
- const takeoverAuthorizations = [...(input.legacyRouteTakeoverAuthorizations ?? []), ...embeddedTakeovers].map((authorization, index) => {
514
+ const takeoverAuthorizations = [
515
+ ...(input.legacyRouteTakeoverAuthorizations ?? []),
516
+ ...embeddedTakeovers,
517
+ ].map((authorization, index) => {
479
518
  try {
480
519
  return (0, exports.parseExactLegacyRouteTakeoverAuthorization)(authorization);
481
520
  }
@@ -489,38 +528,48 @@ const compileRouteClaims = (input) => {
489
528
  const registrations = input.routeSpaces.map((entry, index) => {
490
529
  const revisionRef = declarative_control_1.RevisionRefSchema.parse(entry.revisionRef);
491
530
  const routeSpace = declarative_control_1.RouteSpaceSchema.parse(entry.routeSpace);
492
- if (revisionRef.kind !== 'route-space' || revisionRef.id !== routeSpace.routeSpaceId) {
493
- throw new DeclarativeControlCompilationError('ROUTE_SPACE_MISMATCH', `routeSpaces[${index}]`, 'RouteSpace registration identity does not match its pinned revision.');
531
+ if (revisionRef.kind !== "route-space" ||
532
+ revisionRef.id !== routeSpace.routeSpaceId) {
533
+ throw new DeclarativeControlCompilationError("ROUTE_SPACE_MISMATCH", `routeSpaces[${index}]`, "RouteSpace registration identity does not match its pinned revision.");
494
534
  }
495
535
  return { revisionRef, routeSpace };
496
536
  });
497
- assertUniqueRegistryKeys(registrations.map((entry) => (0, exports.revisionRefKey)(entry.revisionRef)), 'routeSpaces');
498
- const routeSpacesByRevision = new Map(registrations.map((entry) => [(0, exports.revisionRefKey)(entry.revisionRef), entry.routeSpace]));
537
+ assertUniqueRegistryKeys(registrations.map((entry) => (0, exports.revisionRefKey)(entry.revisionRef)), "routeSpaces");
538
+ const routeSpacesByRevision = new Map(registrations.map((entry) => [
539
+ (0, exports.revisionRefKey)(entry.revisionRef),
540
+ entry.routeSpace,
541
+ ]));
499
542
  const compiled = [];
500
543
  input.claims.forEach((inputClaim, index) => {
501
544
  const { legacyRouteTakeoverAuthorization: _authorization, ...runtimeClaim } = inputClaim;
502
- const legacyClaim = 'surface' in runtimeClaim ? declarative_control_1.RouteClaimSchema.parse(runtimeClaim) : declarative_control_1.LegacyRouteClaimSchema.parse(runtimeClaim);
545
+ const legacyClaim = "surface" in runtimeClaim
546
+ ? declarative_control_1.RouteClaimSchema.parse(runtimeClaim)
547
+ : declarative_control_1.LegacyRouteClaimSchema.parse(runtimeClaim);
503
548
  const routeSpace = routeSpacesByRevision.get((0, exports.revisionRefKey)(legacyClaim.routeSpaceRevisionRef));
504
549
  if (!routeSpace)
505
- throw new DeclarativeControlCompilationError('ROUTE_SPACE_MISSING', `routeClaims[${index}].routeSpaceRevisionRef`, 'No exact RouteSpace registration exists.');
550
+ throw new DeclarativeControlCompilationError("ROUTE_SPACE_MISSING", `routeClaims[${index}].routeSpaceRevisionRef`, "No exact RouteSpace registration exists.");
506
551
  const claim = declarative_control_1.RouteClaimSchema.parse({
507
552
  ...legacyClaim,
508
- surface: 'surface' in legacyClaim ? legacyClaim.surface : routeSpace.supportedSurface,
553
+ surface: "surface" in legacyClaim
554
+ ? legacyClaim.surface
555
+ : routeSpace.supportedSurface,
509
556
  });
510
557
  if (routeSpace.supportedSurface !== claim.surface) {
511
- throw new DeclarativeControlCompilationError('ROUTE_SPACE_MISMATCH', `routeClaims[${index}].surface`, `Route claim surface ${claim.surface} does not match RouteSpace ${routeSpace.routeSpaceId}.`);
558
+ throw new DeclarativeControlCompilationError("ROUTE_SPACE_MISMATCH", `routeClaims[${index}].surface`, `Route claim surface ${claim.surface} does not match RouteSpace ${routeSpace.routeSpaceId}.`);
512
559
  }
513
560
  if (claim.surface !== input.surface)
514
561
  return;
515
562
  const normalizedPath = normalizePath(claim.pathTemplate, routeSpace);
516
563
  const knownParameters = new Set(routeSpace.parameters.map((parameter) => parameter.name));
517
- const pathParameters = [...normalizedPath.matchAll(/:([A-Za-z][A-Za-z0-9_-]*)/g)].map((match) => match[1]);
564
+ const pathParameters = [
565
+ ...normalizedPath.matchAll(/:([A-Za-z][A-Za-z0-9_-]*)/g),
566
+ ].map((match) => match[1]);
518
567
  if (new Set(pathParameters).size !== pathParameters.length) {
519
- throw new DeclarativeControlCompilationError('ROUTE_SPACE_MISMATCH', `routeClaims[${index}].pathTemplate`, 'Route parameters must be unique within a path.');
568
+ throw new DeclarativeControlCompilationError("ROUTE_SPACE_MISMATCH", `routeClaims[${index}].pathTemplate`, "Route parameters must be unique within a path.");
520
569
  }
521
570
  const unknownParameter = pathParameters.find((parameter) => !knownParameters.has(parameter));
522
571
  if (unknownParameter) {
523
- throw new DeclarativeControlCompilationError('ROUTE_SPACE_MISMATCH', `routeClaims[${index}].pathTemplate`, `Route parameter ${unknownParameter} is not declared by ${routeSpace.routeSpaceId}.`);
572
+ throw new DeclarativeControlCompilationError("ROUTE_SPACE_MISMATCH", `routeClaims[${index}].pathTemplate`, `Route parameter ${unknownParameter} is not declared by ${routeSpace.routeSpaceId}.`);
524
573
  }
525
574
  const matcher = {
526
575
  surface: claim.surface,
@@ -536,7 +585,7 @@ const compileRouteClaims = (input) => {
536
585
  const reserved = routeSpace.reservedPaths.some((candidate) => {
537
586
  const normalizedReserved = normalizePath(candidate, routeSpace);
538
587
  const reservedClaim = declarative_control_1.CompiledRouteClaimSchema.parse({
539
- kind: 'canonical',
588
+ kind: "canonical",
540
589
  routeSpaceRevisionRef: claim.routeSpaceRevisionRef,
541
590
  pathTemplate: candidate,
542
591
  surface: claim.surface,
@@ -544,24 +593,23 @@ const compileRouteClaims = (input) => {
544
593
  matcher,
545
594
  });
546
595
  return ((0, exports.compiledRouteClaimsOverlap)(compiledClaim, reservedClaim) ||
547
- normalizedPath.startsWith(`${normalizedReserved.replace(/\/+$/, '')}/`));
596
+ normalizedPath.startsWith(`${normalizedReserved.replace(/\/+$/, "")}/`));
548
597
  });
549
598
  if (reserved) {
550
- const takeover = takeoverAuthorizations.find((authorization) => compiledClaim.kind === 'canonical' &&
599
+ const takeover = takeoverAuthorizations.find((authorization) => compiledClaim.kind === "canonical" &&
551
600
  authorization.normalizedPath === compiledClaim.normalizedPath &&
552
601
  (0, exports.sameRevisionRef)(authorization.routeSpaceRevisionRef, compiledClaim.routeSpaceRevisionRef));
553
602
  if (!takeover) {
554
- throw new DeclarativeControlCompilationError('ROUTE_RESERVED', `routeClaims[${index}].pathTemplate`, `Route ${normalizedPath} is reserved by ${routeSpace.routeSpaceId}.`);
603
+ throw new DeclarativeControlCompilationError("ROUTE_RESERVED", `routeClaims[${index}].pathTemplate`, `Route ${normalizedPath} is reserved by ${routeSpace.routeSpaceId}.`);
555
604
  }
556
605
  }
557
- const conflict = compiled.find((candidate) => (0, exports.sameRevisionRef)(candidate.routeSpaceRevisionRef, claim.routeSpaceRevisionRef) &&
558
- (0, exports.compiledRouteClaimsOverlap)(candidate, compiledClaim));
606
+ const conflict = compiled.find((candidate) => (0, exports.sameRevisionRef)(candidate.routeSpaceRevisionRef, claim.routeSpaceRevisionRef) && (0, exports.compiledRouteClaimsOverlap)(candidate, compiledClaim));
559
607
  if (conflict)
560
- throw new DeclarativeControlCompilationError('ROUTE_CONFLICT', `routeClaims[${index}].pathTemplate`, `Route ${normalizedPath} overlaps another active claim pattern.`);
608
+ throw new DeclarativeControlCompilationError("ROUTE_CONFLICT", `routeClaims[${index}].pathTemplate`, `Route ${normalizedPath} overlaps another active claim pattern.`);
561
609
  compiled.push(compiledClaim);
562
610
  });
563
- if (!compiled.some((claim) => claim.kind === 'canonical')) {
564
- throw new DeclarativeControlCompilationError('ROUTE_CONFLICT', 'routeClaims', 'At least one canonical route claim is required.');
611
+ if (!compiled.some((claim) => claim.kind === "canonical")) {
612
+ throw new DeclarativeControlCompilationError("ROUTE_CONFLICT", "routeClaims", "At least one canonical route claim is required.");
565
613
  }
566
614
  return Object.freeze(compiled);
567
615
  };
@@ -573,35 +621,38 @@ exports.compileRouteClaims = compileRouteClaims;
573
621
  */
574
622
  const matchCompiledRouteClaim = (claimInput, pathInput) => {
575
623
  const claim = declarative_control_1.CompiledRouteClaimSchema.parse(claimInput);
576
- const rawPath = String(pathInput || '').trim();
577
- if (!rawPath.startsWith('/') ||
578
- rawPath.includes('?') ||
579
- rawPath.includes('#') ||
580
- rawPath.includes('\\') ||
581
- rawPath.includes('://')) {
624
+ const rawPath = String(pathInput || "").trim();
625
+ if (!rawPath.startsWith("/") ||
626
+ rawPath.includes("?") ||
627
+ rawPath.includes("#") ||
628
+ rawPath.includes("\\") ||
629
+ rawPath.includes("://")) {
582
630
  return { matched: false, parameters: {} };
583
631
  }
584
- const rawSegments = rawPath.split('/');
585
- if (rawSegments.some((segment) => segment === '.' || segment === '..'))
632
+ const rawSegments = rawPath.split("/");
633
+ if (rawSegments.some((segment) => segment === "." || segment === ".."))
586
634
  return { matched: false, parameters: {} };
587
- const requestHasTrailingSlash = rawPath.length > 1 && rawPath.endsWith('/');
588
- if (claim.matcher.trailingSlash === 'require' && !requestHasTrailingSlash)
635
+ const requestHasTrailingSlash = rawPath.length > 1 && rawPath.endsWith("/");
636
+ if (claim.matcher.trailingSlash === "require" && !requestHasTrailingSlash)
589
637
  return { matched: false, parameters: {} };
590
- if (claim.matcher.trailingSlash === 'preserve' &&
591
- requestHasTrailingSlash !== (claim.normalizedPath.length > 1 && claim.normalizedPath.endsWith('/'))) {
638
+ if (claim.matcher.trailingSlash === "preserve" &&
639
+ requestHasTrailingSlash !==
640
+ (claim.normalizedPath.length > 1 && claim.normalizedPath.endsWith("/"))) {
592
641
  return { matched: false, parameters: {} };
593
642
  }
594
643
  const normalizeTrailing = (value) => {
595
- if (claim.matcher.trailingSlash === 'remove' && value.length > 1)
596
- return value.replace(/\/+$/, '');
597
- if (claim.matcher.trailingSlash === 'require' && value.length > 1 && !value.endsWith('/'))
644
+ if (claim.matcher.trailingSlash === "remove" && value.length > 1)
645
+ return value.replace(/\/+$/, "");
646
+ if (claim.matcher.trailingSlash === "require" &&
647
+ value.length > 1 &&
648
+ !value.endsWith("/"))
598
649
  return `${value}/`;
599
650
  return value;
600
651
  };
601
652
  const requestPath = normalizeTrailing(rawPath);
602
653
  const templatePath = normalizeTrailing(claim.normalizedPath);
603
- const requestSegments = requestPath.split('/').filter(Boolean);
604
- const templateSegments = templatePath.split('/').filter(Boolean);
654
+ const requestSegments = requestPath.split("/").filter(Boolean);
655
+ const templateSegments = templatePath.split("/").filter(Boolean);
605
656
  if (requestSegments.length !== templateSegments.length)
606
657
  return { matched: false, parameters: {} };
607
658
  const parameterDefinitions = new Map(claim.matcher.parameters.map((parameter) => [parameter.name, parameter]));
@@ -632,7 +683,7 @@ const matchCompiledRouteClaim = (claimInput, pathInput) => {
632
683
  parameters[definition.name] = value;
633
684
  normalizedSegments.push(rawValue);
634
685
  }
635
- const canonicalPath = normalizeTrailing(`/${normalizedSegments.join('/')}` || '/');
686
+ const canonicalPath = normalizeTrailing(`/${normalizedSegments.join("/")}` || "/");
636
687
  return {
637
688
  matched: true,
638
689
  normalizedPath: canonicalPath,
@@ -641,11 +692,11 @@ const matchCompiledRouteClaim = (claimInput, pathInput) => {
641
692
  };
642
693
  exports.matchCompiledRouteClaim = matchCompiledRouteClaim;
643
694
  function routeParameterPattern(type) {
644
- if (type === 'integer')
695
+ if (type === "integer")
645
696
  return /^-?\d+$/;
646
- if (type === 'uuid')
697
+ if (type === "uuid")
647
698
  return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
648
- if (type === 'slug')
699
+ if (type === "slug")
649
700
  return /^[A-Za-z0-9]+(?:[._-][A-Za-z0-9]+)*$/;
650
701
  return /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
651
702
  }
@@ -657,26 +708,31 @@ function routeParameterPattern(type) {
657
708
  const materializeRouteSpacePath = (input) => {
658
709
  const routeSpace = declarative_control_1.RouteSpaceSchema.parse(input.routeSpace);
659
710
  const applicationPath = declarative_control_1.RoutePathTemplateSchema.parse(input.applicationPath);
660
- const basePath = routeSpace.basePath === '/' ? '' : routeSpace.basePath.replace(/\/+$/, '');
661
- let browserTemplate = normalizePath(`${basePath}${applicationPath === '/' ? '/' : applicationPath}` || '/', routeSpace);
711
+ const basePath = routeSpace.basePath === "/" ? "" : routeSpace.basePath.replace(/\/+$/, "");
712
+ let browserTemplate = normalizePath(`${basePath}${applicationPath === "/" ? "/" : applicationPath}` || "/", routeSpace);
662
713
  const parameters = input.parameters || {};
663
714
  const declared = new Map(routeSpace.parameters.map((parameter) => [parameter.name, parameter]));
664
- const referenced = [...browserTemplate.matchAll(/:([A-Za-z][A-Za-z0-9_-]*)/g)].map((match) => match[1]);
715
+ const referenced = [
716
+ ...browserTemplate.matchAll(/:([A-Za-z][A-Za-z0-9_-]*)/g),
717
+ ].map((match) => match[1]);
665
718
  for (const name of referenced) {
666
719
  const definition = declared.get(name);
667
720
  const raw = parameters[name];
668
- if (!definition || raw === undefined || raw === null || String(raw).trim() === '') {
669
- throw new DeclarativeControlCompilationError('ROUTE_SPACE_MISMATCH', 'parameters', `Route parameter ${name} is not resolved by ${routeSpace.routeSpaceId}.`);
721
+ if (!definition ||
722
+ raw === undefined ||
723
+ raw === null ||
724
+ String(raw).trim() === "") {
725
+ throw new DeclarativeControlCompilationError("ROUTE_SPACE_MISMATCH", "parameters", `Route parameter ${name} is not resolved by ${routeSpace.routeSpaceId}.`);
670
726
  }
671
727
  const value = String(raw);
672
728
  if (!routeParameterPattern(definition.type).test(value)) {
673
- throw new DeclarativeControlCompilationError('ROUTE_SPACE_MISMATCH', `parameters.${name}`, `Route parameter ${name} does not satisfy ${definition.type}.`);
729
+ throw new DeclarativeControlCompilationError("ROUTE_SPACE_MISMATCH", `parameters.${name}`, `Route parameter ${name} does not satisfy ${definition.type}.`);
674
730
  }
675
731
  browserTemplate = browserTemplate.replace(`:${name}`, encodeURIComponent(value));
676
732
  }
677
733
  const unknown = Object.keys(parameters).find((name) => !declared.has(name));
678
734
  if (unknown)
679
- throw new DeclarativeControlCompilationError('ROUTE_SPACE_MISMATCH', `parameters.${unknown}`, `RouteSpace ${routeSpace.routeSpaceId} does not declare ${unknown}.`);
735
+ throw new DeclarativeControlCompilationError("ROUTE_SPACE_MISMATCH", `parameters.${unknown}`, `RouteSpace ${routeSpace.routeSpaceId} does not declare ${unknown}.`);
680
736
  return browserTemplate;
681
737
  };
682
738
  exports.materializeRouteSpacePath = materializeRouteSpacePath;
@@ -689,7 +745,7 @@ const renderTreeDepth = (tree) => {
689
745
  const ancestors = new Set([node.nodeId]);
690
746
  while (parentId) {
691
747
  if (ancestors.has(parentId)) {
692
- throw new DeclarativeControlCompilationError('RENDER_TREE_INVALID', 'page.renderTree.nodes', `RenderTree contains a parent cycle at ${parentId}.`);
748
+ throw new DeclarativeControlCompilationError("RENDER_TREE_INVALID", "page.renderTree.nodes", `RenderTree contains a parent cycle at ${parentId}.`);
693
749
  }
694
750
  ancestors.add(parentId);
695
751
  depth += 1;
@@ -705,48 +761,51 @@ const compareLegacyEntityRef = (reference, revision) => reference.kind === revis
705
761
  reference.ownerRepo === revision.ownerRepo;
706
762
  const pageDependencies = (page, compilerRevisionRef) => [
707
763
  ...page.routeClaims.map((claim) => ({
708
- role: 'route-space',
764
+ role: "route-space",
709
765
  revisionRef: claim.routeSpaceRevisionRef,
710
766
  })),
711
- { role: 'shell', revisionRef: page.shellRevisionRef },
767
+ { role: "shell", revisionRef: page.shellRevisionRef },
712
768
  ...page.capabilityInstances.flatMap((instance) => [
713
769
  {
714
- role: 'capability',
770
+ role: "capability",
715
771
  revisionRef: instance.capabilityRevisionRef,
716
772
  },
717
- { role: 'provider', revisionRef: instance.providerRevisionRef },
718
- ...(instance.eventEffects ?? []).map((effect) => ({ role: 'schema', revisionRef: effect.sourceIntentSchemaRevisionRef })),
773
+ { role: "provider", revisionRef: instance.providerRevisionRef },
774
+ ...(instance.eventEffects ?? []).map((effect) => ({
775
+ role: "schema",
776
+ revisionRef: effect.sourceIntentSchemaRevisionRef,
777
+ })),
719
778
  {
720
- role: 'schema',
779
+ role: "schema",
721
780
  revisionRef: instance.propertySchemaRevisionRef,
722
781
  },
723
782
  ]),
724
783
  ...(page.stateDefinitions ?? []).map((state) => ({
725
- role: 'schema',
784
+ role: "schema",
726
785
  revisionRef: state.schemaRevisionRef,
727
786
  })),
728
787
  ...(page.interactionBindings ?? []).map((binding) => ({
729
- role: 'schema',
788
+ role: "schema",
730
789
  revisionRef: binding.sourceIntentSchemaRevisionRef,
731
790
  })),
732
791
  ...page.ontologyBindings.flatMap((binding) => [
733
792
  {
734
- role: 'ontology-definition',
793
+ role: "ontology-definition",
735
794
  revisionRef: binding.ontologyDefinitionRevisionRef,
736
795
  },
737
- { role: 'view', revisionRef: binding.viewRevisionRef },
796
+ { role: "view", revisionRef: binding.viewRevisionRef },
738
797
  {
739
- role: 'view',
798
+ role: "view",
740
799
  revisionRef: binding.canonicalDataViewRevisionRef,
741
800
  },
742
801
  {
743
- role: 'schema',
802
+ role: "schema",
744
803
  revisionRef: binding.renderModelSchemaRevisionRef,
745
804
  },
746
805
  ...(binding.cursorWindow
747
806
  ? [
748
807
  {
749
- role: 'schema',
808
+ role: "schema",
750
809
  revisionRef: binding.cursorWindow.pageChangeIntentSchemaRevisionRef,
751
810
  },
752
811
  ]
@@ -754,75 +813,449 @@ const pageDependencies = (page, compilerRevisionRef) => [
754
813
  ]),
755
814
  ...(page.queryBindings ?? []).flatMap((binding) => [
756
815
  {
757
- role: 'query-definition',
816
+ role: "query-definition",
758
817
  revisionRef: binding.queryDefinitionRevisionRef,
759
818
  },
760
819
  {
761
- role: 'schema',
820
+ role: "schema",
762
821
  revisionRef: binding.renderModelSchemaRevisionRef,
763
822
  },
764
- ...(binding.targetProjection ? [{ role: 'schema', revisionRef: binding.targetProjection.schemaRevisionRef }] : []),
765
- ...(binding.streamTargetProjection ? [{ role: 'schema', revisionRef: binding.streamTargetProjection.schemaRevisionRef }] : []),
823
+ ...(binding.targetProjection
824
+ ? [
825
+ {
826
+ role: "schema",
827
+ revisionRef: binding.targetProjection.schemaRevisionRef,
828
+ },
829
+ ]
830
+ : []),
831
+ ...(binding.streamTargetProjection
832
+ ? [
833
+ {
834
+ role: "schema",
835
+ revisionRef: binding.streamTargetProjection.schemaRevisionRef,
836
+ },
837
+ ]
838
+ : []),
766
839
  ...(binding.cursorWindow
767
840
  ? [
768
841
  {
769
- role: 'schema',
842
+ role: "schema",
770
843
  revisionRef: binding.cursorWindow.pageChangeIntentSchemaRevisionRef,
771
844
  },
772
845
  ]
773
846
  : []),
774
847
  ]),
775
848
  ...page.actionBindings.flatMap((binding) => [
776
- { role: 'action', revisionRef: binding.commandRevisionRef },
849
+ { role: "action", revisionRef: binding.commandRevisionRef },
777
850
  {
778
- role: 'schema',
851
+ role: "schema",
779
852
  revisionRef: binding.sourceIntentSchemaRevisionRef,
780
853
  },
781
- { role: 'schema', revisionRef: binding.inputSchemaRevisionRef },
782
- { role: 'schema', revisionRef: binding.resultSchemaRevisionRef },
854
+ { role: "schema", revisionRef: binding.inputSchemaRevisionRef },
855
+ { role: "schema", revisionRef: binding.resultSchemaRevisionRef },
783
856
  ...(binding.compensationCommandRevisionRef
784
857
  ? [
785
858
  {
786
- role: 'action',
859
+ role: "action",
787
860
  revisionRef: binding.compensationCommandRevisionRef,
788
861
  },
789
862
  ]
790
863
  : []),
791
864
  ]),
792
865
  ...page.tokenRevisionRefs.map((revisionRef) => ({
793
- role: 'token',
866
+ role: "token",
794
867
  revisionRef,
795
868
  })),
796
- { role: 'performance-budget', revisionRef: page.performanceBudgetRef },
869
+ { role: "performance-budget", revisionRef: page.performanceBudgetRef },
797
870
  {
798
- role: 'observation-policy',
871
+ role: "observation-policy",
799
872
  revisionRef: page.observationPolicyRevisionRef,
800
873
  },
801
- { role: 'compiler', revisionRef: compilerRevisionRef },
874
+ { role: "compiler", revisionRef: compilerRevisionRef },
802
875
  ];
803
876
  const domainQueryDependencies = (definition) => [
804
877
  ...(definition.ontologyDefinitionRevisionRef
805
878
  ? [
806
879
  {
807
- role: 'ontology-definition',
880
+ role: "ontology-definition",
808
881
  revisionRef: definition.ontologyDefinitionRevisionRef,
809
882
  },
810
883
  ]
811
884
  : []),
812
- ...(definition.viewRevisionRef ? [{ role: 'view', revisionRef: definition.viewRevisionRef }] : []),
885
+ ...(definition.viewRevisionRef
886
+ ? [{ role: "view", revisionRef: definition.viewRevisionRef }]
887
+ : []),
813
888
  ...(definition.canonicalDataViewRevisionRef
814
889
  ? [
815
890
  {
816
- role: 'view',
891
+ role: "view",
817
892
  revisionRef: definition.canonicalDataViewRevisionRef,
818
893
  },
819
894
  ]
820
895
  : []),
821
- { role: 'schema', revisionRef: definition.inputSchemaRevisionRef },
822
- { role: 'schema', revisionRef: definition.resultSchemaRevisionRef },
896
+ { role: "schema", revisionRef: definition.inputSchemaRevisionRef },
897
+ { role: "schema", revisionRef: definition.resultSchemaRevisionRef },
823
898
  ];
899
+ const singleByStableIdentity = (registrations, kind, id, path) => {
900
+ const matches = registrations.filter(({ revisionRef }) => revisionRef.kind === kind && revisionRef.id === id);
901
+ if (matches.length !== 1) {
902
+ throw new DeclarativeControlCompilationError("DEPENDENCY_MISSING", path, `Expected exactly one active ${kind} registration for ${id}; found ${matches.length}.`);
903
+ }
904
+ return matches[0];
905
+ };
906
+ const usesResultValue = (mapping) => Object.values(mapping).some((source) => source.kind === "result-field" ||
907
+ (source.kind === "expression" &&
908
+ source.expression !== undefined &&
909
+ (0, page_expression_1.collectPageExpressionReads)(source.expression).some((read) => read.root === "result")));
910
+ const simpleEntityRef = (revisionRef) => ({
911
+ kind: revisionRef.kind,
912
+ id: revisionRef.id,
913
+ version: revisionRef.revision,
914
+ ownerRepo: revisionRef.ownerRepo,
915
+ });
916
+ const defaultRenderSurface = {
917
+ frameOwner: "host",
918
+ density: "default",
919
+ };
920
+ const defaultRenderScroll = {
921
+ owner: "surface",
922
+ axis: "none",
923
+ virtualizationBoundary: false,
924
+ };
925
+ const defaultRenderLifecycle = {
926
+ mountPolicy: "always",
927
+ queryPolicy: "always",
928
+ retainOnDeactivate: false,
929
+ deepLink: false,
930
+ focusReturn: false,
931
+ };
932
+ const resolvePage = (input) => {
933
+ const page = declarative_control_1.PageSchema.parse(input.page);
934
+ const defaults = {
935
+ routeSpace: declarative_control_1.RevisionRefSchema.parse(input.defaults.routeSpace),
936
+ shell: declarative_control_1.RevisionRefSchema.parse(input.defaults.shell),
937
+ tokens: input.defaults.tokens.map((reference) => declarative_control_1.RevisionRefSchema.parse(reference)),
938
+ performanceBudget: declarative_control_1.RevisionRefSchema.parse(input.defaults.performanceBudget),
939
+ observationPolicy: declarative_control_1.RevisionRefSchema.parse(input.defaults.observationPolicy),
940
+ };
941
+ const resourceRegistrations = (input.productResources ?? []).map((registration) => ({
942
+ revisionRef: declarative_control_1.RevisionRefSchema.parse(registration.resourceRevisionRef),
943
+ registration: declarative_control_http_1.DeclarativeProductResourceRegistrationSchema.parse(registration),
944
+ }));
945
+ const resolveResource = (kind, id, fallback, path) => {
946
+ const targetId = id ?? fallback.id;
947
+ if (resourceRegistrations.length === 0) {
948
+ if (targetId !== fallback.id || fallback.kind !== kind) {
949
+ throw new DeclarativeControlCompilationError("DEPENDENCY_MISSING", path, `No ${kind} registry was supplied for ${targetId}.`);
950
+ }
951
+ return fallback;
952
+ }
953
+ return singleByStableIdentity(resourceRegistrations, kind, targetId, path)
954
+ .revisionRef;
955
+ };
956
+ const routeSpaceId = page.routeSpace ?? defaults.routeSpace.id;
957
+ const routeRegistrations = (input.routeSpaces ?? []).map((registration) => ({
958
+ revisionRef: declarative_control_1.RevisionRefSchema.parse(registration.revisionRef),
959
+ routeSpace: registration.routeSpace,
960
+ }));
961
+ const routeSpaceRevisionRef = routeRegistrations.length === 0
962
+ ? (() => {
963
+ if (routeSpaceId !== defaults.routeSpace.id) {
964
+ throw new DeclarativeControlCompilationError("ROUTE_SPACE_MISSING", "page.routeSpace", `No RouteSpace registry was supplied for ${routeSpaceId}.`);
965
+ }
966
+ return defaults.routeSpace;
967
+ })()
968
+ : singleByStableIdentity(routeRegistrations, "route-space", routeSpaceId, "page.routeSpace").revisionRef;
969
+ const shellRevisionRef = resolveResource("shell", page.shell, defaults.shell, "page.shell");
970
+ const tokenRevisionRefs = page.tokens?.map((id, index) => resolveResource("design-token", id, defaults.tokens[0], `page.tokens[${index}]`)) ?? [...defaults.tokens];
971
+ const performanceBudgetRef = resolveResource("performance-budget", page.performanceBudget, defaults.performanceBudget, "page.performanceBudget");
972
+ const observationPolicyRevisionRef = resolveResource("observation-policy", page.observationPolicy, defaults.observationPolicy, "page.observationPolicy");
973
+ const capabilityRegistrations = input.capabilityRegistry.map((registration) => ({
974
+ ...registration,
975
+ revisionRef: declarative_control_1.RevisionRefSchema.parse(registration.capabilityRevisionRef),
976
+ providerRevisionRef: declarative_control_1.RevisionRefSchema.parse(registration.providerRevisionRef),
977
+ propertySchemaRevisionRef: declarative_control_1.RevisionRefSchema.parse(registration.propertySchemaRevisionRef),
978
+ inputPorts: registration.inputPorts.map((port) => ({
979
+ ...port,
980
+ schemaRevisionRef: declarative_control_1.RevisionRefSchema.parse(port.schemaRevisionRef),
981
+ })),
982
+ outputPorts: registration.outputPorts.map((port) => ({
983
+ ...port,
984
+ schemaRevisionRef: declarative_control_1.RevisionRefSchema.parse(port.schemaRevisionRef),
985
+ })),
986
+ }));
987
+ const queryRegistrations = (input.domainQueryRegistry ?? []).map((registration) => ({
988
+ revisionRef: declarative_control_1.RevisionRefSchema.parse(registration.definitionRevisionRef),
989
+ definition: declarative_control_1.DomainQueryDefinitionSchema.parse(registration.definition),
990
+ }));
991
+ const commandRegistrations = (input.domainCommandRegistry ?? []).map((registration) => ({
992
+ revisionRef: declarative_control_1.RevisionRefSchema.parse(registration.definitionRevisionRef),
993
+ definition: registration.definition,
994
+ }));
995
+ const schemaRegistrations = (input.schemaRegistry ?? []).map((registration) => ({
996
+ revisionRef: declarative_control_1.RevisionRefSchema.parse(registration.definitionRevisionRef),
997
+ definition: registration.definition,
998
+ }));
999
+ const stateSchemaById = new Map(schemaRegistrations.map((registration) => [
1000
+ registration.definition.schemaId,
1001
+ registration.revisionRef,
1002
+ ]));
1003
+ const stateDefinitions = (page.state ?? []).map(({ schema, ...state }, index) => {
1004
+ const schemaRevisionRef = stateSchemaById.get(schema);
1005
+ if (!schemaRevisionRef) {
1006
+ throw new DeclarativeControlCompilationError("SCHEMA_DEFINITION_MISMATCH", `page.state[${index}].schema`, `No active Schema registration exists for ${schema}.`);
1007
+ }
1008
+ return { ...state, schemaRevisionRef };
1009
+ });
1010
+ const stateSchemasByStateId = new Map(stateDefinitions.map((definition) => [
1011
+ definition.stateId,
1012
+ definition.schemaRevisionRef,
1013
+ ]));
1014
+ const renderNodes = [];
1015
+ const capabilityInstances = [];
1016
+ const queryBindings = [];
1017
+ const actionBindings = [];
1018
+ const interactionBindings = [];
1019
+ const visitNode = (node, parentNodeId) => {
1020
+ const registration = singleByStableIdentity(capabilityRegistrations, "capability", node.component, `page.body.${node.id}.component`);
1021
+ const children = node.children ?? [];
1022
+ const defaultActivation = {
1023
+ activationId: node.id,
1024
+ mode: "inline",
1025
+ };
1026
+ renderNodes.push({
1027
+ contract: "RenderNode",
1028
+ nodeId: node.id,
1029
+ kind: node.kind ?? "view",
1030
+ version: 1,
1031
+ ownerRepo: registration.providerRevisionRef.ownerRepo,
1032
+ ...(parentNodeId ? { parentNodeId } : {}),
1033
+ children: children.map((child) => child.id),
1034
+ ...(node.slot ? { slot: node.slot } : {}),
1035
+ pageRef: {
1036
+ kind: "page",
1037
+ id: page.pageId,
1038
+ version: 1,
1039
+ ownerRepo: input.pageOwnerRepo,
1040
+ },
1041
+ capabilityRef: simpleEntityRef(registration.revisionRef),
1042
+ providerRef: simpleEntityRef(registration.providerRevisionRef),
1043
+ surface: node.surface ?? defaultRenderSurface,
1044
+ scroll: node.scroll ?? defaultRenderScroll,
1045
+ activation: node.activation ?? defaultActivation,
1046
+ lifecycle: node.lifecycle ?? defaultRenderLifecycle,
1047
+ layout: node.layout ?? { mode: "contents" },
1048
+ ...(node.style ? { style: node.style } : {}),
1049
+ responsive: node.responsive ?? [],
1050
+ state: node.state ?? "idle",
1051
+ renderModel: node.model ?? {},
1052
+ ...(node.repeat
1053
+ ? { repeat: { ...node.repeat, limit: node.repeat.limit ?? 200 } }
1054
+ : {}),
1055
+ });
1056
+ capabilityInstances.push({
1057
+ instanceId: node.id,
1058
+ nodeId: node.id,
1059
+ capabilityRevisionRef: registration.revisionRef,
1060
+ providerRevisionRef: registration.providerRevisionRef,
1061
+ propertySchemaRevisionRef: registration.propertySchemaRevisionRef,
1062
+ properties: node.props ?? {},
1063
+ ...(node.bindings ? { propertyBindings: node.bindings } : {}),
1064
+ ...(node.eventPayloads
1065
+ ? { eventPayloadBindings: node.eventPayloads }
1066
+ : {}),
1067
+ ...(node.effects
1068
+ ? {
1069
+ eventEffects: node.effects.map((effect, index) => {
1070
+ const port = registration.outputPorts.find((candidate) => candidate.name === effect.port);
1071
+ if (!port) {
1072
+ throw new DeclarativeControlCompilationError("PORT_TYPE_MISMATCH", `page.body.${node.id}.effects[${index}].port`, `No output port ${effect.port} exists on ${node.component}.`);
1073
+ }
1074
+ return {
1075
+ sourcePort: effect.port,
1076
+ sourceIntentSchemaRevisionRef: port.schemaRevisionRef,
1077
+ refreshBindingIds: effect.refresh,
1078
+ };
1079
+ }),
1080
+ }
1081
+ : {}),
1082
+ ...(node.access ? { accessPolicy: node.access } : {}),
1083
+ ...(node.activeWhen ? { activationWhen: node.activeWhen } : {}),
1084
+ allowedSideEffects: [...registration.allowedSideEffects],
1085
+ });
1086
+ for (const [index, binding] of (node.data ?? []).entries()) {
1087
+ const queryRegistration = singleByStableIdentity(queryRegistrations, "domain-query-definition", binding.query, `page.body.${node.id}.data[${index}].query`);
1088
+ const port = registration.inputPorts.find((candidate) => candidate.name === binding.port);
1089
+ if (!port) {
1090
+ throw new DeclarativeControlCompilationError("PORT_TYPE_MISMATCH", `page.body.${node.id}.data[${index}].port`, `No input port ${binding.port} exists on ${node.component}.`);
1091
+ }
1092
+ const { query, port: _port, targetProjection, streamTargetProjection, cursorWindow, resultStateBindings, ...rest } = binding;
1093
+ queryBindings.push({
1094
+ ...rest,
1095
+ queryDefinitionRevisionRef: queryRegistration.revisionRef,
1096
+ target: { capabilityInstanceId: node.id, port: binding.port },
1097
+ renderModelSchemaRevisionRef: queryRegistration.definition.resultSchemaRevisionRef,
1098
+ ...(targetProjection
1099
+ ? {
1100
+ targetProjection: {
1101
+ ...targetProjection,
1102
+ schemaRevisionRef: port.schemaRevisionRef,
1103
+ },
1104
+ }
1105
+ : {}),
1106
+ ...(streamTargetProjection
1107
+ ? {
1108
+ streamTargetProjection: {
1109
+ ...streamTargetProjection,
1110
+ schemaRevisionRef: port.schemaRevisionRef,
1111
+ },
1112
+ }
1113
+ : {}),
1114
+ ...(cursorWindow
1115
+ ? {
1116
+ cursorWindow: {
1117
+ ...cursorWindow,
1118
+ pageChangeIntentSchemaRevisionRef: (() => {
1119
+ const sourceInstanceId = cursorWindow.sourceCapabilityInstanceId ?? node.id;
1120
+ const sourceRegistration = capabilityInstances.find((instance) => instance.instanceId === sourceInstanceId);
1121
+ const sourceCapability = sourceRegistration &&
1122
+ capabilityRegistrations.find((candidate) => (0, exports.sameRevisionRef)(candidate.revisionRef, sourceRegistration.capabilityRevisionRef));
1123
+ const sourcePort = sourceCapability?.outputPorts.find((candidate) => candidate.name === cursorWindow.pageChangePort);
1124
+ if (!sourcePort) {
1125
+ throw new DeclarativeControlCompilationError("PORT_TYPE_MISMATCH", `page.body.${node.id}.data[${index}].cursorWindow.pageChangePort`, `No output port ${cursorWindow.pageChangePort} exists on the cursor source component.`);
1126
+ }
1127
+ return sourcePort.schemaRevisionRef;
1128
+ })(),
1129
+ },
1130
+ }
1131
+ : {}),
1132
+ ...(resultStateBindings
1133
+ ? {
1134
+ resultStateBindings: resultStateBindings.map((stateBinding, stateIndex) => {
1135
+ const targetStateSchemaRevisionRef = stateSchemasByStateId.get(stateBinding.targetStateId);
1136
+ if (!targetStateSchemaRevisionRef) {
1137
+ throw new DeclarativeControlCompilationError("SCHEMA_DEFINITION_MISMATCH", `page.body.${node.id}.data[${index}].resultStateBindings[${stateIndex}].targetStateId`, `Unknown Page state ${stateBinding.targetStateId}.`);
1138
+ }
1139
+ return { ...stateBinding, targetStateSchemaRevisionRef };
1140
+ }),
1141
+ }
1142
+ : {}),
1143
+ });
1144
+ }
1145
+ for (const [index, binding] of (node.actions ?? []).entries()) {
1146
+ const commandRegistration = singleByStableIdentity(commandRegistrations, "domain-command", binding.command, `page.body.${node.id}.actions[${index}].command`);
1147
+ const port = registration.outputPorts.find((candidate) => candidate.name === binding.port);
1148
+ if (!port) {
1149
+ throw new DeclarativeControlCompilationError("PORT_TYPE_MISMATCH", `page.body.${node.id}.actions[${index}].port`, `No output port ${binding.port} exists on ${node.component}.`);
1150
+ }
1151
+ const inputSchemaRevisionRef = stateSchemaById.get(commandRegistration.definition.inputSchemaRef);
1152
+ const resultSchemaRevisionRef = commandRegistration.definition
1153
+ .outputSchemaRef
1154
+ ? stateSchemaById.get(commandRegistration.definition.outputSchemaRef)
1155
+ : undefined;
1156
+ if (!inputSchemaRevisionRef || !resultSchemaRevisionRef) {
1157
+ throw new DeclarativeControlCompilationError("COMMAND_DEFINITION_MISMATCH", `page.body.${node.id}.actions[${index}].command`, `Command ${binding.command} must resolve active input and output Schemas.`);
1158
+ }
1159
+ const compensationCommandRevisionRef = binding.compensationCommand
1160
+ ? singleByStableIdentity(commandRegistrations, "domain-command", binding.compensationCommand, `page.body.${node.id}.actions[${index}].compensationCommand`).revisionRef
1161
+ : undefined;
1162
+ const { command, port: _port, compensationCommand, ...rest } = binding;
1163
+ actionBindings.push({
1164
+ ...rest,
1165
+ commandRevisionRef: commandRegistration.revisionRef,
1166
+ source: { capabilityInstanceId: node.id, port: binding.port },
1167
+ sourceIntentSchemaRevisionRef: port.schemaRevisionRef,
1168
+ inputSchemaRevisionRef,
1169
+ ...(compensationCommandRevisionRef
1170
+ ? { compensationCommandRevisionRef }
1171
+ : {}),
1172
+ resultSchemaRevisionRef,
1173
+ });
1174
+ }
1175
+ for (const [index, binding] of (node.on ?? []).entries()) {
1176
+ const port = registration.outputPorts.find((candidate) => candidate.name === binding.port);
1177
+ if (!port) {
1178
+ throw new DeclarativeControlCompilationError("PORT_TYPE_MISMATCH", `page.body.${node.id}.on[${index}].port`, `No output port ${binding.port} exists on ${node.component}.`);
1179
+ }
1180
+ const matchingAction = actionBindings.find((action) => action.source.capabilityInstanceId === node.id &&
1181
+ action.source.port === binding.port);
1182
+ const { port: _port, ...rest } = binding;
1183
+ interactionBindings.push({
1184
+ ...rest,
1185
+ source: { capabilityInstanceId: node.id, port: binding.port },
1186
+ sourceIntentSchemaRevisionRef: port.schemaRevisionRef,
1187
+ ...(usesResultValue(binding.inputMapping)
1188
+ ? (() => {
1189
+ if (!matchingAction) {
1190
+ throw new DeclarativeControlCompilationError("COMMAND_DEFINITION_MISMATCH", `page.body.${node.id}.on[${index}].inputMapping`, "A result-driven interaction requires an Action on the same output port.");
1191
+ }
1192
+ return {
1193
+ sourceResultSchemaRevisionRef: matchingAction.resultSchemaRevisionRef,
1194
+ };
1195
+ })()
1196
+ : {}),
1197
+ });
1198
+ }
1199
+ children.forEach((child) => visitNode(child, node.id));
1200
+ };
1201
+ visitNode(page.body);
1202
+ const resolved = {
1203
+ contract: "Page",
1204
+ schemaVersion: 1,
1205
+ pageId: page.pageId,
1206
+ tenantScope: page.tenantScope,
1207
+ identity: page.identity,
1208
+ supportedSurfaces: [page.surface],
1209
+ lifecycle: page.lifecycle,
1210
+ ...(page.routeStatePresentations
1211
+ ? { routeStatePresentations: page.routeStatePresentations }
1212
+ : {}),
1213
+ routeClaims: [
1214
+ {
1215
+ kind: "canonical",
1216
+ surface: page.surface,
1217
+ routeSpaceRevisionRef,
1218
+ pathTemplate: page.route,
1219
+ },
1220
+ ],
1221
+ shellRevisionRef,
1222
+ renderTree: {
1223
+ contract: "RenderTree",
1224
+ treeId: page.pageId,
1225
+ product: page.surface,
1226
+ rootNodeId: page.body.id,
1227
+ nodes: renderNodes,
1228
+ },
1229
+ capabilityInstances,
1230
+ ...(stateDefinitions.length ? { stateDefinitions } : {}),
1231
+ ...(page.entryTransitions
1232
+ ? {
1233
+ entryTransitions: page.entryTransitions.map(({ target, ...transition }, index) => {
1234
+ const matches = (input.targetRegistry ?? []).filter((registration) => registration.stableTargetRef.kind === target.kind &&
1235
+ registration.stableTargetRef.id === target.id);
1236
+ if (matches.length !== 1) {
1237
+ throw new DeclarativeControlCompilationError("PAGE_ENTRY_TARGET_UNRELEASED", `page.entryTransitions[${index}].target`, `Expected one active ${target.kind} target for ${target.id}; found ${matches.length}.`);
1238
+ }
1239
+ return { ...transition, targetRef: matches[0].stableTargetRef };
1240
+ }),
1241
+ }
1242
+ : {}),
1243
+ ...(interactionBindings.length ? { interactionBindings } : {}),
1244
+ ontologyBindings: [],
1245
+ ...(queryBindings.length ? { queryBindings } : {}),
1246
+ actionBindings,
1247
+ pageAccessPolicy: page.access,
1248
+ managementAccess: page.managementAccess,
1249
+ tokenRevisionRefs,
1250
+ performanceBudgetRef,
1251
+ observationPolicyRevisionRef,
1252
+ privacyClassification: page.privacyClassification,
1253
+ };
1254
+ return declarative_control_1.ResolvedPageSchema.parse(resolved);
1255
+ };
1256
+ exports.resolvePage = resolvePage;
824
1257
  const compilePageRuntimeBundle = (input) => {
825
- const parsedPage = declarative_control_1.PageSchema.parse(input.page);
1258
+ const parsedPage = declarative_control_1.ResolvedPageSchema.parse(input.page);
826
1259
  const page = {
827
1260
  ...parsedPage,
828
1261
  routeStatePresentations: parsedPage.routeStatePresentations ?? [],
@@ -836,12 +1269,12 @@ const compilePageRuntimeBundle = (input) => {
836
1269
  const releaseRevisionRef = declarative_control_1.RevisionRefSchema.parse(input.releaseRevisionRef);
837
1270
  const compilerRevisionRef = declarative_control_1.RevisionRefSchema.parse(input.compilerRevisionRef);
838
1271
  const scope = declarative_control_1.TenantScopeSchema.parse(page.tenantScope);
839
- assertSameTenantScope(release.tenantScope, scope, 'release.tenantScope');
840
- assertRevisionIdentity(pageRevisionRef, 'page', page.pageId, scope, 'pageRevisionRef');
841
- assertRevisionIdentity(release.pageRevisionRef, 'page', page.pageId, scope, 'release.pageRevisionRef');
1272
+ assertSameTenantScope(release.tenantScope, scope, "release.tenantScope");
1273
+ assertRevisionIdentity(pageRevisionRef, "page", page.pageId, scope, "pageRevisionRef");
1274
+ assertRevisionIdentity(release.pageRevisionRef, "page", page.pageId, scope, "release.pageRevisionRef");
842
1275
  if (!(0, exports.sameRevisionRef)(pageRevisionRef, release.pageRevisionRef))
843
- throw new DeclarativeControlCompilationError('REVISION_MISMATCH', 'release.pageRevisionRef', 'Release does not pin the supplied Page revision.');
844
- assertRevisionIdentity(releaseRevisionRef, 'page-release', release.releaseSlotId, scope, 'releaseRevisionRef');
1276
+ throw new DeclarativeControlCompilationError("REVISION_MISMATCH", "release.pageRevisionRef", "Release does not pin the supplied Page revision.");
1277
+ assertRevisionIdentity(releaseRevisionRef, "page-release", release.releaseSlotId, scope, "releaseRevisionRef");
845
1278
  requireReleaseReady(release);
846
1279
  requireDependencies(release.dependencySnapshot, pageDependencies(page, compilerRevisionRef));
847
1280
  assertDependencyScopes(release.dependencySnapshot, scope);
@@ -849,13 +1282,13 @@ const compilePageRuntimeBundle = (input) => {
849
1282
  const definitionRevisionRef = declarative_control_1.RevisionRefSchema.parse(registration.definitionRevisionRef);
850
1283
  const definition = declarative_control_1.DomainQueryDefinitionSchema.parse(registration.definition);
851
1284
  assertSameTenantScope(definition.tenantScope, scope, `domainQueryRegistry[${index}].definition.tenantScope`);
852
- assertRevisionIdentity(definitionRevisionRef, 'domain-query-definition', definition.queryId, scope, `domainQueryRegistry[${index}].definitionRevisionRef`);
1285
+ assertRevisionIdentity(definitionRevisionRef, "domain-query-definition", definition.queryId, scope, `domainQueryRegistry[${index}].definitionRevisionRef`);
853
1286
  if (definitionRevisionRef.contentHash !== (0, exports.canonicalContentHash)(definition)) {
854
- throw new DeclarativeControlCompilationError('QUERY_DEFINITION_MISMATCH', `domainQueryRegistry[${index}].definitionRevisionRef.contentHash`, 'Domain Query registry entry does not match its exact definition content hash.');
1287
+ throw new DeclarativeControlCompilationError("QUERY_DEFINITION_MISMATCH", `domainQueryRegistry[${index}].definitionRevisionRef.contentHash`, "Domain Query registry entry does not match its exact definition content hash.");
855
1288
  }
856
1289
  return { definitionRevisionRef, definition };
857
1290
  });
858
- assertUniqueRegistryKeys(queryRegistrations.map((registration) => (0, exports.revisionRefKey)(registration.definitionRevisionRef)), 'domainQueryRegistry');
1291
+ assertUniqueRegistryKeys(queryRegistrations.map((registration) => (0, exports.revisionRefKey)(registration.definitionRevisionRef)), "domainQueryRegistry");
859
1292
  const queryDefinitionsByRevision = new Map(queryRegistrations.map((registration) => [
860
1293
  (0, exports.revisionRefKey)(registration.definitionRevisionRef),
861
1294
  registration.definition,
@@ -863,47 +1296,49 @@ const compilePageRuntimeBundle = (input) => {
863
1296
  page.queryBindings.forEach((binding, index) => {
864
1297
  const definition = queryDefinitionsByRevision.get((0, exports.revisionRefKey)(binding.queryDefinitionRevisionRef));
865
1298
  if (!definition) {
866
- throw new DeclarativeControlCompilationError('QUERY_DEFINITION_MISMATCH', `queryBindings[${index}].queryDefinitionRevisionRef`, 'Query binding does not resolve to one exact governed Domain Query definition.');
1299
+ throw new DeclarativeControlCompilationError("QUERY_DEFINITION_MISMATCH", `queryBindings[${index}].queryDefinitionRevisionRef`, "Query binding does not resolve to one exact governed Domain Query definition.");
867
1300
  }
868
1301
  if (!(0, exports.sameRevisionRef)(definition.resultSchemaRevisionRef, binding.renderModelSchemaRevisionRef)) {
869
- throw new DeclarativeControlCompilationError('QUERY_DEFINITION_MISMATCH', `queryBindings[${index}].renderModelSchemaRevisionRef`, 'Query binding render model does not match the exact Domain Query result schema.');
1302
+ throw new DeclarativeControlCompilationError("QUERY_DEFINITION_MISMATCH", `queryBindings[${index}].renderModelSchemaRevisionRef`, "Query binding render model does not match the exact Domain Query result schema.");
870
1303
  }
871
1304
  if (!(0, exports.accessPolicyChainImplies)([page.pageAccessPolicy], definition.accessPolicy) &&
872
- binding.accessFailure !== 'render-forbidden') {
873
- throw new DeclarativeControlCompilationError('AUDIENCE_WIDER_THAN_TARGET', `queryBindings[${index}]`, 'Page access is wider than the governed Domain Query audience.');
1305
+ binding.accessFailure !== "render-forbidden") {
1306
+ throw new DeclarativeControlCompilationError("AUDIENCE_WIDER_THAN_TARGET", `queryBindings[${index}]`, "Page access is wider than the governed Domain Query audience.");
874
1307
  }
875
- const sourceKind = definition.dataSource?.kind ?? 'exact-view';
876
- if (binding.execution === 'local-state' && sourceKind !== 'page-state') {
877
- throw new DeclarativeControlCompilationError('QUERY_DEFINITION_MISMATCH', `queryBindings[${index}].execution`, 'A local-state binding must resolve to one page-state Domain Query definition.');
1308
+ const sourceKind = definition.dataSource?.kind ?? "exact-view";
1309
+ if (binding.execution === "local-state" && sourceKind !== "page-state") {
1310
+ throw new DeclarativeControlCompilationError("QUERY_DEFINITION_MISMATCH", `queryBindings[${index}].execution`, "A local-state binding must resolve to one page-state Domain Query definition.");
878
1311
  }
879
- if (binding.execution === 'server' && sourceKind === 'page-state') {
880
- throw new DeclarativeControlCompilationError('QUERY_DEFINITION_MISMATCH', `queryBindings[${index}].execution`, 'A page-state Domain Query cannot execute on the Server.');
1312
+ if (binding.execution === "server" && sourceKind === "page-state") {
1313
+ throw new DeclarativeControlCompilationError("QUERY_DEFINITION_MISMATCH", `queryBindings[${index}].execution`, "A page-state Domain Query cannot execute on the Server.");
881
1314
  }
882
1315
  requireDependencies(release.dependencySnapshot, domainQueryDependencies(definition));
883
1316
  });
884
1317
  const shellRegistration = declarative_control_http_1.DeclarativeProductResourceRegistrationSchema.parse(input.shellRegistration);
885
- if (shellRegistration.resourceKind !== 'shell' ||
1318
+ if (shellRegistration.resourceKind !== "shell" ||
886
1319
  !(0, exports.sameRevisionRef)(shellRegistration.resourceRevisionRef, page.shellRevisionRef) ||
887
- (0, exports.declarativeProductResourceRevisionHash)(shellRegistration) !== shellRegistration.resourceRevisionRef.contentHash ||
888
- (0, exports.declarativeProductResourceSourceHash)(shellRegistration.document) !== shellRegistration.sourceContentHash) {
889
- throw new DeclarativeControlCompilationError('SHELL_REVISION_MISMATCH', 'shellRegistration', 'The active Shell registration does not match the Page exact Shell revision.');
1320
+ (0, exports.declarativeProductResourceRevisionHash)(shellRegistration) !==
1321
+ shellRegistration.resourceRevisionRef.contentHash ||
1322
+ (0, exports.declarativeProductResourceSourceHash)(shellRegistration.document) !==
1323
+ shellRegistration.sourceContentHash) {
1324
+ throw new DeclarativeControlCompilationError("SHELL_REVISION_MISMATCH", "shellRegistration", "The active Shell registration does not match the Page exact Shell revision.");
890
1325
  }
891
1326
  if (!shellRegistration.supportedSurfaces.includes(release.target.surface)) {
892
- throw new DeclarativeControlCompilationError('SHELL_SURFACE_MISMATCH', 'shellRegistration.supportedSurfaces', 'The active Shell registration does not support the release surface.');
1327
+ throw new DeclarativeControlCompilationError("SHELL_SURFACE_MISMATCH", "shellRegistration.supportedSurfaces", "The active Shell registration does not support the release surface.");
893
1328
  }
894
1329
  const shellDocument = declarative_control_http_1.DeclarativeShellResourceDocumentSchema.parse(shellRegistration.document);
895
1330
  const shellChrome = shellDocument.surfaceChrome.find((entry) => entry.surface === release.target.surface);
896
1331
  if (!shellChrome) {
897
- throw new DeclarativeControlCompilationError('SHELL_CHROME_UNAVAILABLE', 'shellRegistration.document.surfaceChrome', 'The active Shell does not declare chrome for the release surface.');
1332
+ throw new DeclarativeControlCompilationError("SHELL_CHROME_UNAVAILABLE", "shellRegistration.document.surfaceChrome", "The active Shell does not declare chrome for the release surface.");
898
1333
  }
899
1334
  const shellDescriptor = {
900
1335
  shellRevisionRef: page.shellRevisionRef,
901
1336
  header: shellChrome.header,
902
1337
  };
903
1338
  if (page.renderTree.nodes.length > input.limits.maxRenderNodes)
904
- throw new DeclarativeControlCompilationError('RENDER_NODE_LIMIT_EXCEEDED', 'page.renderTree.nodes', 'RenderTree exceeds the caller-approved node limit.');
1339
+ throw new DeclarativeControlCompilationError("RENDER_NODE_LIMIT_EXCEEDED", "page.renderTree.nodes", "RenderTree exceeds the caller-approved node limit.");
905
1340
  if (renderTreeDepth(page.renderTree) > input.limits.maxRenderDepth)
906
- throw new DeclarativeControlCompilationError('RENDER_DEPTH_EXCEEDED', 'page.renderTree.nodes', 'RenderTree exceeds the caller-approved depth limit.');
1341
+ throw new DeclarativeControlCompilationError("RENDER_DEPTH_EXCEEDED", "page.renderTree.nodes", "RenderTree exceeds the caller-approved depth limit.");
907
1342
  const renderTree = (0, render_tree_compiler_1.compileRenderTree)(page.renderTree).tree;
908
1343
  const instancesByNode = new Map(page.capabilityInstances.map((instance) => [instance.nodeId, instance]));
909
1344
  const registrations = input.capabilityRegistry.map((registration, registrationIndex) => ({
@@ -912,20 +1347,20 @@ const compilePageRuntimeBundle = (input) => {
912
1347
  providerRevisionRef: declarative_control_1.RevisionRefSchema.parse(registration.providerRevisionRef),
913
1348
  inputPorts: registration.inputPorts.map((port, portIndex) => {
914
1349
  const schemaRevisionRef = declarative_control_1.RevisionRefSchema.parse(port.schemaRevisionRef);
915
- if (schemaRevisionRef.kind !== 'schema') {
916
- throw new DeclarativeControlCompilationError('PORT_TYPE_MISMATCH', `capabilityRegistry[${registrationIndex}].inputPorts[${portIndex}].schemaRevisionRef`, 'Capability ports must pin schema revisions.');
1350
+ if (schemaRevisionRef.kind !== "schema") {
1351
+ throw new DeclarativeControlCompilationError("PORT_TYPE_MISMATCH", `capabilityRegistry[${registrationIndex}].inputPorts[${portIndex}].schemaRevisionRef`, "Capability ports must pin schema revisions.");
917
1352
  }
918
1353
  return { ...port, schemaRevisionRef };
919
1354
  }),
920
1355
  outputPorts: registration.outputPorts.map((port, portIndex) => {
921
1356
  const schemaRevisionRef = declarative_control_1.RevisionRefSchema.parse(port.schemaRevisionRef);
922
- if (schemaRevisionRef.kind !== 'schema') {
923
- throw new DeclarativeControlCompilationError('PORT_TYPE_MISMATCH', `capabilityRegistry[${registrationIndex}].outputPorts[${portIndex}].schemaRevisionRef`, 'Capability ports must pin schema revisions.');
1357
+ if (schemaRevisionRef.kind !== "schema") {
1358
+ throw new DeclarativeControlCompilationError("PORT_TYPE_MISMATCH", `capabilityRegistry[${registrationIndex}].outputPorts[${portIndex}].schemaRevisionRef`, "Capability ports must pin schema revisions.");
924
1359
  }
925
1360
  return { ...port, schemaRevisionRef };
926
1361
  }),
927
1362
  }));
928
- assertUniqueRegistryKeys(registrations.map((registration) => `${(0, exports.revisionRefKey)(registration.capabilityRevisionRef)}:${(0, exports.revisionRefKey)(registration.providerRevisionRef)}`), 'capabilityRegistry');
1363
+ assertUniqueRegistryKeys(registrations.map((registration) => `${(0, exports.revisionRefKey)(registration.capabilityRevisionRef)}:${(0, exports.revisionRefKey)(registration.providerRevisionRef)}`), "capabilityRegistry");
929
1364
  const registrationsByPair = new Map(registrations.map((registration) => [
930
1365
  `${(0, exports.revisionRefKey)(registration.capabilityRevisionRef)}:${(0, exports.revisionRefKey)(registration.providerRevisionRef)}`,
931
1366
  registration,
@@ -937,30 +1372,33 @@ const compilePageRuntimeBundle = (input) => {
937
1372
  !node.providerRef ||
938
1373
  !compareLegacyEntityRef(node.providerRef, instance.providerRevisionRef) ||
939
1374
  node.pageRef.id !== page.pageId) {
940
- throw new DeclarativeControlCompilationError('CAPABILITY_BINDING_MISMATCH', `capabilityInstances[${index}]`, 'RenderTree node identity does not match the declared capability/provider instance.');
1375
+ throw new DeclarativeControlCompilationError("CAPABILITY_BINDING_MISMATCH", `capabilityInstances[${index}]`, "RenderTree node identity does not match the declared capability/provider instance.");
941
1376
  }
942
1377
  const registration = registrationsByPair.get(`${(0, exports.revisionRefKey)(instance.capabilityRevisionRef)}:${(0, exports.revisionRefKey)(instance.providerRevisionRef)}`);
943
1378
  if (!registration) {
944
- throw new DeclarativeControlCompilationError('CAPABILITY_BINDING_MISMATCH', `capabilityInstances[${index}]`, 'Capability/provider pair has no exact governed Design registration.');
1379
+ throw new DeclarativeControlCompilationError("CAPABILITY_BINDING_MISMATCH", `capabilityInstances[${index}]`, "Capability/provider pair has no exact governed Design registration.");
945
1380
  }
946
1381
  if (instance.allowedSideEffects.some((sideEffect) => !registration.allowedSideEffects.includes(sideEffect))) {
947
- throw new DeclarativeControlCompilationError('CAPABILITY_BINDING_MISMATCH', `capabilityInstances[${index}].allowedSideEffects`, 'Page requests undeclared provider side effects.');
1382
+ throw new DeclarativeControlCompilationError("CAPABILITY_BINDING_MISMATCH", `capabilityInstances[${index}].allowedSideEffects`, "Page requests undeclared provider side effects.");
948
1383
  }
949
1384
  if (!(0, exports.sameRevisionRef)(instance.propertySchemaRevisionRef, registration.propertySchemaRevisionRef)) {
950
- throw new DeclarativeControlCompilationError('CAPABILITY_BINDING_MISMATCH', `capabilityInstances[${index}].propertySchemaRevisionRef`, 'Capability properties do not pin the exact schema registered by the active Design catalog.');
1385
+ throw new DeclarativeControlCompilationError("CAPABILITY_BINDING_MISMATCH", `capabilityInstances[${index}].propertySchemaRevisionRef`, "Capability properties do not pin the exact schema registered by the active Design catalog.");
951
1386
  }
952
- if (!(0, exports.accessPolicyChainImplies)([page.pageAccessPolicy, ...(instance.accessPolicy ? [instance.accessPolicy] : [])], registration.accessPolicy)) {
953
- throw new DeclarativeControlCompilationError('AUDIENCE_WIDER_THAN_TARGET', `capabilityInstances[${index}]`, 'Page access is wider than the governed capability audience.');
1387
+ if (!(0, exports.accessPolicyChainImplies)([
1388
+ page.pageAccessPolicy,
1389
+ ...(instance.accessPolicy ? [instance.accessPolicy] : []),
1390
+ ], registration.accessPolicy)) {
1391
+ throw new DeclarativeControlCompilationError("AUDIENCE_WIDER_THAN_TARGET", `capabilityInstances[${index}]`, "Page access is wider than the governed capability audience.");
954
1392
  }
955
1393
  });
956
1394
  if (instancesByNode.size !== page.capabilityInstances.length) {
957
- throw new DeclarativeControlCompilationError('CAPABILITY_BINDING_MISMATCH', 'capabilityInstances', 'Each executable RenderTree node must be governed by at most one capability instance.');
1395
+ throw new DeclarativeControlCompilationError("CAPABILITY_BINDING_MISMATCH", "capabilityInstances", "Each executable RenderTree node must be governed by at most one capability instance.");
958
1396
  }
959
1397
  renderTree.nodes.forEach((node, index) => {
960
1398
  if (!node.providerRef)
961
1399
  return;
962
1400
  if (!instancesByNode.has(node.nodeId)) {
963
- throw new DeclarativeControlCompilationError('CAPABILITY_BINDING_MISMATCH', `renderTree.nodes[${index}]`, 'Every provider-backed RenderTree node must be governed by one capability instance.');
1401
+ throw new DeclarativeControlCompilationError("CAPABILITY_BINDING_MISMATCH", `renderTree.nodes[${index}]`, "Every provider-backed RenderTree node must be governed by one capability instance.");
964
1402
  }
965
1403
  });
966
1404
  page.ontologyBindings.forEach((binding, index) => {
@@ -968,16 +1406,20 @@ const compilePageRuntimeBundle = (input) => {
968
1406
  const registration = instance &&
969
1407
  registrationsByPair.get(`${(0, exports.revisionRefKey)(instance.capabilityRevisionRef)}:${(0, exports.revisionRefKey)(instance.providerRevisionRef)}`);
970
1408
  const port = registration?.inputPorts.find((candidate) => candidate.name === binding.target.port);
971
- if (!port || !(0, exports.sameRevisionRef)(port.schemaRevisionRef, binding.renderModelSchemaRevisionRef)) {
972
- throw new DeclarativeControlCompilationError('PORT_TYPE_MISMATCH', `ontologyBindings[${index}].target.port`, 'Ontology render model does not match the registered capability input port.');
1409
+ if (!port ||
1410
+ !(0, exports.sameRevisionRef)(port.schemaRevisionRef, binding.renderModelSchemaRevisionRef)) {
1411
+ throw new DeclarativeControlCompilationError("PORT_TYPE_MISMATCH", `ontologyBindings[${index}].target.port`, "Ontology render model does not match the registered capability input port.");
973
1412
  }
974
1413
  if (binding.cursorWindow) {
975
- const sourceInstance = page.capabilityInstances.find(candidate => candidate.instanceId === (binding.cursorWindow.sourceCapabilityInstanceId ?? binding.target.capabilityInstanceId));
976
- const sourceRegistration = sourceInstance && registrationsByPair.get(`${(0, exports.revisionRefKey)(sourceInstance.capabilityRevisionRef)}:${(0, exports.revisionRefKey)(sourceInstance.providerRevisionRef)}`);
1414
+ const sourceInstance = page.capabilityInstances.find((candidate) => candidate.instanceId ===
1415
+ (binding.cursorWindow.sourceCapabilityInstanceId ??
1416
+ binding.target.capabilityInstanceId));
1417
+ const sourceRegistration = sourceInstance &&
1418
+ registrationsByPair.get(`${(0, exports.revisionRefKey)(sourceInstance.capabilityRevisionRef)}:${(0, exports.revisionRefKey)(sourceInstance.providerRevisionRef)}`);
977
1419
  const pageChangePort = sourceRegistration?.outputPorts.find((candidate) => candidate.name === binding.cursorWindow.pageChangePort);
978
1420
  if (!pageChangePort ||
979
1421
  !(0, exports.sameRevisionRef)(pageChangePort.schemaRevisionRef, binding.cursorWindow.pageChangeIntentSchemaRevisionRef)) {
980
- throw new DeclarativeControlCompilationError('PORT_TYPE_MISMATCH', `ontologyBindings[${index}].cursorWindow.pageChangePort`, 'Cursor-window page-change intent does not match the registered capability output port.');
1422
+ throw new DeclarativeControlCompilationError("PORT_TYPE_MISMATCH", `ontologyBindings[${index}].cursorWindow.pageChangePort`, "Cursor-window page-change intent does not match the registered capability output port.");
981
1423
  }
982
1424
  }
983
1425
  });
@@ -986,19 +1428,26 @@ const compilePageRuntimeBundle = (input) => {
986
1428
  const registration = instance &&
987
1429
  registrationsByPair.get(`${(0, exports.revisionRefKey)(instance.capabilityRevisionRef)}:${(0, exports.revisionRefKey)(instance.providerRevisionRef)}`);
988
1430
  const port = registration?.inputPorts.find((candidate) => candidate.name === binding.target.port);
989
- if (!port || !(0, exports.sameRevisionRef)(port.schemaRevisionRef, (binding.targetProjection?.schemaRevisionRef ?? binding.renderModelSchemaRevisionRef))) {
990
- throw new DeclarativeControlCompilationError('PORT_TYPE_MISMATCH', `queryBindings[${index}].target.port`, 'Domain Query render model does not match the registered capability input port.');
1431
+ if (!port ||
1432
+ !(0, exports.sameRevisionRef)(port.schemaRevisionRef, binding.targetProjection?.schemaRevisionRef ??
1433
+ binding.renderModelSchemaRevisionRef)) {
1434
+ throw new DeclarativeControlCompilationError("PORT_TYPE_MISMATCH", `queryBindings[${index}].target.port`, "Domain Query render model does not match the registered capability input port.");
991
1435
  }
992
- if (binding.streamTargetProjection && (!port || !(0, exports.sameRevisionRef)(port.schemaRevisionRef, binding.streamTargetProjection.schemaRevisionRef))) {
993
- throw new DeclarativeControlCompilationError('PORT_TYPE_MISMATCH', `queryBindings[${index}].streamTargetProjection`, 'Stream render model does not match the registered capability input port.');
1436
+ if (binding.streamTargetProjection &&
1437
+ (!port ||
1438
+ !(0, exports.sameRevisionRef)(port.schemaRevisionRef, binding.streamTargetProjection.schemaRevisionRef))) {
1439
+ throw new DeclarativeControlCompilationError("PORT_TYPE_MISMATCH", `queryBindings[${index}].streamTargetProjection`, "Stream render model does not match the registered capability input port.");
994
1440
  }
995
1441
  if (binding.cursorWindow) {
996
- const sourceInstance = page.capabilityInstances.find(candidate => candidate.instanceId === (binding.cursorWindow.sourceCapabilityInstanceId ?? binding.target.capabilityInstanceId));
997
- const sourceRegistration = sourceInstance && registrationsByPair.get(`${(0, exports.revisionRefKey)(sourceInstance.capabilityRevisionRef)}:${(0, exports.revisionRefKey)(sourceInstance.providerRevisionRef)}`);
1442
+ const sourceInstance = page.capabilityInstances.find((candidate) => candidate.instanceId ===
1443
+ (binding.cursorWindow.sourceCapabilityInstanceId ??
1444
+ binding.target.capabilityInstanceId));
1445
+ const sourceRegistration = sourceInstance &&
1446
+ registrationsByPair.get(`${(0, exports.revisionRefKey)(sourceInstance.capabilityRevisionRef)}:${(0, exports.revisionRefKey)(sourceInstance.providerRevisionRef)}`);
998
1447
  const pageChangePort = sourceRegistration?.outputPorts.find((candidate) => candidate.name === binding.cursorWindow.pageChangePort);
999
1448
  if (!pageChangePort ||
1000
1449
  !(0, exports.sameRevisionRef)(pageChangePort.schemaRevisionRef, binding.cursorWindow.pageChangeIntentSchemaRevisionRef)) {
1001
- throw new DeclarativeControlCompilationError('PORT_TYPE_MISMATCH', `queryBindings[${index}].cursorWindow.pageChangePort`, 'Cursor-window page-change intent does not match the registered capability output port.');
1450
+ throw new DeclarativeControlCompilationError("PORT_TYPE_MISMATCH", `queryBindings[${index}].cursorWindow.pageChangePort`, "Cursor-window page-change intent does not match the registered capability output port.");
1002
1451
  }
1003
1452
  }
1004
1453
  });
@@ -1006,12 +1455,13 @@ const compilePageRuntimeBundle = (input) => {
1006
1455
  const registration = registrationsByPair.get(`${(0, exports.revisionRefKey)(instance.capabilityRevisionRef)}:${(0, exports.revisionRefKey)(instance.providerRevisionRef)}`);
1007
1456
  instance.eventPayloadBindings?.forEach((binding, bindingIndex) => {
1008
1457
  if (!registration?.outputPorts.some((port) => port.name === binding.port))
1009
- throw new DeclarativeControlCompilationError('PORT_TYPE_MISMATCH', `capabilityInstances[${index}].eventPayloadBindings[${bindingIndex}]`, 'Event payload projection must reference a registered output port.');
1458
+ throw new DeclarativeControlCompilationError("PORT_TYPE_MISMATCH", `capabilityInstances[${index}].eventPayloadBindings[${bindingIndex}]`, "Event payload projection must reference a registered output port.");
1010
1459
  });
1011
1460
  instance.eventEffects?.forEach((effect, effectIndex) => {
1012
1461
  const port = registration?.outputPorts.find((candidate) => candidate.name === effect.sourcePort);
1013
- if (!port || !(0, exports.sameRevisionRef)(port.schemaRevisionRef, effect.sourceIntentSchemaRevisionRef))
1014
- throw new DeclarativeControlCompilationError('PORT_TYPE_MISMATCH', `capabilityInstances[${index}].eventEffects[${effectIndex}]`, 'Event effect source must match an exact registered output port schema.');
1462
+ if (!port ||
1463
+ !(0, exports.sameRevisionRef)(port.schemaRevisionRef, effect.sourceIntentSchemaRevisionRef))
1464
+ throw new DeclarativeControlCompilationError("PORT_TYPE_MISMATCH", `capabilityInstances[${index}].eventEffects[${effectIndex}]`, "Event effect source must match an exact registered output port schema.");
1015
1465
  });
1016
1466
  });
1017
1467
  page.interactionBindings.forEach((binding, index) => {
@@ -1019,8 +1469,9 @@ const compilePageRuntimeBundle = (input) => {
1019
1469
  const registration = instance &&
1020
1470
  registrationsByPair.get(`${(0, exports.revisionRefKey)(instance.capabilityRevisionRef)}:${(0, exports.revisionRefKey)(instance.providerRevisionRef)}`);
1021
1471
  const port = registration?.outputPorts.find((candidate) => candidate.name === binding.source.port);
1022
- if (!port || !(0, exports.sameRevisionRef)(port.schemaRevisionRef, binding.sourceIntentSchemaRevisionRef)) {
1023
- throw new DeclarativeControlCompilationError('PORT_TYPE_MISMATCH', `interactionBindings[${index}].sourceIntentSchemaRevisionRef`, 'Interaction source intent does not match the registered capability output port.');
1472
+ if (!port ||
1473
+ !(0, exports.sameRevisionRef)(port.schemaRevisionRef, binding.sourceIntentSchemaRevisionRef)) {
1474
+ throw new DeclarativeControlCompilationError("PORT_TYPE_MISMATCH", `interactionBindings[${index}].sourceIntentSchemaRevisionRef`, "Interaction source intent does not match the registered capability output port.");
1024
1475
  }
1025
1476
  });
1026
1477
  page.actionBindings.forEach((binding, index) => {
@@ -1028,24 +1479,28 @@ const compilePageRuntimeBundle = (input) => {
1028
1479
  const registration = instance &&
1029
1480
  registrationsByPair.get(`${(0, exports.revisionRefKey)(instance.capabilityRevisionRef)}:${(0, exports.revisionRefKey)(instance.providerRevisionRef)}`);
1030
1481
  const port = registration?.outputPorts.find((candidate) => candidate.name === binding.source.port);
1031
- if (!port || !(0, exports.sameRevisionRef)(port.schemaRevisionRef, binding.sourceIntentSchemaRevisionRef)) {
1032
- throw new DeclarativeControlCompilationError('PORT_TYPE_MISMATCH', `actionBindings[${index}].sourceIntentSchemaRevisionRef`, 'Action source intent does not match the registered capability output port.');
1482
+ if (!port ||
1483
+ !(0, exports.sameRevisionRef)(port.schemaRevisionRef, binding.sourceIntentSchemaRevisionRef)) {
1484
+ throw new DeclarativeControlCompilationError("PORT_TYPE_MISMATCH", `actionBindings[${index}].sourceIntentSchemaRevisionRef`, "Action source intent does not match the registered capability output port.");
1033
1485
  }
1034
1486
  });
1035
1487
  const routeClaims = (0, exports.compileRouteClaims)({
1036
1488
  claims: page.routeClaims,
1037
1489
  routeSpaces: input.routeSpaces,
1038
1490
  surface: release.target.surface,
1039
- legacyRouteTakeoverAuthorizations: release.target.legacyRouteTakeoverAuthorization
1491
+ legacyRouteTakeoverAuthorizations: release.target
1492
+ .legacyRouteTakeoverAuthorization
1040
1493
  ? [release.target.legacyRouteTakeoverAuthorization]
1041
1494
  : [],
1042
1495
  });
1043
- const releaseRoute = routeClaims.find((claim) => claim.kind === 'canonical' && claim.normalizedPath === release.target.normalizedPath);
1044
- if (!releaseRoute || !(0, exports.sameRevisionRef)(releaseRoute.routeSpaceRevisionRef, release.target.routeSpaceRevisionRef)) {
1045
- throw new DeclarativeControlCompilationError('ROUTE_SPACE_MISMATCH', 'release.target', 'Release target does not match an exact Page route claim.');
1496
+ const releaseRoute = routeClaims.find((claim) => claim.kind === "canonical" &&
1497
+ claim.normalizedPath === release.target.normalizedPath);
1498
+ if (!releaseRoute ||
1499
+ !(0, exports.sameRevisionRef)(releaseRoute.routeSpaceRevisionRef, release.target.routeSpaceRevisionRef)) {
1500
+ throw new DeclarativeControlCompilationError("ROUTE_SPACE_MISMATCH", "release.target", "Release target does not match an exact Page route claim.");
1046
1501
  }
1047
1502
  if (!page.supportedSurfaces.includes(release.target.surface)) {
1048
- throw new DeclarativeControlCompilationError('ROUTE_SPACE_MISMATCH', 'release.target.surface', 'Page does not support the release surface.');
1503
+ throw new DeclarativeControlCompilationError("ROUTE_SPACE_MISMATCH", "release.target.surface", "Page does not support the release surface.");
1049
1504
  }
1050
1505
  const routeTargets = (input.targetRegistry ?? []).map((registration, index) => ({
1051
1506
  ...registration,
@@ -1060,33 +1515,36 @@ const compilePageRuntimeBundle = (input) => {
1060
1515
  routeClaim: declarative_control_1.CompiledRouteClaimSchema.parse(registration.routeClaim),
1061
1516
  sourceIndex: index,
1062
1517
  }));
1063
- assertUniqueRegistryKeys(routeTargets.map((registration) => (0, exports.stableRefKey)(registration.stableTargetRef)), 'targetRegistry');
1518
+ assertUniqueRegistryKeys(routeTargets.map((registration) => (0, exports.stableRefKey)(registration.stableTargetRef)), "targetRegistry");
1064
1519
  const entryTransitions = page.entryTransitions.map((transition, index) => {
1065
- const matches = routeTargets.filter((registration) => registration.kind === 'route' &&
1520
+ const matches = routeTargets.filter((registration) => registration.kind === "route" &&
1066
1521
  (0, exports.sameStableRef)(registration.stableTargetRef, transition.targetRef) &&
1067
1522
  registration.surface === release.target.surface);
1068
1523
  if (matches.length !== 1) {
1069
- throw new DeclarativeControlCompilationError('PAGE_ENTRY_TARGET_UNRELEASED', `entryTransitions[${index}].targetRef`, 'Entry transition target must resolve to one exact active route registration on the same surface.');
1524
+ throw new DeclarativeControlCompilationError("PAGE_ENTRY_TARGET_UNRELEASED", `entryTransitions[${index}].targetRef`, "Entry transition target must resolve to one exact active route registration on the same surface.");
1070
1525
  }
1071
1526
  const target = matches[0];
1072
- if (target.releaseRevisionRef && !['page-release', 'workbench-release'].includes(target.releaseRevisionRef.kind)) {
1073
- throw new DeclarativeControlCompilationError('PAGE_ENTRY_TARGET_UNRELEASED', `entryTransitions[${index}].targetRef`, 'Entry transition Release provenance must identify a Page or Workbench Release.');
1527
+ if (target.releaseRevisionRef &&
1528
+ !["page-release", "workbench-release"].includes(target.releaseRevisionRef.kind)) {
1529
+ throw new DeclarativeControlCompilationError("PAGE_ENTRY_TARGET_UNRELEASED", `entryTransitions[${index}].targetRef`, "Entry transition Release provenance must identify a Page or Workbench Release.");
1074
1530
  }
1075
- if (target.routeClaim.kind !== 'canonical') {
1076
- throw new DeclarativeControlCompilationError('PAGE_ENTRY_TARGET_UNRELEASED', `entryTransitions[${index}].targetRef`, 'Entry transition targets must expose one canonical route claim.');
1531
+ if (target.routeClaim.kind !== "canonical") {
1532
+ throw new DeclarativeControlCompilationError("PAGE_ENTRY_TARGET_UNRELEASED", `entryTransitions[${index}].targetRef`, "Entry transition targets must expose one canonical route claim.");
1077
1533
  }
1078
1534
  if (!(0, exports.sameStableRef)(target.stableTargetRef, target.targetRevisionRef)) {
1079
- throw new DeclarativeControlCompilationError('PAGE_ENTRY_TARGET_UNRELEASED', `targetRegistry[${target.sourceIndex}]`, 'Entry transition target registration identity is not exact.');
1535
+ throw new DeclarativeControlCompilationError("PAGE_ENTRY_TARGET_UNRELEASED", `targetRegistry[${target.sourceIndex}]`, "Entry transition target registration identity is not exact.");
1080
1536
  }
1081
1537
  // Entry transitions may narrow into a separately protected route. The target
1082
1538
  // route remains authoritative and re-evaluates its own access policy after
1083
1539
  // navigation, so a source Page must not inherit the target's permissions.
1084
- const requiredPathParameters = [...target.routeClaim.normalizedPath.matchAll(/:([A-Za-z][A-Za-z0-9_-]*)/g)].map((match) => match[1]);
1540
+ const requiredPathParameters = [
1541
+ ...target.routeClaim.normalizedPath.matchAll(/:([A-Za-z][A-Za-z0-9_-]*)/g),
1542
+ ].map((match) => match[1]);
1085
1543
  const mappedPathParameters = Object.keys(transition.pathParameters);
1086
1544
  const missing = requiredPathParameters.find((name) => !mappedPathParameters.includes(name));
1087
1545
  const unknown = mappedPathParameters.find((name) => !requiredPathParameters.includes(name));
1088
1546
  if (missing || unknown) {
1089
- throw new DeclarativeControlCompilationError('ROUTE_SPACE_MISMATCH', `entryTransitions[${index}].pathParameters`, missing
1547
+ throw new DeclarativeControlCompilationError("ROUTE_SPACE_MISMATCH", `entryTransitions[${index}].pathParameters`, missing
1090
1548
  ? `Entry transition does not resolve target route parameter ${missing}.`
1091
1549
  : `Entry transition maps unknown target route parameter ${unknown}.`);
1092
1550
  }
@@ -1106,15 +1564,17 @@ const compilePageRuntimeBundle = (input) => {
1106
1564
  ]);
1107
1565
  return {
1108
1566
  ...transition,
1109
- browsingContext: transition.browsingContext ?? 'same',
1567
+ browsingContext: transition.browsingContext ?? "same",
1110
1568
  targetRevisionRef: target.targetRevisionRef,
1111
- ...(target.releaseRevisionRef ? { targetReleaseRevisionRef: target.releaseRevisionRef } : {}),
1569
+ ...(target.releaseRevisionRef
1570
+ ? { targetReleaseRevisionRef: target.releaseRevisionRef }
1571
+ : {}),
1112
1572
  targetAccessPolicy: target.accessPolicy,
1113
1573
  targetRouteClaim: target.routeClaim,
1114
1574
  };
1115
1575
  });
1116
1576
  const unsigned = {
1117
- contract: 'PageRuntimeBundle',
1577
+ contract: "PageRuntimeBundle",
1118
1578
  schemaVersion: 1,
1119
1579
  tenantScope: scope,
1120
1580
  releaseRevisionRef,
@@ -1153,23 +1613,23 @@ const compilePageRuntimeBundle = (input) => {
1153
1613
  exports.compilePageRuntimeBundle = compilePageRuntimeBundle;
1154
1614
  const workbenchDependencyRole = (kind) => {
1155
1615
  switch (kind) {
1156
- case 'workflow':
1157
- return 'workflow';
1158
- case 'agent':
1159
- return 'agent';
1160
- case 'capability':
1161
- return 'capability';
1162
- case 'design':
1163
- return 'design';
1164
- case 'built-in-application':
1165
- return 'built-in-application';
1616
+ case "workflow":
1617
+ return "workflow";
1618
+ case "agent":
1619
+ return "agent";
1620
+ case "capability":
1621
+ return "capability";
1622
+ case "design":
1623
+ return "design";
1624
+ case "built-in-application":
1625
+ return "built-in-application";
1166
1626
  default:
1167
- return 'workflow';
1627
+ return "workflow";
1168
1628
  }
1169
1629
  };
1170
1630
  const workbenchDependencies = (workbench, compilerRevisionRef) => [
1171
1631
  ...workbench.routeClaims.map((claim) => ({
1172
- role: 'route-space',
1632
+ role: "route-space",
1173
1633
  revisionRef: claim.routeSpaceRevisionRef,
1174
1634
  })),
1175
1635
  ...workbench.appInstances.flatMap((instance) => [
@@ -1177,28 +1637,28 @@ const workbenchDependencies = (workbench, compilerRevisionRef) => [
1177
1637
  role: workbenchDependencyRole(instance.targetRevisionRef.kind),
1178
1638
  revisionRef: instance.targetRevisionRef,
1179
1639
  },
1180
- { role: 'provider', revisionRef: instance.providerRevisionRef },
1181
- { role: 'schema', revisionRef: instance.inputSchemaRevisionRef },
1640
+ { role: "provider", revisionRef: instance.providerRevisionRef },
1641
+ { role: "schema", revisionRef: instance.inputSchemaRevisionRef },
1182
1642
  ]),
1183
1643
  {
1184
- role: 'capability',
1644
+ role: "capability",
1185
1645
  revisionRef: workbench.layout.hostCapabilityRevisionRef,
1186
1646
  },
1187
- { role: 'provider', revisionRef: workbench.layout.hostProviderRevisionRef },
1647
+ { role: "provider", revisionRef: workbench.layout.hostProviderRevisionRef },
1188
1648
  {
1189
- role: 'layout-policy',
1649
+ role: "layout-policy",
1190
1650
  revisionRef: workbench.layout.layoutPolicyRevisionRef,
1191
1651
  },
1192
1652
  ...workbench.layout.tokenRevisionRefs.map((revisionRef) => ({
1193
- role: 'token',
1653
+ role: "token",
1194
1654
  revisionRef,
1195
1655
  })),
1196
- { role: 'performance-budget', revisionRef: workbench.performanceBudgetRef },
1656
+ { role: "performance-budget", revisionRef: workbench.performanceBudgetRef },
1197
1657
  {
1198
- role: 'observation-policy',
1658
+ role: "observation-policy",
1199
1659
  revisionRef: workbench.observationPolicyRevisionRef,
1200
1660
  },
1201
- { role: 'compiler', revisionRef: compilerRevisionRef },
1661
+ { role: "compiler", revisionRef: compilerRevisionRef },
1202
1662
  ];
1203
1663
  const compileWorkbenchRuntimeBundle = (input) => {
1204
1664
  const workbench = declarative_control_1.WorkbenchSchema.parse(input.workbench);
@@ -1207,20 +1667,20 @@ const compileWorkbenchRuntimeBundle = (input) => {
1207
1667
  const releaseRevisionRef = declarative_control_1.RevisionRefSchema.parse(input.releaseRevisionRef);
1208
1668
  const compilerRevisionRef = declarative_control_1.RevisionRefSchema.parse(input.compilerRevisionRef);
1209
1669
  const scope = declarative_control_1.TenantScopeSchema.parse(workbench.tenantScope);
1210
- assertSameTenantScope(release.tenantScope, scope, 'release.tenantScope');
1211
- if (workbench.purpose === 'template')
1212
- throw new DeclarativeControlCompilationError('WORKBENCH_TEMPLATE_UNRELEASABLE', 'workbench.purpose', 'Workbench templates cannot be activated.');
1670
+ assertSameTenantScope(release.tenantScope, scope, "release.tenantScope");
1671
+ if (workbench.purpose === "template")
1672
+ throw new DeclarativeControlCompilationError("WORKBENCH_TEMPLATE_UNRELEASABLE", "workbench.purpose", "Workbench templates cannot be activated.");
1213
1673
  if (workbench.groups.length > input.limits.maxWorkbenchGroups ||
1214
1674
  workbench.appInstances.length > input.limits.maxWorkbenchInstances) {
1215
- throw new DeclarativeControlCompilationError('WORKBENCH_INSTANCE_LIMIT_EXCEEDED', 'workbench', 'Workbench exceeds caller-approved compilation limits.');
1675
+ throw new DeclarativeControlCompilationError("WORKBENCH_INSTANCE_LIMIT_EXCEEDED", "workbench", "Workbench exceeds caller-approved compilation limits.");
1216
1676
  }
1217
- assertRevisionIdentity(workbenchRevisionRef, 'workbench', workbench.workbenchId, scope, 'workbenchRevisionRef');
1218
- assertRevisionIdentity(release.workbenchRevisionRef, 'workbench', workbench.workbenchId, scope, 'release.workbenchRevisionRef');
1677
+ assertRevisionIdentity(workbenchRevisionRef, "workbench", workbench.workbenchId, scope, "workbenchRevisionRef");
1678
+ assertRevisionIdentity(release.workbenchRevisionRef, "workbench", workbench.workbenchId, scope, "release.workbenchRevisionRef");
1219
1679
  if (!(0, exports.sameRevisionRef)(workbenchRevisionRef, release.workbenchRevisionRef))
1220
- throw new DeclarativeControlCompilationError('REVISION_MISMATCH', 'release.workbenchRevisionRef', 'Release does not pin the supplied Workbench revision.');
1221
- assertRevisionIdentity(releaseRevisionRef, 'workbench-release', release.releaseSlotId, scope, 'releaseRevisionRef');
1680
+ throw new DeclarativeControlCompilationError("REVISION_MISMATCH", "release.workbenchRevisionRef", "Release does not pin the supplied Workbench revision.");
1681
+ assertRevisionIdentity(releaseRevisionRef, "workbench-release", release.releaseSlotId, scope, "releaseRevisionRef");
1222
1682
  if (release.target.workbenchId !== workbench.workbenchId)
1223
- throw new DeclarativeControlCompilationError('REVISION_MISMATCH', 'release.target.workbenchId', 'Release target does not match Workbench identity.');
1683
+ throw new DeclarativeControlCompilationError("REVISION_MISMATCH", "release.target.workbenchId", "Release target does not match Workbench identity.");
1224
1684
  requireReleaseReady(release);
1225
1685
  requireDependencies(release.dependencySnapshot, workbenchDependencies(workbench, compilerRevisionRef));
1226
1686
  assertDependencyScopes(release.dependencySnapshot, scope);
@@ -1228,21 +1688,27 @@ const compileWorkbenchRuntimeBundle = (input) => {
1228
1688
  claims: workbench.routeClaims,
1229
1689
  routeSpaces: input.routeSpaces,
1230
1690
  surface: release.target.surface,
1231
- legacyRouteTakeoverAuthorizations: release.target.legacyRouteTakeoverAuthorization
1691
+ legacyRouteTakeoverAuthorizations: release.target
1692
+ .legacyRouteTakeoverAuthorization
1232
1693
  ? [release.target.legacyRouteTakeoverAuthorization]
1233
1694
  : [],
1234
1695
  });
1235
- const releaseRoute = routeClaims.find((claim) => claim.kind === 'canonical' && claim.normalizedPath === release.target.normalizedPath);
1236
- if (!releaseRoute || !(0, exports.sameRevisionRef)(releaseRoute.routeSpaceRevisionRef, release.target.routeSpaceRevisionRef)) {
1237
- throw new DeclarativeControlCompilationError('ROUTE_SPACE_MISMATCH', 'release.target', 'Release target does not match an exact Workbench route claim.');
1696
+ const releaseRoute = routeClaims.find((claim) => claim.kind === "canonical" &&
1697
+ claim.normalizedPath === release.target.normalizedPath);
1698
+ if (!releaseRoute ||
1699
+ !(0, exports.sameRevisionRef)(releaseRoute.routeSpaceRevisionRef, release.target.routeSpaceRevisionRef)) {
1700
+ throw new DeclarativeControlCompilationError("ROUTE_SPACE_MISMATCH", "release.target", "Release target does not match an exact Workbench route claim.");
1238
1701
  }
1239
1702
  const targetRegistry = input.targetRegistry.map((registration) => ({
1240
1703
  stableTargetRef: declarative_control_1.StableRefSchema.parse(registration.stableTargetRef),
1241
1704
  targetRevisionRef: declarative_control_1.RevisionRefSchema.parse(registration.targetRevisionRef),
1242
1705
  accessPolicy: declarative_control_1.AccessPolicySchema.parse(registration.accessPolicy),
1243
1706
  }));
1244
- assertUniqueRegistryKeys(targetRegistry.map((registration) => (0, exports.stableRefKey)(registration.stableTargetRef)), 'targetRegistry');
1245
- const targetsByStableRef = new Map(targetRegistry.map((registration) => [(0, exports.stableRefKey)(registration.stableTargetRef), registration]));
1707
+ assertUniqueRegistryKeys(targetRegistry.map((registration) => (0, exports.stableRefKey)(registration.stableTargetRef)), "targetRegistry");
1708
+ const targetsByStableRef = new Map(targetRegistry.map((registration) => [
1709
+ (0, exports.stableRefKey)(registration.stableTargetRef),
1710
+ registration,
1711
+ ]));
1246
1712
  const groupsById = new Map(workbench.groups.map((group) => [group.groupId, group]));
1247
1713
  const appInstances = workbench.appInstances.map((instance, index) => {
1248
1714
  const stableTarget = declarative_control_1.StableRefSchema.parse({
@@ -1250,13 +1716,15 @@ const compileWorkbenchRuntimeBundle = (input) => {
1250
1716
  id: instance.targetRevisionRef.id,
1251
1717
  ownerRepo: instance.targetRevisionRef.ownerRepo,
1252
1718
  visibility: instance.targetRevisionRef.visibility,
1253
- ...(instance.targetRevisionRef.tenantScope ? { tenantScope: instance.targetRevisionRef.tenantScope } : {}),
1719
+ ...(instance.targetRevisionRef.tenantScope
1720
+ ? { tenantScope: instance.targetRevisionRef.tenantScope }
1721
+ : {}),
1254
1722
  });
1255
1723
  const registration = targetsByStableRef.get((0, exports.stableRefKey)(stableTarget));
1256
1724
  if (!registration ||
1257
1725
  !(0, exports.sameStableRef)(registration.stableTargetRef, stableFromRevision(registration.targetRevisionRef)) ||
1258
1726
  !(0, exports.sameRevisionRef)(registration.targetRevisionRef, instance.targetRevisionRef)) {
1259
- throw new DeclarativeControlCompilationError('NAV_TARGET_UNRELEASED', `appInstances[${index}].targetRevisionRef`, 'Workbench app target is not present at the exact registered revision.');
1727
+ throw new DeclarativeControlCompilationError("NAV_TARGET_UNRELEASED", `appInstances[${index}].targetRevisionRef`, "Workbench app target is not present at the exact registered revision.");
1260
1728
  }
1261
1729
  assertTenantCompatible(instance.targetRevisionRef, scope, `appInstances[${index}].targetRevisionRef`);
1262
1730
  const group = groupsById.get(instance.groupId);
@@ -1266,12 +1734,12 @@ const compileWorkbenchRuntimeBundle = (input) => {
1266
1734
  instance.accessPolicy,
1267
1735
  ];
1268
1736
  if (!(0, exports.accessPolicyChainImplies)(chain, registration.accessPolicy)) {
1269
- throw new DeclarativeControlCompilationError('AUDIENCE_WIDER_THAN_TARGET', `appInstances[${index}].accessPolicy`, 'Workbench and instance audience is wider than the target audience.');
1737
+ throw new DeclarativeControlCompilationError("AUDIENCE_WIDER_THAN_TARGET", `appInstances[${index}].accessPolicy`, "Workbench and instance audience is wider than the target audience.");
1270
1738
  }
1271
1739
  return { ...instance, targetAccessPolicy: registration.accessPolicy };
1272
1740
  });
1273
1741
  const unsigned = {
1274
- contract: 'WorkbenchRuntimeBundle',
1742
+ contract: "WorkbenchRuntimeBundle",
1275
1743
  schemaVersion: 1,
1276
1744
  tenantScope: scope,
1277
1745
  releaseRevisionRef,
@@ -1284,7 +1752,9 @@ const compileWorkbenchRuntimeBundle = (input) => {
1284
1752
  workbenchRevisionRef,
1285
1753
  identity: {
1286
1754
  name: workbench.identity.name,
1287
- ...(workbench.identity.description ? { description: workbench.identity.description } : {}),
1755
+ ...(workbench.identity.description
1756
+ ? { description: workbench.identity.description }
1757
+ : {}),
1288
1758
  },
1289
1759
  surface: release.target.surface,
1290
1760
  routeClaims,
@@ -1322,7 +1792,7 @@ const navigationDepth = (navigation) => {
1322
1792
  const orderedNavigationNodes = (navigation) => {
1323
1793
  const children = new Map();
1324
1794
  navigation.nodes.forEach((node) => {
1325
- const parent = node.parentNodeId ?? '';
1795
+ const parent = node.parentNodeId ?? "";
1326
1796
  const siblings = children.get(parent) ?? [];
1327
1797
  children.set(parent, [...siblings, node]);
1328
1798
  });
@@ -1334,14 +1804,14 @@ const orderedNavigationNodes = (navigation) => {
1334
1804
  append(node.nodeId);
1335
1805
  }
1336
1806
  };
1337
- append('');
1807
+ append("");
1338
1808
  return ordered;
1339
1809
  };
1340
1810
  const navigationDependencies = (navigation, release, compilerRevisionRef) => [
1341
1811
  ...release.resolvedTargets.flatMap((target) => [
1342
1812
  {
1343
- role: target.targetRevisionRef.kind === 'domain-command'
1344
- ? 'action'
1813
+ role: target.targetRevisionRef.kind === "domain-command"
1814
+ ? "action"
1345
1815
  : target.targetRevisionRef.kind,
1346
1816
  revisionRef: target.targetRevisionRef,
1347
1817
  },
@@ -1354,12 +1824,12 @@ const navigationDependencies = (navigation, release, compilerRevisionRef) => [
1354
1824
  ]
1355
1825
  : []),
1356
1826
  ]),
1357
- { role: 'performance-budget', revisionRef: navigation.performanceBudgetRef },
1827
+ { role: "performance-budget", revisionRef: navigation.performanceBudgetRef },
1358
1828
  {
1359
- role: 'observation-policy',
1829
+ role: "observation-policy",
1360
1830
  revisionRef: navigation.observationPolicyRevisionRef,
1361
1831
  },
1362
- { role: 'compiler', revisionRef: compilerRevisionRef },
1832
+ { role: "compiler", revisionRef: compilerRevisionRef },
1363
1833
  ];
1364
1834
  const compileNavigationRuntimeBundle = (input) => {
1365
1835
  const navigation = declarative_control_1.NavigationSchema.parse(input.navigation);
@@ -1368,19 +1838,20 @@ const compileNavigationRuntimeBundle = (input) => {
1368
1838
  const releaseRevisionRef = declarative_control_1.RevisionRefSchema.parse(input.releaseRevisionRef);
1369
1839
  const compilerRevisionRef = declarative_control_1.RevisionRefSchema.parse(input.compilerRevisionRef);
1370
1840
  const scope = declarative_control_1.TenantScopeSchema.parse(navigation.tenantScope);
1371
- assertSameTenantScope(release.tenantScope, scope, 'release.tenantScope');
1841
+ assertSameTenantScope(release.tenantScope, scope, "release.tenantScope");
1372
1842
  if (navigation.nodes.length > input.limits.maxNavigationNodes)
1373
- throw new DeclarativeControlCompilationError('NAV_NODE_LIMIT_EXCEEDED', 'navigation.nodes', 'Navigation exceeds the caller-approved node limit.');
1843
+ throw new DeclarativeControlCompilationError("NAV_NODE_LIMIT_EXCEEDED", "navigation.nodes", "Navigation exceeds the caller-approved node limit.");
1374
1844
  if (navigationDepth(navigation) > input.limits.maxNavigationDepth)
1375
- throw new DeclarativeControlCompilationError('NAV_DEPTH_EXCEEDED', 'navigation.nodes', 'Navigation exceeds the caller-approved depth limit.');
1376
- assertRevisionIdentity(navigationRevisionRef, 'navigation', navigation.navigationId, scope, 'navigationRevisionRef');
1377
- assertRevisionIdentity(release.navigationRevisionRef, 'navigation', navigation.navigationId, scope, 'release.navigationRevisionRef');
1845
+ throw new DeclarativeControlCompilationError("NAV_DEPTH_EXCEEDED", "navigation.nodes", "Navigation exceeds the caller-approved depth limit.");
1846
+ assertRevisionIdentity(navigationRevisionRef, "navigation", navigation.navigationId, scope, "navigationRevisionRef");
1847
+ assertRevisionIdentity(release.navigationRevisionRef, "navigation", navigation.navigationId, scope, "release.navigationRevisionRef");
1378
1848
  if (!(0, exports.sameRevisionRef)(navigationRevisionRef, release.navigationRevisionRef))
1379
- throw new DeclarativeControlCompilationError('REVISION_MISMATCH', 'release.navigationRevisionRef', 'Release does not pin the supplied Navigation revision.');
1380
- assertRevisionIdentity(releaseRevisionRef, 'navigation-release', release.releaseSlotId, scope, 'releaseRevisionRef');
1381
- if (release.target.surface !== navigation.supportedSurfaces.find((surface) => surface === release.target.surface) ||
1849
+ throw new DeclarativeControlCompilationError("REVISION_MISMATCH", "release.navigationRevisionRef", "Release does not pin the supplied Navigation revision.");
1850
+ assertRevisionIdentity(releaseRevisionRef, "navigation-release", release.releaseSlotId, scope, "releaseRevisionRef");
1851
+ if (release.target.surface !==
1852
+ navigation.supportedSurfaces.find((surface) => surface === release.target.surface) ||
1382
1853
  !navigation.placements.includes(release.target.placement)) {
1383
- throw new DeclarativeControlCompilationError('REVISION_MISMATCH', 'release.target', 'Navigation release target is not declared by the Navigation record.');
1854
+ throw new DeclarativeControlCompilationError("REVISION_MISMATCH", "release.target", "Navigation release target is not declared by the Navigation record.");
1384
1855
  }
1385
1856
  requireReleaseReady(release);
1386
1857
  requireDependencies(release.dependencySnapshot, navigationDependencies(navigation, release, compilerRevisionRef));
@@ -1392,32 +1863,32 @@ const compileNavigationRuntimeBundle = (input) => {
1392
1863
  surface: declarative_control_1.ProductSurfaceSchema.parse(registration.surface),
1393
1864
  accessPolicy: declarative_control_1.AccessPolicySchema.parse(registration.accessPolicy),
1394
1865
  };
1395
- if (registration.kind === 'route') {
1866
+ if (registration.kind === "route") {
1396
1867
  const routeClaim = declarative_control_1.CompiledRouteClaimSchema.parse(registration.routeClaim);
1397
1868
  if (routeClaim.surface !== common.surface) {
1398
- throw new DeclarativeControlCompilationError('ROUTE_SPACE_MISMATCH', `targetRegistry[${index}].routeClaim.surface`, 'Navigation route claim must match its registered surface.');
1869
+ throw new DeclarativeControlCompilationError("ROUTE_SPACE_MISMATCH", `targetRegistry[${index}].routeClaim.surface`, "Navigation route claim must match its registered surface.");
1399
1870
  }
1400
1871
  return {
1401
1872
  ...common,
1402
- kind: 'route',
1873
+ kind: "route",
1403
1874
  releaseRevisionRef: registration.releaseRevisionRef
1404
1875
  ? declarative_control_1.RevisionRefSchema.parse(registration.releaseRevisionRef)
1405
1876
  : undefined,
1406
1877
  routeClaim,
1407
1878
  };
1408
1879
  }
1409
- if (registration.kind === 'registered-menu-action') {
1880
+ if (registration.kind === "registered-menu-action") {
1410
1881
  const sourceCatalogRevisionRef = declarative_control_1.RevisionRefSchema.parse(registration.sourceCatalogRevisionRef);
1411
- if (sourceCatalogRevisionRef.kind !== 'application-menu-catalog' ||
1412
- registration.targetRevisionRef.kind !== 'menu-action') {
1413
- throw new DeclarativeControlCompilationError('NAV_TARGET_UNRELEASED', 'targetRegistry', 'Registered Menu Actions require exact menu-action and application-menu-catalog revisions.');
1882
+ if (sourceCatalogRevisionRef.kind !== "application-menu-catalog" ||
1883
+ registration.targetRevisionRef.kind !== "menu-action") {
1884
+ throw new DeclarativeControlCompilationError("NAV_TARGET_UNRELEASED", "targetRegistry", "Registered Menu Actions require exact menu-action and application-menu-catalog revisions.");
1414
1885
  }
1415
1886
  if (registration.inputSchemaRef && !registration.validateInput) {
1416
- throw new DeclarativeControlCompilationError('NAV_TARGET_UNRELEASED', 'targetRegistry', 'Registered Menu Actions with input schemas require the active catalog validator.');
1887
+ throw new DeclarativeControlCompilationError("NAV_TARGET_UNRELEASED", "targetRegistry", "Registered Menu Actions with input schemas require the active catalog validator.");
1417
1888
  }
1418
1889
  return {
1419
1890
  ...common,
1420
- kind: 'registered-menu-action',
1891
+ kind: "registered-menu-action",
1421
1892
  applicationId: registration.applicationId,
1422
1893
  actionRef: registration.actionRef,
1423
1894
  inputSchemaRef: registration.inputSchemaRef,
@@ -1425,33 +1896,37 @@ const compileNavigationRuntimeBundle = (input) => {
1425
1896
  sourceCatalogRevisionRef,
1426
1897
  };
1427
1898
  }
1428
- if (registration.targetRevisionRef.kind !== 'domain-command') {
1429
- throw new DeclarativeControlCompilationError('NAV_TARGET_UNRELEASED', 'targetRegistry', 'Governed DomainCommand actions require an exact domain-command revision.');
1899
+ if (registration.targetRevisionRef.kind !== "domain-command") {
1900
+ throw new DeclarativeControlCompilationError("NAV_TARGET_UNRELEASED", "targetRegistry", "Governed DomainCommand actions require an exact domain-command revision.");
1430
1901
  }
1431
1902
  const inputSchemaRevisionRef = declarative_control_1.RevisionRefSchema.parse(registration.inputSchemaRevisionRef);
1432
1903
  const resultSchemaRevisionRef = registration.resultSchemaRevisionRef
1433
1904
  ? declarative_control_1.RevisionRefSchema.parse(registration.resultSchemaRevisionRef)
1434
1905
  : undefined;
1435
- if (inputSchemaRevisionRef.kind !== 'schema' ||
1436
- (resultSchemaRevisionRef && resultSchemaRevisionRef.kind !== 'schema')) {
1437
- throw new DeclarativeControlCompilationError('NAV_TARGET_UNRELEASED', 'targetRegistry', 'Governed DomainCommand actions require exact input and output Schema revisions.');
1906
+ if (inputSchemaRevisionRef.kind !== "schema" ||
1907
+ (resultSchemaRevisionRef && resultSchemaRevisionRef.kind !== "schema")) {
1908
+ throw new DeclarativeControlCompilationError("NAV_TARGET_UNRELEASED", "targetRegistry", "Governed DomainCommand actions require exact input and output Schema revisions.");
1438
1909
  }
1439
1910
  return {
1440
1911
  ...common,
1441
- kind: 'governed-domain-command',
1912
+ kind: "governed-domain-command",
1442
1913
  inputSchemaRevisionRef,
1443
1914
  resultSchemaRevisionRef,
1444
1915
  };
1445
1916
  });
1446
- assertUniqueRegistryKeys(targetRegistry.map((registration) => (0, exports.stableRefKey)(registration.stableTargetRef)), 'targetRegistry');
1447
- const targetsByStableRef = new Map(targetRegistry.map((registration) => [(0, exports.stableRefKey)(registration.stableTargetRef), registration]));
1917
+ assertUniqueRegistryKeys(targetRegistry.map((registration) => (0, exports.stableRefKey)(registration.stableTargetRef)), "targetRegistry");
1918
+ const targetsByStableRef = new Map(targetRegistry.map((registration) => [
1919
+ (0, exports.stableRefKey)(registration.stableTargetRef),
1920
+ registration,
1921
+ ]));
1448
1922
  const releasedByNodeId = new Map(release.resolvedTargets.map((target) => [target.nodeId, target]));
1449
1923
  const unavailableByNodeId = new Map((release.unavailableTargets ?? []).map((target) => [target.nodeId, target]));
1450
1924
  const nodesById = new Map(navigation.nodes.map((node) => [node.nodeId, node]));
1451
1925
  for (const target of release.unavailableTargets ?? []) {
1452
1926
  const node = nodesById.get(target.nodeId);
1453
- if (node?.kind !== 'target' || !(0, exports.sameStableRef)(node.targetRef, target.stableTargetRef)) {
1454
- throw new DeclarativeControlCompilationError('NAV_TARGET_UNRELEASED', 'release.unavailableTargets', 'An unavailable target must identify its source Page node exactly.');
1927
+ if (node?.kind !== "target" ||
1928
+ !(0, exports.sameStableRef)(node.targetRef, target.stableTargetRef)) {
1929
+ throw new DeclarativeControlCompilationError("NAV_TARGET_UNRELEASED", "release.unavailableTargets", "An unavailable target must identify its source Page node exactly.");
1455
1930
  }
1456
1931
  }
1457
1932
  const nodes = orderedNavigationNodes(navigation).map((node, index) => {
@@ -1459,22 +1934,26 @@ const compileNavigationRuntimeBundle = (input) => {
1459
1934
  let parentId = node.parentNodeId;
1460
1935
  while (parentId) {
1461
1936
  const parent = nodesById.get(parentId);
1462
- if (parent?.kind === 'group')
1937
+ if (parent?.kind === "group")
1463
1938
  ancestors.unshift(parent.audience);
1464
1939
  parentId = parent?.parentNodeId ?? null;
1465
1940
  }
1466
- if (node.kind !== 'target')
1941
+ if (node.kind !== "target")
1467
1942
  return { ...node, ancestorAccessPolicies: ancestors };
1468
- if (!['page', 'workbench', 'menu-action', 'domain-command'].includes(node.targetRef.kind)) {
1469
- throw new DeclarativeControlCompilationError('NAV_TARGET_UNRELEASED', `nodes[${index}].targetRef.kind`, 'Navigation targets may reference only Page, Workbench, registered Menu Action, or DomainCommand identities.');
1943
+ if (!["page", "workbench", "menu-action", "domain-command"].includes(node.targetRef.kind)) {
1944
+ throw new DeclarativeControlCompilationError("NAV_TARGET_UNRELEASED", `nodes[${index}].targetRef.kind`, "Navigation targets may reference only Page, Workbench, registered Menu Action, or DomainCommand identities.");
1470
1945
  }
1471
1946
  const registration = targetsByStableRef.get((0, exports.stableRefKey)(node.targetRef));
1472
1947
  const released = releasedByNodeId.get(node.nodeId);
1473
1948
  const unavailable = unavailableByNodeId.get(node.nodeId);
1474
- if (!registration && unavailable && node.targetRef.kind === 'page' && (0, exports.sameStableRef)(unavailable.stableTargetRef, node.targetRef)) {
1949
+ if (!registration &&
1950
+ unavailable &&
1951
+ node.targetRef.kind === "page" &&
1952
+ (0, exports.sameStableRef)(unavailable.stableTargetRef, node.targetRef)) {
1475
1953
  assertTenantCompatible(node.targetRef, scope, `nodes[${index}].targetRef`);
1476
- if (unavailable.accessPolicy && !(0, exports.accessPolicyChainImplies)([...ancestors, node.audience], unavailable.accessPolicy)) {
1477
- throw new DeclarativeControlCompilationError('AUDIENCE_WIDER_THAN_TARGET', `nodes[${index}].audience`, 'Effective Navigation audience is wider than the last verified target audience.');
1954
+ if (unavailable.accessPolicy &&
1955
+ !(0, exports.accessPolicyChainImplies)([...ancestors, node.audience], unavailable.accessPolicy)) {
1956
+ throw new DeclarativeControlCompilationError("AUDIENCE_WIDER_THAN_TARGET", `nodes[${index}].audience`, "Effective Navigation audience is wider than the last verified target audience.");
1478
1957
  }
1479
1958
  return {
1480
1959
  ...node,
@@ -1482,84 +1961,95 @@ const compileNavigationRuntimeBundle = (input) => {
1482
1961
  parameterMapping: {},
1483
1962
  ancestorAccessPolicies: ancestors,
1484
1963
  resolvedTarget: {
1485
- kind: 'unavailable',
1964
+ kind: "unavailable",
1486
1965
  nodeId: node.nodeId,
1487
1966
  stableTargetRef: node.targetRef,
1488
1967
  accessPolicy: unavailable.accessPolicy,
1489
1968
  },
1490
1969
  };
1491
1970
  }
1492
- if (!registration || !released
1493
- || !(0, exports.sameStableRef)(registration.stableTargetRef, stableFromRevision(registration.targetRevisionRef))
1494
- || !(0, exports.sameStableRef)(registration.stableTargetRef, released.stableTargetRef)
1495
- || !(0, exports.sameRevisionRef)(registration.targetRevisionRef, released.targetRevisionRef)
1496
- || (registration.kind === 'route' && (Boolean(registration.releaseRevisionRef) !== Boolean(released.releaseRevisionRef)
1497
- || (registration.releaseRevisionRef && released.releaseRevisionRef && !(0, exports.sameRevisionRef)(registration.releaseRevisionRef, released.releaseRevisionRef))))) {
1498
- throw new DeclarativeControlCompilationError('NAV_TARGET_UNRELEASED', `nodes[${index}].targetRef`, 'Navigation target is not resolved to the exact active release recorded by NavigationRelease.');
1971
+ if (!registration ||
1972
+ !released ||
1973
+ !(0, exports.sameStableRef)(registration.stableTargetRef, stableFromRevision(registration.targetRevisionRef)) ||
1974
+ !(0, exports.sameStableRef)(registration.stableTargetRef, released.stableTargetRef) ||
1975
+ !(0, exports.sameRevisionRef)(registration.targetRevisionRef, released.targetRevisionRef) ||
1976
+ (registration.kind === "route" &&
1977
+ (Boolean(registration.releaseRevisionRef) !==
1978
+ Boolean(released.releaseRevisionRef) ||
1979
+ (registration.releaseRevisionRef &&
1980
+ released.releaseRevisionRef &&
1981
+ !(0, exports.sameRevisionRef)(registration.releaseRevisionRef, released.releaseRevisionRef))))) {
1982
+ throw new DeclarativeControlCompilationError("NAV_TARGET_UNRELEASED", `nodes[${index}].targetRef`, "Navigation target is not resolved to the exact active release recorded by NavigationRelease.");
1499
1983
  }
1500
1984
  if (registration.surface !== release.target.surface) {
1501
- throw new DeclarativeControlCompilationError('NAV_TARGET_UNRELEASED', `nodes[${index}].targetRef`, 'Navigation target is active on another surface.');
1985
+ throw new DeclarativeControlCompilationError("NAV_TARGET_UNRELEASED", `nodes[${index}].targetRef`, "Navigation target is active on another surface.");
1502
1986
  }
1503
1987
  assertTenantCompatible(registration.targetRevisionRef, scope, `nodes[${index}].targetRef`);
1504
1988
  if (!(0, exports.accessPolicyChainImplies)([...ancestors, node.audience], registration.accessPolicy)) {
1505
- throw new DeclarativeControlCompilationError('AUDIENCE_WIDER_THAN_TARGET', `nodes[${index}].audience`, 'Effective Navigation audience is wider than the target audience.');
1989
+ throw new DeclarativeControlCompilationError("AUDIENCE_WIDER_THAN_TARGET", `nodes[${index}].audience`, "Effective Navigation audience is wider than the target audience.");
1506
1990
  }
1507
1991
  const mappedInput = Object.fromEntries(Object.entries(node.parameterMapping).map(([name, source]) => {
1508
- if (source.kind !== 'constant') {
1509
- throw new DeclarativeControlCompilationError('NAV_TARGET_UNRELEASED', `nodes[${index}].parameterMapping.${name}`, 'Navigation actions accept only publication-time constant input.');
1992
+ if (source.kind !== "constant") {
1993
+ throw new DeclarativeControlCompilationError("NAV_TARGET_UNRELEASED", `nodes[${index}].parameterMapping.${name}`, "Navigation actions accept only publication-time constant input.");
1510
1994
  }
1511
1995
  return [name, source.value];
1512
1996
  }));
1513
1997
  let resolvedTarget;
1514
- if (registration.kind === 'route') {
1998
+ if (registration.kind === "route") {
1515
1999
  resolvedTarget = {
1516
2000
  ...released,
1517
- kind: 'route',
2001
+ kind: "route",
1518
2002
  accessPolicy: registration.accessPolicy,
1519
2003
  routeClaim: registration.routeClaim,
1520
2004
  };
1521
2005
  }
1522
- else if (registration.kind === 'registered-menu-action') {
2006
+ else if (registration.kind === "registered-menu-action") {
1523
2007
  if (!registration.inputSchemaRef && Object.keys(mappedInput).length > 0) {
1524
- throw new DeclarativeControlCompilationError('NAV_TARGET_UNRELEASED', `nodes[${index}].parameterMapping`, 'The registered Menu Action does not accept input.');
2008
+ throw new DeclarativeControlCompilationError("NAV_TARGET_UNRELEASED", `nodes[${index}].parameterMapping`, "The registered Menu Action does not accept input.");
1525
2009
  }
1526
2010
  let input;
1527
2011
  try {
1528
- input = common_1.JsonObjectSchema.parse(registration.validateInput ? registration.validateInput(mappedInput) : mappedInput);
2012
+ input = common_1.JsonObjectSchema.parse(registration.validateInput
2013
+ ? registration.validateInput(mappedInput)
2014
+ : mappedInput);
1529
2015
  }
1530
2016
  catch (error) {
1531
- throw new DeclarativeControlCompilationError('NAV_ACTION_INPUT_INVALID', `nodes[${index}].parameterMapping`, `Registered Menu Action input failed its active catalog schema: ${error instanceof Error ? error.message : String(error)}`);
2017
+ throw new DeclarativeControlCompilationError("NAV_ACTION_INPUT_INVALID", `nodes[${index}].parameterMapping`, `Registered Menu Action input failed its active catalog schema: ${error instanceof Error ? error.message : String(error)}`);
1532
2018
  }
1533
- const sourceDependency = release.dependencySnapshot.find((dependency) => dependency.role === 'application-menu-catalog' &&
2019
+ const sourceDependency = release.dependencySnapshot.find((dependency) => dependency.role === "application-menu-catalog" &&
1534
2020
  (0, exports.sameRevisionRef)(dependency.revisionRef, registration.sourceCatalogRevisionRef));
1535
2021
  if (!sourceDependency)
1536
- throw new DeclarativeControlCompilationError('DEPENDENCY_MISSING', `nodes[${index}].targetRef`, 'Registered Menu Action source catalog is not pinned by NavigationRelease.');
2022
+ throw new DeclarativeControlCompilationError("DEPENDENCY_MISSING", `nodes[${index}].targetRef`, "Registered Menu Action source catalog is not pinned by NavigationRelease.");
1537
2023
  resolvedTarget = {
1538
2024
  ...released,
1539
- kind: 'registered-menu-action',
2025
+ kind: "registered-menu-action",
1540
2026
  accessPolicy: registration.accessPolicy,
1541
- execution: 'client',
2027
+ execution: "client",
1542
2028
  applicationId: registration.applicationId,
1543
2029
  actionRef: registration.actionRef,
1544
- ...(registration.inputSchemaRef ? { inputSchemaRef: registration.inputSchemaRef } : {}),
2030
+ ...(registration.inputSchemaRef
2031
+ ? { inputSchemaRef: registration.inputSchemaRef }
2032
+ : {}),
1545
2033
  input,
1546
2034
  sourceCatalogRevisionRef: registration.sourceCatalogRevisionRef,
1547
2035
  };
1548
2036
  }
1549
2037
  else {
1550
- const inputDependency = release.dependencySnapshot.find((dependency) => dependency.role === 'schema' && (0, exports.sameRevisionRef)(dependency.revisionRef, registration.inputSchemaRevisionRef));
2038
+ const inputDependency = release.dependencySnapshot.find((dependency) => dependency.role === "schema" &&
2039
+ (0, exports.sameRevisionRef)(dependency.revisionRef, registration.inputSchemaRevisionRef));
1551
2040
  const resultDependency = registration.resultSchemaRevisionRef
1552
- ? release.dependencySnapshot.find((dependency) => dependency.role === 'schema' &&
2041
+ ? release.dependencySnapshot.find((dependency) => dependency.role === "schema" &&
1553
2042
  (0, exports.sameRevisionRef)(dependency.revisionRef, registration.resultSchemaRevisionRef))
1554
2043
  : undefined;
1555
- if (!inputDependency || (registration.resultSchemaRevisionRef && !resultDependency)) {
1556
- throw new DeclarativeControlCompilationError('DEPENDENCY_MISSING', `nodes[${index}].targetRef`, 'Governed DomainCommand schemas are not pinned by NavigationRelease.');
2044
+ if (!inputDependency ||
2045
+ (registration.resultSchemaRevisionRef && !resultDependency)) {
2046
+ throw new DeclarativeControlCompilationError("DEPENDENCY_MISSING", `nodes[${index}].targetRef`, "Governed DomainCommand schemas are not pinned by NavigationRelease.");
1557
2047
  }
1558
2048
  resolvedTarget = {
1559
2049
  ...released,
1560
- kind: 'governed-domain-command',
2050
+ kind: "governed-domain-command",
1561
2051
  accessPolicy: registration.accessPolicy,
1562
- execution: 'server',
2052
+ execution: "server",
1563
2053
  commandRevisionRef: registration.targetRevisionRef,
1564
2054
  inputSchemaRevisionRef: registration.inputSchemaRevisionRef,
1565
2055
  ...(registration.resultSchemaRevisionRef
@@ -1575,7 +2065,7 @@ const compileNavigationRuntimeBundle = (input) => {
1575
2065
  };
1576
2066
  });
1577
2067
  const unsigned = {
1578
- contract: 'NavigationRuntimeBundle',
2068
+ contract: "NavigationRuntimeBundle",
1579
2069
  schemaVersion: 1,
1580
2070
  tenantScope: scope,
1581
2071
  releaseRevisionRef,
@@ -1601,7 +2091,7 @@ exports.compileNavigationRuntimeBundle = compileNavigationRuntimeBundle;
1601
2091
  const validateWorkbenchRuntimeSet = (bundleInputs) => {
1602
2092
  const bundles = bundleInputs.map((bundle) => declarative_control_1.WorkbenchRuntimeBundleSchema.parse(bundle));
1603
2093
  if (bundles.length === 0) {
1604
- throw new DeclarativeControlCompilationError('WORKBENCH_RELEASE_SET_INVALID', 'bundles', 'An active Workbench release set must retain at least one Workbench.');
2094
+ throw new DeclarativeControlCompilationError("WORKBENCH_RELEASE_SET_INVALID", "bundles", "An active Workbench release set must retain at least one Workbench.");
1605
2095
  }
1606
2096
  const first = bundles[0];
1607
2097
  const seenIds = new Set();
@@ -1611,44 +2101,46 @@ const validateWorkbenchRuntimeSet = (bundleInputs) => {
1611
2101
  if (scopeKey(bundle.tenantScope) !== scopeKey(first.tenantScope) ||
1612
2102
  bundle.surface !== first.surface ||
1613
2103
  !(0, exports.sameStableRef)(bundle.target.environmentRef, first.target.environmentRef)) {
1614
- throw new DeclarativeControlCompilationError('WORKBENCH_RELEASE_SET_INVALID', `bundles[${index}]`, 'Workbench release set entries must share tenant, environment, and surface.');
2104
+ throw new DeclarativeControlCompilationError("WORKBENCH_RELEASE_SET_INVALID", `bundles[${index}]`, "Workbench release set entries must share tenant, environment, and surface.");
1615
2105
  }
1616
2106
  if (seenIds.has(bundle.workbenchId))
1617
- throw new DeclarativeControlCompilationError('WORKBENCH_RELEASE_SET_INVALID', `bundles[${index}].workbenchId`, 'Workbench identities must be unique in an active release set.');
2107
+ throw new DeclarativeControlCompilationError("WORKBENCH_RELEASE_SET_INVALID", `bundles[${index}].workbenchId`, "Workbench identities must be unique in an active release set.");
1618
2108
  if (seenOrders.has(bundle.target.order))
1619
- throw new DeclarativeControlCompilationError('WORKBENCH_RELEASE_SET_INVALID', `bundles[${index}].target.order`, 'Workbench order values must be unique in an active release set.');
2109
+ throw new DeclarativeControlCompilationError("WORKBENCH_RELEASE_SET_INVALID", `bundles[${index}].target.order`, "Workbench order values must be unique in an active release set.");
1620
2110
  seenIds.add(bundle.workbenchId);
1621
2111
  seenOrders.add(bundle.target.order);
1622
2112
  if (bundle.target.isDefaultCandidate)
1623
2113
  defaultCount += 1;
1624
2114
  });
1625
2115
  if (defaultCount > 1)
1626
- throw new DeclarativeControlCompilationError('WORKBENCH_RELEASE_SET_INVALID', 'bundles', 'An active Workbench release set may have at most one default candidate.');
1627
- return Object.freeze([...bundles].sort((left, right) => left.target.order - right.target.order || left.workbenchId.localeCompare(right.workbenchId)));
2116
+ throw new DeclarativeControlCompilationError("WORKBENCH_RELEASE_SET_INVALID", "bundles", "An active Workbench release set may have at most one default candidate.");
2117
+ return Object.freeze([...bundles].sort((left, right) => left.target.order - right.target.order ||
2118
+ left.workbenchId.localeCompare(right.workbenchId)));
1628
2119
  };
1629
2120
  exports.validateWorkbenchRuntimeSet = validateWorkbenchRuntimeSet;
1630
2121
  const resolveWorkbenchEntry = (input) => {
1631
2122
  if (input.requestedWorkbenchId) {
1632
2123
  const requested = input.bundles.find((bundle) => bundle.workbenchId === input.requestedWorkbenchId);
1633
2124
  if (!requested)
1634
- return { status: 'not-found', workbenchId: input.requestedWorkbenchId };
2125
+ return { status: "not-found", workbenchId: input.requestedWorkbenchId };
1635
2126
  if (!input.isAllowed(requested))
1636
- return { status: 'forbidden', workbenchId: input.requestedWorkbenchId };
1637
- return { status: 'resolved', bundle: requested, source: 'explicit' };
2127
+ return { status: "forbidden", workbenchId: input.requestedWorkbenchId };
2128
+ return { status: "resolved", bundle: requested, source: "explicit" };
1638
2129
  }
1639
2130
  const allowed = input.bundles
1640
2131
  .filter(input.isAllowed)
1641
- .sort((left, right) => left.target.order - right.target.order || left.workbenchId.localeCompare(right.workbenchId));
2132
+ .sort((left, right) => left.target.order - right.target.order ||
2133
+ left.workbenchId.localeCompare(right.workbenchId));
1642
2134
  const defaultBundle = allowed.find((bundle) => bundle.target.isDefaultCandidate);
1643
2135
  if (defaultBundle)
1644
- return { status: 'resolved', bundle: defaultBundle, source: 'default' };
2136
+ return { status: "resolved", bundle: defaultBundle, source: "default" };
1645
2137
  if (allowed[0])
1646
2138
  return {
1647
- status: 'resolved',
2139
+ status: "resolved",
1648
2140
  bundle: allowed[0],
1649
- source: 'first-accessible',
2141
+ source: "first-accessible",
1650
2142
  };
1651
- return { status: 'forbidden', workbenchId: '' };
2143
+ return { status: "forbidden", workbenchId: "" };
1652
2144
  };
1653
2145
  exports.resolveWorkbenchEntry = resolveWorkbenchEntry;
1654
2146
  //# sourceMappingURL=declarative-control-compiler.js.map