@xemahq/xema 0.45.1 → 0.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/commands/biome.d.ts.map +1 -1
  2. package/dist/commands/biome.js +3 -0
  3. package/dist/commands/biome.js.map +1 -1
  4. package/dist/edition/verify-image-evidence.bundle.mjs +1613 -846
  5. package/dist/edition/verify-image-evidence.bundle.provenance.json +516 -474
  6. package/dist/runtime/biome-publish-image-layers.d.ts +20 -0
  7. package/dist/runtime/biome-publish-image-layers.d.ts.map +1 -0
  8. package/dist/runtime/biome-publish-image-layers.js +64 -0
  9. package/dist/runtime/biome-publish-image-layers.js.map +1 -0
  10. package/dist/runtime/biome-publish.d.ts +4 -0
  11. package/dist/runtime/biome-publish.d.ts.map +1 -1
  12. package/dist/runtime/biome-publish.js +25 -5
  13. package/dist/runtime/biome-publish.js.map +1 -1
  14. package/dist/runtime/config/schema.d.ts +4 -3
  15. package/dist/runtime/config/schema.d.ts.map +1 -1
  16. package/dist/runtime/config/schema.js +8 -2
  17. package/dist/runtime/config/schema.js.map +1 -1
  18. package/dist/runtime/installation/contract.d.ts +2 -2
  19. package/dist/runtime/installation/contract.d.ts.map +1 -1
  20. package/dist/runtime/installation/contract.js +1 -1
  21. package/dist/runtime/installation/contract.js.map +1 -1
  22. package/edition/README.md +2 -1
  23. package/edition/assemble-producer-input.mjs +2 -0
  24. package/edition/biome-content.mjs +6 -0
  25. package/edition/build-platform-service-index.mjs +2 -0
  26. package/edition/canonical-repository-url.mjs +12 -0
  27. package/edition/cosign-certificate-constraints.mjs +40 -0
  28. package/edition/customer-edition-verbs.mjs +6 -0
  29. package/edition/develop-coverage-readers.mjs +6 -4
  30. package/edition/develop-edition.mjs +20 -0
  31. package/edition/develop-record-ancestry.mjs +121 -0
  32. package/edition/develop-select-records.mjs +365 -0
  33. package/edition/distribution-evidence-set.mjs +14 -2
  34. package/edition/edition-config.mjs +27 -1
  35. package/edition/edition-protocol.mjs +8 -1
  36. package/edition/image-evidence.mjs +2 -12
  37. package/edition/kernel-signer-kind.mjs +23 -0
  38. package/edition/lib.mjs +104 -2
  39. package/edition/oci-evidence-verbs.mjs +2 -2
  40. package/edition/oci-image-source-evidence.mjs +84 -39
  41. package/edition/operation-grant-admission.mjs +98 -4
  42. package/edition/operation-requirements.mjs +118 -4
  43. package/edition/plan-image-evidence-refresh.mjs +20 -6
  44. package/edition/platform-service-class.mjs +23 -0
  45. package/edition/platform-service-ownership.mjs +23 -13
  46. package/edition/produce-distribution-completeness-evidence.mjs +2 -0
  47. package/edition/produce-image-source-evidence.mjs +9 -11
  48. package/edition/producer-evidence-bundle.mjs +12 -1
  49. package/edition/record-refused.mjs +11 -0
  50. package/edition/resolve-distribution.mjs +43 -1
  51. package/package.json +3 -3
