@xemahq/xema 0.30.0 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/dev/infra-preflight.js +1 -1
- package/dist/dev/infra-preflight.js.map +1 -1
- package/dist/edition/verify-image-evidence.bundle.mjs +2921 -2290
- package/dist/edition/verify-image-evidence.bundle.provenance.json +481 -415
- package/dist/runtime/runner/helm-cli.d.ts.map +1 -1
- package/dist/runtime/runner/helm-cli.js.map +1 -1
- package/dist/runtime/store-submit.d.ts.map +1 -1
- package/dist/runtime/store-submit.js.map +1 -1
- package/edition/README.md +2 -3
- package/edition/assemble-producer-input.mjs +1 -1
- package/edition/biome-content.mjs +6 -0
- package/edition/build-platform-service-index.mjs +2 -0
- package/edition/build-runtime-image-source-index.mjs +21 -6
- package/edition/catalogue.mjs +5 -1
- package/edition/checkout-indexed-source-repositories.mjs +41 -6
- package/edition/dispatched-runtime-components.mjs +82 -0
- package/edition/edition-protocol.mjs +2 -2
- package/edition/external-source-walk.mjs +1 -1
- package/edition/image-evidence.mjs +1 -1
- package/edition/kernel-capability-domain.mjs +30 -0
- package/edition/lib.mjs +119 -3
- package/edition/operation-grant-admission.mjs +70 -0
- package/edition/operation-requirements.mjs +128 -0
- package/edition/platform-lock-readability.mjs +2 -2
- package/edition/platform-service-class.mjs +42 -0
- package/edition/platform-service-ownership.mjs +78 -0
- package/edition/remedy-command.mjs +2 -2
- package/edition/resolve-customer-edition.mjs +4 -1
- package/edition/resolve-distribution.mjs +65 -15
- package/edition/resolve-images.mjs +65 -4
- package/edition/seal-image-digests.mjs +1 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helm-cli.d.ts","sourceRoot":"","sources":["../../../src/runtime/runner/helm-cli.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"helm-cli.d.ts","sourceRoot":"","sources":["../../../src/runtime/runner/helm-cli.ts"],"names":[],"mappings":"AAsBA,eAAO,MAAM,sBAAsB,SAAS,CAAC;AAiB7C,eAAO,MAAM,uBAAuB,kCAAkC,CAAC;AAEvE,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1C;AAED,qBAAa,OAAO;IAClB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAE7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqB;gBAEpC,IAAI,GAAE,cAAmB;IAMrC,IAAI,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAQ9C,YAAY,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAItD,OAAO,CAAC,GAAG;IAiBL,SAAS,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IASnD,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IAM7B,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC;IAS5B,iBAAiB,IAAI,OAAO,CAAC,SAAS,gBAAgB,EAAE,CAAC;IAoBzD,gBAAgB,CACpB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IA4BvC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA6B9E,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoC9D,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGhD;AAMD,oBAAY,iBAAiB;IAC3B,OAAO,YAAY;IACnB,QAAQ,aAAa;IACrB,WAAW,gBAAgB;IAC3B,UAAU,eAAe;IACzB,MAAM,WAAW;IACjB,YAAY,iBAAiB;IAC7B,cAAc,oBAAoB;IAClC,cAAc,oBAAoB;IAClC,eAAe,qBAAqB;CACrC;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;CACpC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helm-cli.js","sourceRoot":"","sources":["../../../src/runtime/runner/helm-cli.ts"],"names":[],"mappings":";;;AAAA,2DAAqD;
|
|
1
|
+
{"version":3,"file":"helm-cli.js","sourceRoot":"","sources":["../../../src/runtime/runner/helm-cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store-submit.d.ts","sourceRoot":"","sources":["../../src/runtime/store-submit.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAe,KAAK,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAI5E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAUnD,oBAAY,iBAAiB;IAC3B,MAAM,WAAW;IACjB,GAAG,QAAQ;CACZ;AAkBD,eAAO,MAAM,6BAA6B,gBAAgB,CAAC;AAG3D,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,OAAO,EAAE,MAAM;CAI5B;
|
|
1
|
+
{"version":3,"file":"store-submit.d.ts","sourceRoot":"","sources":["../../src/runtime/store-submit.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAe,KAAK,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAI5E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAUnD,oBAAY,iBAAiB;IAC3B,MAAM,WAAW;IACjB,GAAG,QAAQ;CACZ;AAkBD,eAAO,MAAM,6BAA6B,gBAAgB,CAAC;AAG3D,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,OAAO,EAAE,MAAM;CAI5B;AAiBD,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAWnE;AA+CD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AA+CD,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,kBAAkB,EAC1B,KAAK,EAAE;IACL,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B,GACA,OAAO,CAAC,YAAY,CAAC,CAavB;AAGD,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,kBAAkB,EAC1B,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE;IACL,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnD,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAC1D,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxD,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB,GACA,OAAO,CAAC,gBAAgB,CAAC,CAiB3B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store-submit.js","sourceRoot":"","sources":["../../src/runtime/store-submit.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"store-submit.js","sourceRoot":"","sources":["../../src/runtime/store-submit.ts"],"names":[],"mappings":"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"}
|
package/edition/README.md
CHANGED
|
@@ -75,8 +75,7 @@ xema edition list --editions-root <dir>
|
|
|
75
75
|
xema edition locks <id> --channel <release|develop> # validated locks as JSON; an unsealed distribution lock is read on develop only
|
|
76
76
|
xema edition artifact <id> --channel release --registry <ns> --coordinate <tag> --engine-image <repo>@sha256:<digest> --out <dir>
|
|
77
77
|
xema edition develop <freeze-sources|resolve|target|check-existing> ...
|
|
78
|
-
|
|
79
|
-
`check-overrides --overrides <json> --data-root <dir>` takes the data root only (the pin roles it judges against) and refuses every other root flag.
|
|
78
|
+
xema edition develop check-overrides --overrides <json> --data-root <dir> # data root only
|
|
80
79
|
xema edition chart-set <resolve|source-commit> ...
|
|
81
80
|
xema edition arming --channel <release|develop> --data-root <dir> --kernel <dir>
|
|
82
81
|
xema edition verify-evidence <id> --descriptor <abs path> [--json]
|
|
@@ -96,7 +95,7 @@ The edition library builds, validates and verifies evidence statements; it never
|
|
|
96
95
|
|
|
97
96
|
## Kernel protocol and pins
|
|
98
97
|
|
|
99
|
-
The CLI is coupled to the kernel's edition protocol, not to the kernel package. `@xemahq/contracts` exports the protocol identity as data (`dist/edition-protocol/edition-protocol.json`: `{contentDigest, provisional, version}`). This CLI supports exactly protocol
|
|
98
|
+
The CLI is coupled to the kernel's edition protocol, not to the kernel package. `@xemahq/contracts` exports the protocol identity as data (`dist/edition-protocol/edition-protocol.json`: `{contentDigest, provisional, version}`). This CLI supports exactly protocol v5 and REFUSES an identity with `provisional: true`; every loader that executes the kernel, `xema edition check` first, and the evidence verifier compare only that identity and refuse an unsupported one, naming the supported and the declared versions. A protocol change needs a CLI release first; only then does the data root repin its kernel authority.
|
|
100
99
|
|
|
101
100
|
- `xema edition evidence statement entitlement stage` writes entitlement predicate v2 (`lockDigest`, `catalogueDigest`, read from the edition's committed locks), so it takes `--editions-root` besides `--data-root` and `--kernel`.
|
|
102
101
|
- The runtime image source index is v2 and carries operator-stated `producerWorkflowPins` (the workflow commit a producer certificate must be signed from, per repository). `xema edition index runtime-image-source [--producer-workflow-pin <owner/repo>=<40-hex>]...` preserves the committed pins exactly; each flag sets one repository's pin (repeatable; a repeated or non-GitHub `owner/repo` is refused; only `--trusted-write` writes an index, so the flag with any other mode, `--check-sources` included, is refused); a bootstrap index with none writes `[]`. A v1 index is not read: re-index the data root.
|
|
@@ -20,6 +20,10 @@ import { execFileSync } from 'node:child_process';
|
|
|
20
20
|
import { relative, sep } from 'node:path';
|
|
21
21
|
|
|
22
22
|
import { readGitJsonAtCommit } from './lib.mjs';
|
|
23
|
+
import {
|
|
24
|
+
assertOperationGrantsAdmitted,
|
|
25
|
+
assertOrganizationSweepsAdmitted,
|
|
26
|
+
} from './operation-grant-admission.mjs';
|
|
23
27
|
|
|
24
28
|
/** A biome whose recomputed content hash is not the lock's, or whose inputs cannot be recomputed. */
|
|
25
29
|
export class BiomeContentHashError extends Error {
|
|
@@ -246,6 +250,8 @@ export async function biomeSourceTreeIds({ schemas, lock, imageLock, locate, ven
|
|
|
246
250
|
/** Seal: the unsealed lock + the recomputed hashes -> the kernel's `sealDistributionLock`. */
|
|
247
251
|
export async function sealLock({ schemas, unsealed, imageLock, locate, vendoredCommit, catalogue, catalogueDigest }) {
|
|
248
252
|
const hashes = await computeBiomeContentHashes({ schemas, lock: unsealed, imageLock, locate, vendoredCommit, catalogue, catalogueDigest });
|
|
253
|
+
assertOperationGrantsAdmitted(schemas, unsealed);
|
|
254
|
+
assertOrganizationSweepsAdmitted(schemas, unsealed);
|
|
249
255
|
return schemas.sealDistributionLock(unsealed, hashes);
|
|
250
256
|
}
|
|
251
257
|
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
import {
|
|
15
15
|
comparablePlatformService,
|
|
16
16
|
declaredInstallationClass,
|
|
17
|
+
sourceOwnedCapabilityDomains,
|
|
17
18
|
} from './platform-service-class.mjs';
|
|
18
19
|
import {
|
|
19
20
|
platformServiceSourceDeclaration,
|
|
@@ -142,6 +143,7 @@ function buildTrustedIndex(sourceAuthority) {
|
|
|
142
143
|
name: declaration.name,
|
|
143
144
|
tier: declaration.tier,
|
|
144
145
|
...declaredInstallationClass(declaration),
|
|
146
|
+
...sourceOwnedCapabilityDomains(sourceManifest, `${binding.path} at ${before}`),
|
|
145
147
|
repositoryUrl,
|
|
146
148
|
repo: binding.repo,
|
|
147
149
|
path: binding.path,
|
|
@@ -204,6 +204,10 @@ function assertVendoredSourcesResolve(crossRepoBuildInputs, resolveIdentity) {
|
|
|
204
204
|
}
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
+
const LEGACY_INDEX_SCHEMA_VERSION = 1;
|
|
208
|
+
const CURRENT_INDEX_SCHEMA_VERSION = 2;
|
|
209
|
+
const KNOWN_INDEX_SCHEMA_VERSIONS = Object.freeze([LEGACY_INDEX_SCHEMA_VERSION, CURRENT_INDEX_SCHEMA_VERSION]);
|
|
210
|
+
|
|
207
211
|
/**
|
|
208
212
|
* The kernel-contract authority for a pin regeneration.
|
|
209
213
|
*
|
|
@@ -250,13 +254,24 @@ function assertVendoredSourcesResolve(crossRepoBuildInputs, resolveIdentity) {
|
|
|
250
254
|
* rule — the caller states the commit (`--kernel-commit`) and the checkout's
|
|
251
255
|
* HEAD must equal it. Stating a commit when a committed authority exists is
|
|
252
256
|
* refused: it would be read by nobody.
|
|
257
|
+
*
|
|
258
|
+
* A committed index of schemaVersion 1 carries an authority a current kernel
|
|
259
|
+
* cannot validate, so it counts as having NO committed authority: it is
|
|
260
|
+
* migrated by bootstrap, which writes a schemaVersion 2 index. Any other
|
|
261
|
+
* schemaVersion is refused by name, never read as one of these.
|
|
253
262
|
*/
|
|
254
263
|
async function resolveContractAuthority(schemas, kernelRoot, kernelCommit) {
|
|
255
264
|
const repositoryDirectory = kernelRoot ?? undefined;
|
|
256
265
|
const committed = existsSync(runtimeImageSourceIndexPath())
|
|
257
266
|
? readJson(runtimeImageSourceIndexPath())
|
|
258
267
|
: undefined;
|
|
259
|
-
if (!committed
|
|
268
|
+
if (committed !== undefined && !KNOWN_INDEX_SCHEMA_VERSIONS.includes(committed.schemaVersion)) {
|
|
269
|
+
throw new Error(
|
|
270
|
+
`${runtimeImageSourceIndexPath()} has schemaVersion ${JSON.stringify(committed.schemaVersion)}; ` +
|
|
271
|
+
`this command reads ${KNOWN_INDEX_SCHEMA_VERSIONS.join(' or ')}`,
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
if (committed === undefined || committed.schemaVersion === LEGACY_INDEX_SCHEMA_VERSION || !committed.contractAuthority) {
|
|
260
275
|
return buildTrustedKernelContractAuthority({
|
|
261
276
|
...(repositoryDirectory === undefined ? {} : { repositoryDirectory }),
|
|
262
277
|
schemas,
|
|
@@ -487,7 +502,7 @@ export async function buildTrustedIndex(
|
|
|
487
502
|
const repositoryPins = [...sourceRepos]
|
|
488
503
|
.sort(compareStrings)
|
|
489
504
|
.map(getRepositoryIdentity);
|
|
490
|
-
const
|
|
505
|
+
const sortedCrossRepoBuildInputs = [...crossRepoBuildInputs()].sort(
|
|
491
506
|
(left, right) =>
|
|
492
507
|
compareStrings(
|
|
493
508
|
[left.consumerRepo, left.consumerService, left.destinationPath].join(
|
|
@@ -498,7 +513,7 @@ export async function buildTrustedIndex(
|
|
|
498
513
|
),
|
|
499
514
|
),
|
|
500
515
|
);
|
|
501
|
-
assertVendoredSourcesResolve(
|
|
516
|
+
assertVendoredSourcesResolve(sortedCrossRepoBuildInputs, getRepositoryIdentity);
|
|
502
517
|
const buildStepContextDirectories = [...buildStepContextDirectoriesDeclared()].sort(
|
|
503
518
|
(left, right) =>
|
|
504
519
|
compareStrings(
|
|
@@ -514,7 +529,7 @@ export async function buildTrustedIndex(
|
|
|
514
529
|
);
|
|
515
530
|
}
|
|
516
531
|
}
|
|
517
|
-
for (const input of
|
|
532
|
+
for (const input of sortedCrossRepoBuildInputs) {
|
|
518
533
|
for (const repo of [input.consumerRepo, input.sourceRepo]) {
|
|
519
534
|
if (!sourceRepos.has(repo)) {
|
|
520
535
|
throw new Error(
|
|
@@ -525,10 +540,10 @@ export async function buildTrustedIndex(
|
|
|
525
540
|
}
|
|
526
541
|
}
|
|
527
542
|
return {
|
|
528
|
-
schemaVersion:
|
|
543
|
+
schemaVersion: CURRENT_INDEX_SCHEMA_VERSION,
|
|
529
544
|
contractAuthority,
|
|
530
545
|
supplementalSubjects,
|
|
531
|
-
crossRepoBuildInputs,
|
|
546
|
+
crossRepoBuildInputs: sortedCrossRepoBuildInputs,
|
|
532
547
|
buildStepContextDirectories,
|
|
533
548
|
repositoryPins,
|
|
534
549
|
producerWorkflowPins: mergeProducerWorkflowPins(
|
package/edition/catalogue.mjs
CHANGED
|
@@ -14,6 +14,7 @@ import { join } from 'node:path';
|
|
|
14
14
|
import { assertCanonicalDistributionId } from './distribution-paths.mjs';
|
|
15
15
|
import { EDITION_OFFERING_LAYERS, EditionChannel } from './edition-constants.mjs';
|
|
16
16
|
import { serializeJson } from './lib.mjs';
|
|
17
|
+
import { verifiedPlatformServiceIndex } from './platform-service-ownership.mjs';
|
|
17
18
|
|
|
18
19
|
export const CATALOGUE_FILE = EDITION_OFFERING_LAYERS.catalogue;
|
|
19
20
|
export const CATALOGUE_SCHEMA = 'xema.edition-catalogue/v1';
|
|
@@ -109,6 +110,7 @@ export function buildCatalogue({
|
|
|
109
110
|
kernel,
|
|
110
111
|
leaf,
|
|
111
112
|
sourceTreeIds,
|
|
113
|
+
readManifest,
|
|
112
114
|
}) {
|
|
113
115
|
const sourced = distributionLock.biomes.filter((biome) => biome.source !== undefined);
|
|
114
116
|
if (sourced.length > 0) {
|
|
@@ -119,7 +121,9 @@ export function buildCatalogue({
|
|
|
119
121
|
const biomes = biomeIndex.filter((row) => shippedBiomes.has(row.id));
|
|
120
122
|
const missing = [...shippedBiomes].filter((id) => !biomes.some((row) => row.id === id));
|
|
121
123
|
if (missing.length > 0) {throw new CatalogueError(`offering "${offeringId}": the biome index has no row for ${missing.join(', ')}`);}
|
|
122
|
-
|
|
124
|
+
// The customer trusts this catalogue's ownership rows without sources, so they are
|
|
125
|
+
// re-derived from the pinned manifests here, before the catalogue seals.
|
|
126
|
+
const platformServices = verifiedPlatformServiceIndex(platformServiceIndex, { names: shippedServices, readManifest }).services.filter((row) => shippedServices.has(row.name));
|
|
123
127
|
return parseCatalogue({
|
|
124
128
|
schema: CATALOGUE_SCHEMA,
|
|
125
129
|
offeringId,
|
|
@@ -5,7 +5,7 @@ import { existsSync, mkdirSync, readFileSync } from 'node:fs';
|
|
|
5
5
|
import { dirname, resolve } from 'node:path';
|
|
6
6
|
|
|
7
7
|
import { editionWorkspaceConfig } from './edition-config.mjs';
|
|
8
|
-
import { WorkspaceRoot, configureEditionWorkspaceFromProcess, isEntryModule, runtimeImageSourceIndexPath, sourcesRoot } from './edition-workspace.mjs';
|
|
8
|
+
import { WorkspaceRoot, configureEditionWorkspaceFromProcess, isEntryModule, platformServiceIndexPath, runtimeImageSourceIndexPath, sourcesRoot } from './edition-workspace.mjs';
|
|
9
9
|
import { holdSource, withSourceGitEnv } from './git-source-auth.mjs';
|
|
10
10
|
import { applyPinSource, snapshotPinSource } from './pin-source.mjs';
|
|
11
11
|
import { readStrictJsonFile } from './strict-json.mjs';
|
|
@@ -45,10 +45,40 @@ function git(args, env) {
|
|
|
45
45
|
execFileSync('git', args, { env, stdio: 'inherit' });
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
/**
|
|
49
|
+
* The extra commits each checkout must also hold: resolve reads every platform
|
|
50
|
+
* service's manifest at the `sourceCommit` platform-service-index.json pins, and
|
|
51
|
+
* that commit may differ from the repository's own pin. Maps repo to the
|
|
52
|
+
* distinct such commits (excluding the pinned one). A platform service whose
|
|
53
|
+
* repository has no pin is refused: there is no checkout to fetch into.
|
|
54
|
+
*/
|
|
55
|
+
export function platformServiceExtraCommits(plan, platformServiceIndex) {
|
|
56
|
+
if (!Array.isArray(platformServiceIndex?.services)) {
|
|
57
|
+
throw new Error('platform-service-index.json declares no services array');
|
|
58
|
+
}
|
|
59
|
+
const pinned = new Map(plan.map((entry) => [entry.repo, entry.sourceCommit]));
|
|
60
|
+
const extra = new Map();
|
|
61
|
+
for (const service of platformServiceIndex.services) {
|
|
62
|
+
if (!pinned.has(service?.repo)) {
|
|
63
|
+
throw new Error(
|
|
64
|
+
`platform service "${service?.name}" names repository ${JSON.stringify(service?.repo)}, which has no repository pin in the runtime image source index`,
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
if (!SHA.test(String(service.sourceCommit ?? ''))) {
|
|
68
|
+
throw new Error(`platform service "${service.name}" sourceCommit is not exact lowercase 40-hex`);
|
|
69
|
+
}
|
|
70
|
+
if (service.sourceCommit === pinned.get(service.repo)) {continue;}
|
|
71
|
+
if (!extra.has(service.repo)) {extra.set(service.repo, new Set());}
|
|
72
|
+
extra.get(service.repo).add(service.sourceCommit);
|
|
73
|
+
}
|
|
74
|
+
return new Map([...extra].map(([repo, commits]) => [repo, [...commits]]));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function checkoutIndexedSources({ workspaceRoot, index, platformServiceIndex, env = process.env, runGit = git }) {
|
|
49
78
|
if (!workspaceRoot) {throw new Error('workspaceRoot is required');}
|
|
50
79
|
const workspace = editionWorkspaceConfig();
|
|
51
80
|
const plan = sourceCheckoutPlan(index, workspace);
|
|
81
|
+
const extraCommits = platformServiceExtraCommits(plan, platformServiceIndex);
|
|
52
82
|
for (const entry of plan) {holdSource({ name: entry.repo, url: entry.repositoryUrl }, workspace, env);}
|
|
53
83
|
for (const entry of plan) {
|
|
54
84
|
const target = resolve(workspaceRoot, entry.repo);
|
|
@@ -57,10 +87,10 @@ export function checkoutIndexedSources({ workspaceRoot, index, env = process.env
|
|
|
57
87
|
}
|
|
58
88
|
withSourceGitEnv({ name: entry.repo, url: entry.repositoryUrl }, { workspace, env }, (gitEnv) => {
|
|
59
89
|
mkdirSync(dirname(target), { recursive: true });
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
90
|
+
runGit(['init', '--quiet', target], gitEnv);
|
|
91
|
+
runGit(['-C', target, 'remote', 'add', 'origin', entry.repositoryUrl], gitEnv);
|
|
92
|
+
runGit(['-C', target, 'fetch', '--quiet', '--depth=1', 'origin', entry.sourceCommit], gitEnv);
|
|
93
|
+
runGit(['-C', target, 'checkout', '--quiet', '--detach', entry.sourceCommit], gitEnv);
|
|
64
94
|
const actual = execFileSync('git', ['-C', target, 'rev-parse', 'HEAD'], {
|
|
65
95
|
env: gitEnv,
|
|
66
96
|
encoding: 'utf8',
|
|
@@ -68,6 +98,10 @@ export function checkoutIndexedSources({ workspaceRoot, index, env = process.env
|
|
|
68
98
|
if (actual !== entry.sourceCommit) {
|
|
69
99
|
throw new Error(`${entry.repo} resolved ${actual}, expected ${entry.sourceCommit}`);
|
|
70
100
|
}
|
|
101
|
+
for (const commit of extraCommits.get(entry.repo) ?? []) {
|
|
102
|
+
runGit(['-C', target, 'fetch', '--quiet', '--depth=1', 'origin', commit], gitEnv);
|
|
103
|
+
console.log(`[source-checkout] ${entry.repo} also holds platform-service commit ${commit}`);
|
|
104
|
+
}
|
|
71
105
|
});
|
|
72
106
|
console.log(`[source-checkout] ${entry.repo} @ ${entry.sourceCommit}`);
|
|
73
107
|
}
|
|
@@ -96,6 +130,7 @@ if (isEntryModule(import.meta.url)) {
|
|
|
96
130
|
const count = checkoutIndexedSources({
|
|
97
131
|
workspaceRoot: sourcesRoot(),
|
|
98
132
|
index,
|
|
133
|
+
platformServiceIndex: JSON.parse(readFileSync(platformServiceIndexPath(), 'utf8')),
|
|
99
134
|
});
|
|
100
135
|
console.log(`[source-checkout] materialized ${count} indexed repositories at exact commits`);
|
|
101
136
|
} catch (error) {
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { compareStrings } from './string-order.mjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The runtime components an edition must carry because a biome it rosters
|
|
5
|
+
* DISPATCHES them: the kernel's `runtime-image` edges, projected per biome into
|
|
6
|
+
* the index as `dispatchesRuntimeComponents` and followed here against the
|
|
7
|
+
* index entry of each target biome.
|
|
8
|
+
*
|
|
9
|
+
* "Needs that image" and nothing else. The target biome is NOT rostered — it is
|
|
10
|
+
* not installed, booted or required — only its runtime component's image
|
|
11
|
+
* enters the edition, as a runtime-component row of the image lock.
|
|
12
|
+
*
|
|
13
|
+
* The closure is one step by construction: the kernel admits
|
|
14
|
+
* `dispatchesRuntimeComponents` on a `service` component only, and a target is
|
|
15
|
+
* a runtime component, which is never a standing service — so a dispatched
|
|
16
|
+
* image dispatches nothing further, and an unrostered target biome's own
|
|
17
|
+
* services (and their edges) are not in the edition at all.
|
|
18
|
+
*
|
|
19
|
+
* Targets are resolved against FIRST-PARTY server entries only: the image plane
|
|
20
|
+
* reads a target's coordinates from the first-party biome index, which carries
|
|
21
|
+
* no biome drawn from a declared source. A biome drawn from a declared source
|
|
22
|
+
* that dispatches is refused for the same reason.
|
|
23
|
+
*
|
|
24
|
+
* Returns one row per distinct (target biome, component key), sorted, with the
|
|
25
|
+
* rostered biomes that dispatch it. Every unresolvable edge is refused, naming
|
|
26
|
+
* the consumer and the target.
|
|
27
|
+
*
|
|
28
|
+
* @param {string} context the edition the refusal names, e.g. `distribution "core"`
|
|
29
|
+
* @param {object[]} consumers the rostered index entries
|
|
30
|
+
* @param {object[]} index the index the targets are resolved against
|
|
31
|
+
*/
|
|
32
|
+
export function resolveDispatchedRuntimeComponents(context, consumers, index) {
|
|
33
|
+
const rows = new Map();
|
|
34
|
+
for (const consumer of [...consumers].sort((a, b) => compareStrings(a.id, b.id))) {
|
|
35
|
+
const edges = consumer.dispatchesRuntimeComponents ?? [];
|
|
36
|
+
if (edges.length === 0) {continue;}
|
|
37
|
+
if (consumer.source !== undefined) {
|
|
38
|
+
throw new Error(
|
|
39
|
+
`${context}: biome "${consumer.id}", drawn from declared source "${consumer.source}", dispatches ` +
|
|
40
|
+
`runtime components (${edges.map((edge) => `${edge.biomeId}/${edge.componentKey}`).join(', ')}). ` +
|
|
41
|
+
'A dispatched image is resolved from the first-party biome index, which carries no biome from a ' +
|
|
42
|
+
'declared source — refusing rather than shipping the dispatcher without the images it launches.',
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
for (const edge of edges) {
|
|
46
|
+
const edgeText = `biome "${consumer.id}" dispatches runtime component "${edge.componentKey}" of biome "${edge.biomeId}"`;
|
|
47
|
+
const candidates = index.filter(
|
|
48
|
+
(entry) => entry.id === edge.biomeId && entry.target === 'server' && entry.source === undefined,
|
|
49
|
+
);
|
|
50
|
+
if (candidates.length === 0) {
|
|
51
|
+
throw new Error(
|
|
52
|
+
`${context}: ${edgeText}, but the biome index has no first-party server biome "${edge.biomeId}" — ` +
|
|
53
|
+
'refusing rather than shipping the dispatcher without the image it launches.',
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
if (candidates.length > 1) {
|
|
57
|
+
throw new Error(
|
|
58
|
+
`${context}: ${edgeText}, but the biome index has ${candidates.length} first-party server biomes ` +
|
|
59
|
+
`"${edge.biomeId}" (${candidates.map((entry) => entry.repo).join(', ')}), so the target is ambiguous.`,
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
const [target] = candidates;
|
|
63
|
+
const image = (target.runtimeComponentKeys ?? {})[edge.componentKey];
|
|
64
|
+
if (image === undefined) {
|
|
65
|
+
const keys = Object.keys(target.runtimeComponentKeys ?? {});
|
|
66
|
+
throw new Error(
|
|
67
|
+
`${context}: ${edgeText}, but "${edge.biomeId}" declares no runtime component keyed ` +
|
|
68
|
+
`"${edge.componentKey}" (its runtime components: ${keys.length > 0 ? keys.join(', ') : 'none'}). ` +
|
|
69
|
+
'Either no component has that key, or it is a standing service or worker — a dispatched ' +
|
|
70
|
+
'component must be one its own biome never schedules.',
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
const key = `${target.id}\0${edge.componentKey}`;
|
|
74
|
+
const row = rows.get(key) ?? { target, componentKey: edge.componentKey, image, consumers: [] };
|
|
75
|
+
if (!row.consumers.includes(consumer.id)) {row.consumers.push(consumer.id);}
|
|
76
|
+
rows.set(key, row);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return [...rows.entries()]
|
|
80
|
+
.sort(([a], [b]) => compareStrings(a, b))
|
|
81
|
+
.map(([, row]) => row);
|
|
82
|
+
}
|
|
@@ -31,8 +31,8 @@ import { readBoundedNoFollowFile } from './no-follow-file.mjs';
|
|
|
31
31
|
/** The edition protocols this library interprets: version -> content digest. */
|
|
32
32
|
export const SUPPORTED_EDITION_PROTOCOLS = Object.freeze([
|
|
33
33
|
Object.freeze({
|
|
34
|
-
version:
|
|
35
|
-
contentDigest: '
|
|
34
|
+
version: 5,
|
|
35
|
+
contentDigest: '326d8b62ba87073fa91cf726eb596f9371904f056db688729d8800cc94c2d646',
|
|
36
36
|
}),
|
|
37
37
|
]);
|
|
38
38
|
|
|
@@ -376,7 +376,7 @@ function lockedSourceRecord(source, commit) {
|
|
|
376
376
|
// DistributionLockSchema is `.strict()` and only learned this key in 0.10.0,
|
|
377
377
|
// so any pinned image resolving `^0.9.x` REFUSES THE WHOLE LOCK at boot —
|
|
378
378
|
// `Unrecognized key: "imageNamePrefix"`, before Nest starts. That took
|
|
379
|
-
//
|
|
379
|
+
// a customer environment's three lock consumers down on 2026-09-17 and was fixed by
|
|
380
380
|
// removing the key from the SEALED LOCK, leaving this line to re-emit it on
|
|
381
381
|
// the next resolve. A workaround standing where a fix belongs removes the
|
|
382
382
|
// signal; this is the fix.
|
|
@@ -1082,7 +1082,7 @@ async function verifyImageDeliveryEntitlementWithCosign({
|
|
|
1082
1082
|
* `submodules/…` repository the vendor builds images from. A customer edition
|
|
1083
1083
|
* additionally draws biomes from sources declared in its own manifest
|
|
1084
1084
|
* (`sources[]`, `kind: git`), and the images built from those have a `repo`
|
|
1085
|
-
* the index has never heard of and never will:
|
|
1085
|
+
* the index has never heard of and never will: `<customer>-biomes`, not
|
|
1086
1086
|
* `repos/xema-base`. Without a pin for it every such subject is refused as
|
|
1087
1087
|
* "has no committed repository pin", so a customer could verify the vendor's
|
|
1088
1088
|
* images in its edition and never its own.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
|
|
3
|
+
import { kernelDistPath } from './edition-workspace.mjs';
|
|
4
|
+
|
|
5
|
+
const requireFromHere = createRequire(import.meta.url);
|
|
6
|
+
|
|
7
|
+
let schema;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Is `value` a capability domain? The kernel's `CapabilityDomainSchema` is the
|
|
11
|
+
* ONE grammar; it is read from the distribution subpath, the only plane the
|
|
12
|
+
* edition protocol exposes to this library. Nothing here restates the pattern.
|
|
13
|
+
*
|
|
14
|
+
* @param {unknown} value
|
|
15
|
+
* @returns {boolean}
|
|
16
|
+
*/
|
|
17
|
+
export function isKernelCapabilityDomain(value) {
|
|
18
|
+
if (schema === undefined) {
|
|
19
|
+
const path = kernelDistPath('distribution', 'index.js');
|
|
20
|
+
const mod = requireFromHere(path);
|
|
21
|
+
if (typeof mod.CapabilityDomainSchema?.safeParse !== 'function') {
|
|
22
|
+
throw new Error(
|
|
23
|
+
`Built kernel distribution module at ${path} does not export CapabilityDomainSchema — ` +
|
|
24
|
+
'the dist is stale; rebuild kernel-contracts at a commit that carries it.',
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
schema = mod.CapabilityDomainSchema;
|
|
28
|
+
}
|
|
29
|
+
return schema.safeParse(value).success;
|
|
30
|
+
}
|