@@ -83,6 +83,7 @@ import { walkDeclaredSources } from './external-source-walk.mjs';
83
83
  import {
84
84
  biomeTierOrder,
85
85
  assertDeclaredDatabasesUnowned,
86
+ buildAudienceNamespaceOwners,
86
87
  buildCapabilityDomainOwners,
87
88
  compareIndexEntries,
88
89
  loadKernelBiomeContracts,
@@ -97,7 +98,10 @@ import {
97
98
  import {
98
99
  assertInstalledOperationCeilingAdmitted,
99
100
  assertOperationGrantsAdmitted,
101
+ assertExactAudiencesAdmitted,
100
102
  assertOrganizationSweepsAdmitted,
103
+ assertEventSubscriptionsAdmitted,
104
+ assertOrgContextRelaysAdmitted,
101
105
  assertStoreWorkloadCeilingAdmitted,
102
106
  } from './operation-grant-admission.mjs';
103
107
  import { PUBLISHED_PIN_SOURCE, pinnedSource } from './pin-source.mjs';
@@ -310,6 +314,7 @@ export function composeManifest(manifest, pinSource = PUBLISHED_PIN_SOURCE) {
310
314
  // reduces the declarations.
311
315
  declaredVisibilities: manifest.visibility === undefined ? [] : [manifest.visibility],
312
316
  storeWorkloadCeiling: manifest.storeWorkloadCeiling,
317
+ storeEventCeiling: manifest.storeEventCeiling,
313
318
  declaredSourceNames: new Set(sources.map((source) => source.name)),
314
319
  declaredSources: sources.map((source) => pinnedSource(source, pinSource)),
315
320
  owner: manifest.owner,
@@ -1163,6 +1168,7 @@ export function resolveDistributionFromInputs(
1163
1168
  trustCeiling,
1164
1169
  declaredVisibilities,
1165
1170
  storeWorkloadCeiling,
1171
+ storeEventCeiling,
1166
1172
  owner,
1167
1173
  leaf,
1168
1174
  // Absent on a selector-model composition — including every `composed` a
@@ -2058,12 +2064,29 @@ export function resolveDistributionFromInputs(
2058
2064
  Object.keys(e.installedOperationRequests).length > 0
2059
2065
  ? { installedOperationRequests: e.installedOperationRequests }
2060
2066
  : {}),
2067
+ // The workload components that relay an organization context, forwarded
2068
+ // verbatim; the lock admits them (`admitOrgContextRelays`).
2069
+ ...(e.orgContextRelayers !== undefined && e.orgContextRelayers.length > 0
2070
+ ? { orgContextRelayers: e.orgContextRelayers }
2071
+ : {}),
2072
+ // The event subscription clauses each workload component declares,
2073
+ // forwarded verbatim; the lock admits them (`admitEventSubscriptions`).
2074
+ ...(e.eventSubscriptionRequirements !== undefined &&
2075
+ Object.keys(e.eventSubscriptionRequirements).length > 0
2076
+ ? { eventSubscriptionRequirements: e.eventSubscriptionRequirements }
2077
+ : {}),
2061
2078
  // The organization sweeps each workload component may hold, forwarded
2062
2079
  // verbatim; the seal admits them (`admitOrganizationSweeps`).
2063
2080
  ...(e.organizationSweepRequirements !== undefined &&
2064
2081
  Object.keys(e.organizationSweepRequirements).length > 0
2065
2082
  ? { organizationSweepRequirements: e.organizationSweepRequirements }
2066
2083
  : {}),
2084
+ // The exact audiences each workload component requires, forwarded
2085
+ // verbatim; the seal admits them (`admitExactAudiences`).
2086
+ ...(e.audienceRequirements !== undefined &&
2087
+ Object.keys(e.audienceRequirements).length > 0
2088
+ ? { audienceRequirements: e.audienceRequirements }
2089
+ : {}),
2067
2090
  // --- Catalog projection (consumed by biome-host's DistributionCatalogSource) ---
2068
2091
  // Forwarded verbatim from the index so the lock is the SELF-CONTAINED
2069
2092
  // single source of truth for the biome catalog: biome-host builds the
@@ -2140,6 +2163,12 @@ export function resolveDistributionFromInputs(
2140
2163
  ...(source.ownsCapabilityDomains === undefined
2141
2164
  ? {}
2142
2165
  : { ownsCapabilityDomains: source.ownsCapabilityDomains }),
2166
+ // The service's own requirement and ownership declarations, likewise
2167
+ // verbatim from the index row: `admitOperationGrants` and
2168
+ // `admitExactAudiences` read them from the lock.
2169
+ ...(source.requiresOperations === undefined ? {} : { requiresOperations: source.requiresOperations }),
2170
+ ...(source.requiresAudiences === undefined ? {} : { requiresAudiences: source.requiresAudiences }),
2171
+ ...(source.ownsAudienceNamespaces === undefined ? {} : { ownsAudienceNamespaces: source.ownsAudienceNamespaces }),
2143
2172
  source,
2144
2173
  };
2145
2174
  })
@@ -2157,6 +2186,7 @@ export function resolveDistributionFromInputs(
2157
2186
  // owning biome from the store and then bind its refs to a URL they control.
2158
2187
  // See `buildCapabilityDomainOwners`. Throws on a duplicate claim.
2159
2188
  const capabilityDomainOwners = buildCapabilityDomainOwners(index);
2189
+ const audienceNamespaceOwners = buildAudienceNamespaceOwners(index);
2160
2190
 
2161
2191
  // inputHash: deterministic over the index SUBSET that fed the lock + the
2162
2192
  // reservation table + the leaf manifest, so drift in any input is detectable.
@@ -2164,8 +2194,11 @@ export function resolveDistributionFromInputs(
2164
2194
  const platform = serializeJson(platformServiceList);
2165
2195
  const owners = serializeJson(capabilityDomainOwners);
2166
2196
  const manifestImg = serializeJson(leaf);
2197
+ // The audience-namespace owners are derived from the WHOLE index, so a claim change in an unselected
2198
+ // biome is drift. Appended only when non-empty: an edition with none keeps the hash it always had.
2199
+ const audienceOwners = audienceNamespaceOwners.length > 0 ? `\0${serializeJson(audienceNamespaceOwners)}` : '';
2167
2200
  const inputHash = sha256Hex(
2168
- `${subset}\0${platform}\0${owners}\0${manifestImg}`,
2201
+ `${subset}\0${platform}\0${owners}\0${manifestImg}${audienceOwners}`,
2169
2202
  );
2170
2203
 
2171
2204
  const lock = {
@@ -2181,6 +2214,9 @@ export function resolveDistributionFromInputs(
2181
2214
  resolvedAt,
2182
2215
  inputHash,
2183
2216
  };
2217
+ // Appended after `inputHash` and only when a biome owns a namespace, like
2218
+ // `owner` below: an unconditional key would change the bytes of every lock.
2219
+ if (audienceNamespaceOwners.length > 0) {lock.audienceNamespaceOwners = audienceNamespaceOwners;}
2184
2220
 
2185
2221
  // Owner and visibility are written ONLY when something declared them, and
2186
2222
  // they are appended AFTER `inputHash` rather than woven into the literal
@@ -2216,6 +2252,9 @@ export function resolveDistributionFromInputs(
2216
2252
  // The edition's store-workload ceiling — written ONLY when the edition
2217
2253
  // declares one (the kernel refuses an empty list), carried unchanged.
2218
2254
  if (storeWorkloadCeiling !== undefined) {lock.storeWorkloadCeiling = storeWorkloadCeiling;}
2255
+ // The edition's store event ceiling — written ONLY when the edition declares
2256
+ // one (the kernel refuses an empty list), carried unchanged.
2257
+ if (storeEventCeiling !== undefined) {lock.storeEventCeiling = storeEventCeiling;}
2219
2258
 
2220
2259
  // (7) Re-derive the ownership index through the KERNEL so the table this
2221
2260
  // resolver emits is validated by the exact code every consumer will read
@@ -2235,6 +2274,9 @@ export function resolveDistributionFromInputs(
2235
2274
  // never fails (the resolve and `edition check` both run through here).
2236
2275
  assertOperationGrantsAdmitted(schemas, parsed, { report: (line) => console.log(`[operations] ${line}`) });
2237
2276
  assertOrganizationSweepsAdmitted(schemas, parsed);
2277
+ assertExactAudiencesAdmitted(schemas, parsed);
2278
+ assertOrgContextRelaysAdmitted(schemas, parsed);
2279
+ assertEventSubscriptionsAdmitted(schemas, parsed);
2238
2280
  assertInstalledOperationCeilingAdmitted(schemas, parsed);
2239
2281
  assertStoreWorkloadCeilingAdmitted(schemas, parsed);
2240
2282
  return validateImmutableDistributionLock(lock);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xemahq/xema",
3
- "version": "0.45.1",
3
+ "version": "0.46.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/xema-dev/xema-cli.git",
@@ -54,7 +54,7 @@
54
54
  "@xemahq/distribution-source-hash": "^0.2.2",
55
55
  "@xemahq/dsl": "^0.24.0",
56
56
  "@xemahq/identity-client": "^0.16.0",
57
- "@xemahq/contracts": "^0.102.0",
57
+ "@xemahq/contracts": "^0.110.0",
58
58
  "@xemahq/kernel-state-runtime": "^0.8.0",
59
59
  "@xemahq/license-verifier": "^0.2.0",
60
60
  "@xemahq/service-registry-nest": "^0.12.2",
@@ -92,6 +92,6 @@
92
92
  "typecheck": "tsc --noEmit"
93
93
  },
94
94
  "xemaRelease": {
95
- "sourceDigest": "sha256:04abcd3c081c6cd50d0133c543310f75801357071b18834ec4b15af587760461"
95
+ "sourceDigest": "sha256:184f63317ecd8173e0fd3122d80aca617832209e5221bd8d984ec9c5eff5ef6c"
96
96
  }
97
97
  }