@xemahq/xema 0.41.1 → 0.43.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/commands/edition.d.ts.map +1 -1
- package/dist/commands/edition.js +2 -1
- package/dist/commands/edition.js.map +1 -1
- package/dist/edition/verify-image-evidence.bundle.mjs +1289 -840
- package/dist/edition/verify-image-evidence.bundle.provenance.json +494 -458
- package/dist/runtime/edition/verb-map.d.ts +1 -0
- package/dist/runtime/edition/verb-map.d.ts.map +1 -1
- package/dist/runtime/edition/verb-map.js +2 -0
- package/dist/runtime/edition/verb-map.js.map +1 -1
- package/edition/README.md +31 -1
- package/edition/authored-source-check.mjs +135 -0
- package/edition/biome-content.mjs +4 -0
- package/edition/customer-edition-verbs.mjs +1 -0
- package/edition/develop-edition-invariants.mjs +141 -0
- package/edition/develop-edition-resolve.mjs +7 -1
- package/edition/develop-edition.mjs +22 -2
- package/edition/dispatched-runtime-components.mjs +4 -3
- package/edition/dist-check.mjs +108 -63
- package/edition/edition-protocol.mjs +36 -9
- package/edition/edition-workspace.mjs +2 -0
- package/edition/kernel-protocol-choice.mjs +239 -0
- package/edition/lib.mjs +100 -3
- package/edition/operation-grant-admission.mjs +65 -1
- package/edition/operation-requirements.mjs +18 -1
- package/edition/resolve-customer-edition.mjs +4 -3
- package/edition/resolve-distribution.mjs +16 -0
- package/edition/resolve-images.mjs +124 -15
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verb-map.d.ts","sourceRoot":"","sources":["../../../src/runtime/edition/verb-map.ts"],"names":[],"mappings":"AAKA,oBAAY,WAAW;IACrB,OAAO,YAAY;IACnB,IAAI,SAAS;IACb,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,QAAQ,aAAa;IACrB,SAAS,cAAc;IACvB,KAAK,UAAU;IACf,KAAK,UAAU;IACf,GAAG,QAAQ;IACX,eAAe,qBAAqB;IACpC,eAAe,qBAAqB;IACpC,kBAAkB,yBAAyB;IAC3C,cAAc,oBAAoB;IAClC,QAAQ,aAAa;IACrB,IAAI,SAAS;IACb,KAAK,UAAU;IACf,aAAa,mBAAmB;IAChC,QAAQ,cAAc;IACtB,cAAc,oBAAoB;IAClC,MAAM,WAAW;IACjB,GAAG,QAAQ;IACX,KAAK,UAAU;CAChB;AAGD,oBAAY,wBAAwB;IAClC,OAAO,YAAY;IACnB,YAAY,kBAAkB;CAC/B;AAGD,oBAAY,mBAAmB;IAC7B,aAAa,mBAAmB;IAChC,SAAS,cAAc;IACvB,WAAW,iBAAiB;IAC5B,cAAc,oBAAoB;IAClC,WAAW,iBAAiB;IAC5B,GAAG,QAAQ;CACZ;AAGD,oBAAY,wBAAwB;IAClC,QAAQ,aAAa;IACrB,YAAY,iBAAiB;IAC7B,WAAW,gBAAgB;IAC3B,SAAS,cAAc;CACxB;AAGD,oBAAY,gBAAgB;IAC1B,KAAK,UAAU;IACf,eAAe,qBAAqB;IACpC,kBAAkB,yBAAyB;CAC5C;AAGD,oBAAY,oBAAoB;IAC9B,OAAO,YAAY;IACnB,MAAM,WAAW;CAClB;AAGD,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,MAAM,CAAC,WAAW,CAAC,cAAc,EAAE,MAAM,CAAC,CAE1F,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CACvC,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,WAAW,CAAC,KAAK,GAAG,WAAW,CAAC,cAAc,GAAG,WAAW,CAAC,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"verb-map.d.ts","sourceRoot":"","sources":["../../../src/runtime/edition/verb-map.ts"],"names":[],"mappings":"AAKA,oBAAY,WAAW;IACrB,OAAO,YAAY;IACnB,IAAI,SAAS;IACb,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,QAAQ,aAAa;IACrB,SAAS,cAAc;IACvB,KAAK,UAAU;IACf,KAAK,UAAU;IACf,aAAa,mBAAmB;IAChC,GAAG,QAAQ;IACX,eAAe,qBAAqB;IACpC,eAAe,qBAAqB;IACpC,kBAAkB,yBAAyB;IAC3C,cAAc,oBAAoB;IAClC,QAAQ,aAAa;IACrB,IAAI,SAAS;IACb,KAAK,UAAU;IACf,aAAa,mBAAmB;IAChC,QAAQ,cAAc;IACtB,cAAc,oBAAoB;IAClC,MAAM,WAAW;IACjB,GAAG,QAAQ;IACX,KAAK,UAAU;CAChB;AAGD,oBAAY,wBAAwB;IAClC,OAAO,YAAY;IACnB,YAAY,kBAAkB;CAC/B;AAGD,oBAAY,mBAAmB;IAC7B,aAAa,mBAAmB;IAChC,SAAS,cAAc;IACvB,WAAW,iBAAiB;IAC5B,cAAc,oBAAoB;IAClC,WAAW,iBAAiB;IAC5B,GAAG,QAAQ;CACZ;AAGD,oBAAY,wBAAwB;IAClC,QAAQ,aAAa;IACrB,YAAY,iBAAiB;IAC7B,WAAW,gBAAgB;IAC3B,SAAS,cAAc;CACxB;AAGD,oBAAY,gBAAgB;IAC1B,KAAK,UAAU;IACf,eAAe,qBAAqB;IACpC,kBAAkB,yBAAyB;CAC5C;AAGD,oBAAY,oBAAoB;IAC9B,OAAO,YAAY;IACnB,MAAM,WAAW;CAClB;AAGD,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,MAAM,CAAC,WAAW,CAAC,cAAc,EAAE,MAAM,CAAC,CAE1F,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CACvC,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,WAAW,CAAC,KAAK,GAAG,WAAW,CAAC,cAAc,GAAG,WAAW,CAAC,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,CAqBnI,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,MAAM,CAAC,wBAAwB,EAAE,MAAM,CAAC,CAGtF,CAAC;AAEF,eAAO,MAAM,gCAAgC,EAAE,QAAQ,CAAC,MAAM,CAAC,wBAAwB,EAAE,MAAM,CAAC,CAK/F,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,mBAAmB,EAAE,mBAAmB,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,CAQxH,CAAC;AAGF,eAAO,MAAM,qBAAqB,WAAW,CAAC;AAE9C,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAI1E,CAAC;AAEF,MAAM,WAAW,iBAAiB;IAEhC,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,CAAC;IAExC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC;AAiDD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,iBAAiB,CAoBtG"}
|
|
@@ -12,6 +12,7 @@ var EditionVerb;
|
|
|
12
12
|
EditionVerb["Catalogue"] = "catalogue";
|
|
13
13
|
EditionVerb["Index"] = "index";
|
|
14
14
|
EditionVerb["Check"] = "check";
|
|
15
|
+
EditionVerb["CheckAuthored"] = "check-authored";
|
|
15
16
|
EditionVerb["Why"] = "why";
|
|
16
17
|
EditionVerb["VerifyPlatforms"] = "verify-platforms";
|
|
17
18
|
EditionVerb["CheckoutSources"] = "checkout-sources";
|
|
@@ -70,6 +71,7 @@ exports.EDITION_VERB_ENTRY = {
|
|
|
70
71
|
[EditionVerb.Artifact]: 'release-edition-artifact.mjs',
|
|
71
72
|
[EditionVerb.Catalogue]: 'catalogue-edition.mjs',
|
|
72
73
|
[EditionVerb.Check]: 'dist-check.mjs',
|
|
74
|
+
[EditionVerb.CheckAuthored]: 'authored-source-check.mjs',
|
|
73
75
|
[EditionVerb.Why]: 'why.mjs',
|
|
74
76
|
[EditionVerb.VerifyPlatforms]: 'verify-image-platforms.mjs',
|
|
75
77
|
[EditionVerb.CheckoutSources]: 'checkout-indexed-source-repositories.mjs',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verb-map.js","sourceRoot":"","sources":["../../../src/runtime/edition/verb-map.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"verb-map.js","sourceRoot":"","sources":["../../../src/runtime/edition/verb-map.ts"],"names":[],"mappings":"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"}
|
package/edition/README.md
CHANGED
|
@@ -33,6 +33,7 @@ Each takes the roots below plus its own arguments (`--check`, an edition id, ...
|
|
|
33
33
|
| `seal-image-digests.mjs` | data, editions, kernel |
|
|
34
34
|
| `verify-image-platforms.mjs` | data, editions, kernel |
|
|
35
35
|
| `dist-check.mjs` | data, editions, sources, kernel, deploy, cache |
|
|
36
|
+
| `authored-source-check.mjs` (`xema edition check-authored`) | data, editions, sources, kernel |
|
|
36
37
|
| `develop-edition.mjs` | data, editions, sources, kernel, deploy, cache |
|
|
37
38
|
| `release-edition.mjs` (`xema edition release`) | per verb: `freeze-sources` data; `target` none; `check-existing` data, cache; `resolve` data, editions, sources, cache |
|
|
38
39
|
| `release-edition-artifact.mjs` (`xema edition artifact`) | data, editions, kernel |
|
|
@@ -71,6 +72,7 @@ Read strictly: every key is required, an unknown key or a duplicate key is refus
|
|
|
71
72
|
xema edition resolve <id> [--check] # write or verify the lock set
|
|
72
73
|
xema edition seal <id> # seal image digests
|
|
73
74
|
xema edition check # committed locks and indices are current
|
|
75
|
+
xema edition check-authored # the authored source, offline: definitions, indexes, policies, chart-set pin
|
|
74
76
|
xema edition why <id> <biome> # why a biome is in an edition
|
|
75
77
|
xema edition list --editions-root <dir>
|
|
76
78
|
xema edition locks <id> --channel <release|develop> # validated locks as JSON; an unsealed distribution lock is read on develop only
|
|
@@ -87,6 +89,32 @@ xema edition evidence <assemble-input|check-committed|plan-refresh|statement|ass
|
|
|
87
89
|
|
|
88
90
|
Results are JSON on stdout and diagnostics on stderr. Exit 0 is success and 1 is a refusal. `xema edition <verb> --help` names the roots and flags each verb takes.
|
|
89
91
|
|
|
92
|
+
## Authored-source check
|
|
93
|
+
|
|
94
|
+
`xema edition check-authored` grades what is authored, offline, and reads no release state. `xema edition check` is the full release-path check; the authored check is a separate entry, not that check with parts turned off. It resolves no edition.
|
|
95
|
+
|
|
96
|
+
It refuses on:
|
|
97
|
+
|
|
98
|
+
- the kernel's edition protocol;
|
|
99
|
+
- `biome-index.json`: immutable entries, deterministic order, no duplicate source identity;
|
|
100
|
+
- `platform-service-index.json` and `runtime-image-source-index.json`, validated offline;
|
|
101
|
+
- the evidence trust policy, its pin and its arming (an unarmed policy counts the editions that hold a release lock, by presence only);
|
|
102
|
+
- the data-root readers (store source repositories, publisher trust);
|
|
103
|
+
- the fleet chart-set pin and the pinned kernel's authorization composer;
|
|
104
|
+
- the ownership self-tests: the kernel's capability-domain reader refuses two owners of one domain and an invalid domain, and counts no unlisted domain as first-party;
|
|
105
|
+
- every edition definition's structure: the kernel parses it, `sourcePins` included, and it composes.
|
|
106
|
+
|
|
107
|
+
It reads no lock content (the committed `distribution`, `images`, `authorization` and per-edition `chart-set` locks; the trust-arming rule counts lock files by presence) and no source checkout at a pinned commit. The sources root is read only for the kernel contract checkout the runtime-image-source index check verifies its authority against. `--check-sources` is refused: it is the release check's source audit.
|
|
108
|
+
|
|
109
|
+
## Develop plane invariants
|
|
110
|
+
|
|
111
|
+
`xema edition develop resolve` asserts the capability-domain reservation table and biome confinement on the candidate it resolves, against the develop graph it froze, before any later phase. On develop they are asserted only there; `xema edition check` asserts them over the committed locks.
|
|
112
|
+
|
|
113
|
+
- Reservation: the candidate's `capabilityDomainOwners` is non-empty, accepted by the kernel's reader, and exactly the table the frozen graph's full biome index builds, so every candidate over one graph carries the same table.
|
|
114
|
+
- Confinement: each `confinedBiomes` declaration names a biome the frozen index carries and a substantive `consequence`; the candidate ships a confined biome only when admitted, and an admission of the candidate for a biome it does not ship is refused as stale.
|
|
115
|
+
|
|
116
|
+
A violation throws `DevelopEditionInvariantError`, whose `violations` carry a `DevelopEditionInvariantReason` each.
|
|
117
|
+
|
|
90
118
|
## Evidence trust
|
|
91
119
|
|
|
92
120
|
The edition library builds, validates and verifies evidence statements; it never signs. Signing is done by the caller with `cosign`.
|
|
@@ -100,7 +128,9 @@ The edition library builds, validates and verifies evidence statements; it never
|
|
|
100
128
|
|
|
101
129
|
## Kernel protocol and pins
|
|
102
130
|
|
|
103
|
-
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
|
|
131
|
+
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 protocols v9 to v14, each pinned to its digest and vendored (v10 to v14 grow the kernel source closure only; a data root whose pinned kernel speaks v8 stays on CLI 0.41.x, v5 on 0.33.x) 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.
|
|
132
|
+
|
|
133
|
+
A develop edition does not take the kernel's develop head blindly: `xema edition develop choose-kernel --kernel <package dir> [--kernel-pin <40-hex>] --out <file>` reads the declared protocol of each commit on the checkout's first-parent history (from source, unbuilt) and chooses the newest one this CLI supports. It writes `{chosenSha, headSha, held, reason}` (`reason`: `head-supported` | `head-ahead` | `explicit-pin`; `held` is `head-ahead`), and when held prints `kernel held at v<N> (<sha12>), head at v<M> (<sha12>): raise the CLI` (stdout only, never persisted). The head is the checkout's `refs/remotes/origin/develop` (a full-history checkout). An explicit pin wins but is still checked, and must be on that head's first-parent history (`not-on-develop` otherwise); when no commit is supported it refuses (`EditionProtocolMismatchError`, `no-supported-commit`; the walk ends at the first commit with no declaration file) and never falls back to the head; a declaration that exists but does not parse, at the head or any walked commit, is refused by name (`unparseable`), never skipped. `freeze-graph` applies the same check to `--kernel-sha`.
|
|
104
134
|
|
|
105
135
|
- `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`.
|
|
106
136
|
- A source repository JOINS a data root that has committed pins with one command: `xema edition index runtime-image-source --trusted-write --repo <repository> [--at <40-hex>] [--kernel-root <checkout>]`. The repository is resolved once and the runtime image source, biome and platform-service indexes are all written from the committed pins plus that one pin; every committed pin is kept field for field (a differing one is refused by name), a second declared repository with no pin is refused, and the summary names each pin added, moved and dropped. Then `xema edition index biome --check`, `xema edition index runtime-image-source --check` and `pnpm check`. The biome builder takes no `--repo`: it would resolve the repository a second time.
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// authored-source-check — `xema edition check-authored`: grades the AUTHORED
|
|
3
|
+
// distribution source, the develop lifecycle's gate. It is its own mode, not
|
|
4
|
+
// the release check with assertions turned off: `xema edition check`
|
|
5
|
+
// (dist-check.mjs) stays the full release-path grade, and nothing here can
|
|
6
|
+
// make it skip anything.
|
|
7
|
+
//
|
|
8
|
+
// Authored and release state are separate lifecycles. What is authored is
|
|
9
|
+
// graded here, offline; what only a release carries is not read: no lock
|
|
10
|
+
// content (the committed distribution / images / authorization / chart-set
|
|
11
|
+
// locks; the trust-arming rule counts lock files by presence), and nothing that
|
|
12
|
+
// needs a source checkout at a committed `repositoryPins` commit. No edition is
|
|
13
|
+
// resolved here: the plane invariants over a resolved edition (the
|
|
14
|
+
// capability-domain reservation table and biome confinement) are asserted on
|
|
15
|
+
// develop by the develop resolve against the graph it froze
|
|
16
|
+
// (develop-edition-invariants.mjs), and on the release path by
|
|
17
|
+
// `xema edition check` over the committed locks. One place per assertion.
|
|
18
|
+
//
|
|
19
|
+
// KEPT (each refuses):
|
|
20
|
+
// - the kernel speaks a supported edition protocol;
|
|
21
|
+
// - biome-index.json: immutable entries, deterministic order, no duplicate
|
|
22
|
+
// source identity, a serviceDependencies projection on every entry;
|
|
23
|
+
// - platform-service-index.json: parses, matches the declared
|
|
24
|
+
// platformServiceSources offline, service-dependency owner parity;
|
|
25
|
+
// - runtime-image-source-index.json: the offline `--check`;
|
|
26
|
+
// - the evidence trust policy, its data-root pin and its arming assessment;
|
|
27
|
+
// - the data-root readers (store source repositories, publisher trust);
|
|
28
|
+
// - the fleet chart-set pin is a rostered chart-set lock;
|
|
29
|
+
// - the pinned kernel's authorization composer loads;
|
|
30
|
+
// - the ownership self-tests: the kernel's capability-domain reader refuses
|
|
31
|
+
// two owners of one domain and an invalid domain, and counts no unlisted
|
|
32
|
+
// domain as first-party (synthetic tables, no lock);
|
|
33
|
+
// - every edition definition is structurally valid: the kernel parses it
|
|
34
|
+
// (its `sourcePins` included) and it composes.
|
|
35
|
+
//
|
|
36
|
+
// NOT HERE:
|
|
37
|
+
// - lock currency, sealed hashes, the authorization lock, each edition's
|
|
38
|
+
// chart-set.lock.json copy, platform-service ownership at pinned commits,
|
|
39
|
+
// `--check-sources` (refused): release state, `xema edition check`;
|
|
40
|
+
// - the definition resolve, reservations, confinement: the develop resolve.
|
|
41
|
+
|
|
42
|
+
import {
|
|
43
|
+
checkDataRootPlane,
|
|
44
|
+
discoverDistributionIds,
|
|
45
|
+
loadPlaneAuthorizationKernel,
|
|
46
|
+
ownershipSelfTestFailures,
|
|
47
|
+
readFleetChartSetPin,
|
|
48
|
+
} from './dist-check.mjs';
|
|
49
|
+
import { describeEditionHolds } from './edition-source-pins.mjs';
|
|
50
|
+
import { WorkspaceRoot, configureEditionWorkspaceFromProcess, isEntryModule } from './edition-workspace.mjs';
|
|
51
|
+
import { loadKernelDistributionSchemas } from './lib.mjs';
|
|
52
|
+
import { composeEdition } from './resolve-distribution.mjs';
|
|
53
|
+
|
|
54
|
+
/** The release-path flag this mode refuses rather than ignores. */
|
|
55
|
+
const CHECK_SOURCES_FLAG = '--check-sources';
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Whether edition `id`'s definition is structurally valid: the kernel parses it
|
|
59
|
+
* and it composes. Nothing is resolved and no index or source is read.
|
|
60
|
+
*
|
|
61
|
+
* @returns {Promise<string | null>} the refusal, or null when valid
|
|
62
|
+
*/
|
|
63
|
+
export async function definitionRefusal(id) {
|
|
64
|
+
try {
|
|
65
|
+
const schemas = await loadKernelDistributionSchemas();
|
|
66
|
+
composeEdition(schemas.parseDistribution, id);
|
|
67
|
+
return null;
|
|
68
|
+
} catch (err) {
|
|
69
|
+
return err.message;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* The ownership self-tests (dist-check.mjs): the kernel's capability-domain
|
|
75
|
+
* reader, against synthetic tables. Lock-free. Returns true when green.
|
|
76
|
+
*/
|
|
77
|
+
async function checkOwnershipSelfTests(resolveFirstPartyCapabilityDomains) {
|
|
78
|
+
let failures;
|
|
79
|
+
try {
|
|
80
|
+
failures = ownershipSelfTestFailures(resolveFirstPartyCapabilityDomains);
|
|
81
|
+
} catch (err) {
|
|
82
|
+
failures = [`the kernel's capability-domain reader threw on a valid table: ${err.message}`];
|
|
83
|
+
}
|
|
84
|
+
for (const failure of failures) {console.error(`[dist:check-authored] ownership self-test FAILED: ${failure}`);}
|
|
85
|
+
if (failures.length === 0) {console.log('[dist:check-authored] ownership self-tests: green.');}
|
|
86
|
+
return failures.length === 0;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* The authored check over the configured roots. Returns true when green.
|
|
91
|
+
* `resolveFirstPartyCapabilityDomains` is the kernel's reader unless a test
|
|
92
|
+
* stands in for it.
|
|
93
|
+
*/
|
|
94
|
+
export async function checkAuthoredSource({ resolveFirstPartyCapabilityDomains } = {}) {
|
|
95
|
+
let green = await checkDataRootPlane({ checkSources: false });
|
|
96
|
+
const reader = resolveFirstPartyCapabilityDomains ?? (await loadKernelDistributionSchemas()).resolveFirstPartyCapabilityDomains;
|
|
97
|
+
if (!(await checkOwnershipSelfTests(reader))) {green = false;}
|
|
98
|
+
|
|
99
|
+
const distributionIds = discoverDistributionIds();
|
|
100
|
+
for (const line of describeEditionHolds(distributionIds)) {console.log(line);}
|
|
101
|
+
for (const id of distributionIds) {
|
|
102
|
+
const refusal = await definitionRefusal(id);
|
|
103
|
+
if (refusal === null) {
|
|
104
|
+
console.log(`[dist:check-authored] ${id}: the definition is valid.`);
|
|
105
|
+
} else {
|
|
106
|
+
console.error(`[dist:check-authored] ${id}: the definition is invalid — ${refusal}`);
|
|
107
|
+
green = false;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const { green: authorizationKernelGreen } = await loadPlaneAuthorizationKernel();
|
|
112
|
+
if (!authorizationKernelGreen) {green = false;}
|
|
113
|
+
if (readFleetChartSetPin() === null) {green = false;}
|
|
114
|
+
|
|
115
|
+
return green;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
async function main() {
|
|
119
|
+
if (process.argv.includes(CHECK_SOURCES_FLAG)) {
|
|
120
|
+
throw new Error(
|
|
121
|
+
`${CHECK_SOURCES_FLAG} audits the indexes against source checkouts, which is release state: ` +
|
|
122
|
+
`run \`xema edition check ${CHECK_SOURCES_FLAG}\`.`,
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
if (!(await checkAuthoredSource())) {process.exit(1);}
|
|
126
|
+
console.log('[dist:check-authored] the authored distribution source is green.');
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (isEntryModule(import.meta.url)) {
|
|
130
|
+
configureEditionWorkspaceFromProcess([WorkspaceRoot.Data, WorkspaceRoot.Editions, WorkspaceRoot.Sources, WorkspaceRoot.Kernel]);
|
|
131
|
+
main().catch((err) => {
|
|
132
|
+
console.error(`[dist:check-authored] ${err.message}`);
|
|
133
|
+
process.exit(1);
|
|
134
|
+
});
|
|
135
|
+
}
|
|
@@ -22,8 +22,10 @@ import { relative, sep } from 'node:path';
|
|
|
22
22
|
import { assertCustomerLockWithinCatalogueCeiling } from './catalogue.mjs';
|
|
23
23
|
import { readGitJsonAtCommit } from './lib.mjs';
|
|
24
24
|
import {
|
|
25
|
+
assertInstalledOperationCeilingAdmitted,
|
|
25
26
|
assertOperationGrantsAdmitted,
|
|
26
27
|
assertOrganizationSweepsAdmitted,
|
|
28
|
+
assertStoreWorkloadCeilingAdmitted,
|
|
27
29
|
} from './operation-grant-admission.mjs';
|
|
28
30
|
|
|
29
31
|
/** A biome whose recomputed content hash is not the lock's, or whose inputs cannot be recomputed. */
|
|
@@ -289,6 +291,8 @@ export async function sealLock({ schemas, unsealed, imageLock, locate, vendoredC
|
|
|
289
291
|
const hashes = await computeBiomeContentHashes({ schemas, lock: unsealed, imageLock, locate, vendoredCommit, catalogue, catalogueDigest, storePublisherAnchorKeys, sourceFactsById });
|
|
290
292
|
assertOperationGrantsAdmitted(schemas, unsealed);
|
|
291
293
|
assertOrganizationSweepsAdmitted(schemas, unsealed);
|
|
294
|
+
assertInstalledOperationCeilingAdmitted(schemas, unsealed);
|
|
295
|
+
assertStoreWorkloadCeilingAdmitted(schemas, unsealed);
|
|
292
296
|
return schemas.sealDistributionLock(unsealed, hashes);
|
|
293
297
|
}
|
|
294
298
|
|
|
@@ -214,6 +214,7 @@ const COMMANDS = Object.freeze({
|
|
|
214
214
|
required: ['--pins', '--cosign'],
|
|
215
215
|
},
|
|
216
216
|
'check-overrides': { positional: false, values: ['--overrides'], switches: [], required: ['--overrides'] },
|
|
217
|
+
'choose-kernel': { positional: false, values: ['--kernel-pin', '--out'], switches: [], required: ['--out'] },
|
|
217
218
|
'check-existing': {
|
|
218
219
|
positional: true,
|
|
219
220
|
values: ['--pins', '--artifact', '--engine-image'],
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
// develop-edition-invariants — the plane invariants a DEVELOP candidate asserts
|
|
2
|
+
// itself, against the develop graph it froze: the capability-domain
|
|
3
|
+
// reservation table and biome confinement.
|
|
4
|
+
//
|
|
5
|
+
// On develop these live ONLY here. `xema edition check-authored` reads no
|
|
6
|
+
// resolved edition, and `xema edition check` (the release path) grades the
|
|
7
|
+
// same two invariants over the committed locks.
|
|
8
|
+
//
|
|
9
|
+
// RESERVATION. Ownership is a property of the platform, not of what an edition
|
|
10
|
+
// preloads (see `buildCapabilityDomainOwners`): every edition carries the table
|
|
11
|
+
// built from the FULL index. The release check proves it by comparing the
|
|
12
|
+
// committed locks with each other. A single candidate proves the same thing
|
|
13
|
+
// alone: its table must be exactly the one the frozen graph's full biome index
|
|
14
|
+
// builds, so any two candidates over one graph carry the identical table. It
|
|
15
|
+
// must also be non-empty (an empty table makes nothing first-party), and the
|
|
16
|
+
// kernel's reader must accept it (one owner per domain, valid domains).
|
|
17
|
+
//
|
|
18
|
+
// CONFINEMENT. The data root's `confinedBiomes` name biomes whose contents must
|
|
19
|
+
// not reach an unadmitted installation. The candidate is one graded edition:
|
|
20
|
+
// a declaration naming a biome the frozen index does not carry guards nothing
|
|
21
|
+
// and is refused; shipping a confined biome without an admission is refused; an
|
|
22
|
+
// admission of this edition for a biome it does not ship is a stale permission
|
|
23
|
+
// and is refused; a declaration without a substantive consequence is refused.
|
|
24
|
+
|
|
25
|
+
import { editionWorkspaceConfig } from './edition-config.mjs';
|
|
26
|
+
import { buildCapabilityDomainOwners, serializeJson } from './lib.mjs';
|
|
27
|
+
|
|
28
|
+
/** Why a develop candidate was refused. */
|
|
29
|
+
export const DevelopEditionInvariantReason = Object.freeze({
|
|
30
|
+
RESERVATION_TABLE_EMPTY: 'reservation-table-empty',
|
|
31
|
+
RESERVATION_TABLE_NOT_PLATFORM_TABLE: 'reservation-table-not-platform-table',
|
|
32
|
+
RESERVATION_TABLE_REFUSED_BY_KERNEL: 'reservation-table-refused-by-kernel',
|
|
33
|
+
CONFINED_BIOME_UNKNOWN: 'confined-biome-unknown',
|
|
34
|
+
CONFINED_BIOME_UNADMITTED: 'confined-biome-unadmitted',
|
|
35
|
+
CONFINEMENT_ADMISSION_STALE: 'confinement-admission-stale',
|
|
36
|
+
CONFINEMENT_CONSEQUENCE_MISSING: 'confinement-consequence-missing',
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
/** The shortest `consequence` that can name what a confinement protects. */
|
|
40
|
+
const MIN_CONSEQUENCE_LENGTH = 40;
|
|
41
|
+
|
|
42
|
+
/** A develop candidate broke a plane invariant. `violations` carries every one, each with its reason. */
|
|
43
|
+
export class DevelopEditionInvariantError extends Error {
|
|
44
|
+
/** @param {string} id @param {{ reason: string, detail: string }[]} violations */
|
|
45
|
+
constructor(id, violations) {
|
|
46
|
+
super(
|
|
47
|
+
`develop edition "${id}" breaks ${violations.length} plane invariant(s):\n` +
|
|
48
|
+
violations.map(({ reason, detail }) => ` - [${reason}] ${detail}`).join('\n'),
|
|
49
|
+
);
|
|
50
|
+
this.name = 'DevelopEditionInvariantError';
|
|
51
|
+
this.distributionId = id;
|
|
52
|
+
this.violations = violations;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* The reservation violations of `lock`, whose graph's full biome index is
|
|
58
|
+
* `biomeIndex`. `resolveFirstPartyCapabilityDomains` is the kernel's reader.
|
|
59
|
+
*/
|
|
60
|
+
export function reservationViolations({ lock, biomeIndex, resolveFirstPartyCapabilityDomains }) {
|
|
61
|
+
const R = DevelopEditionInvariantReason;
|
|
62
|
+
const table = lock.capabilityDomainOwners;
|
|
63
|
+
if (!Array.isArray(table) || table.length === 0) {
|
|
64
|
+
return [{
|
|
65
|
+
reason: R.RESERVATION_TABLE_EMPTY,
|
|
66
|
+
detail: 'capabilityDomainOwners is missing or empty: an empty reservation table makes NOTHING first-party (fail-open)',
|
|
67
|
+
}];
|
|
68
|
+
}
|
|
69
|
+
const violations = [];
|
|
70
|
+
try {
|
|
71
|
+
resolveFirstPartyCapabilityDomains(lock);
|
|
72
|
+
} catch (err) {
|
|
73
|
+
violations.push({ reason: R.RESERVATION_TABLE_REFUSED_BY_KERNEL, detail: err.message });
|
|
74
|
+
}
|
|
75
|
+
if (serializeJson(table) !== serializeJson(buildCapabilityDomainOwners(biomeIndex))) {
|
|
76
|
+
violations.push({
|
|
77
|
+
reason: R.RESERVATION_TABLE_NOT_PLATFORM_TABLE,
|
|
78
|
+
detail:
|
|
79
|
+
'capabilityDomainOwners is not the table the frozen graph\'s full biome index builds. Ownership must not vary ' +
|
|
80
|
+
'by edition, or a trimmed edition leaves domains org-bindable',
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
return violations;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* The confinement violations of edition `id` shipping `lock`, under the data
|
|
88
|
+
* root's `declarations`, with `knownBiomeIds` the frozen index's biome ids.
|
|
89
|
+
*/
|
|
90
|
+
export function confinementViolations({ id, lock, declarations, knownBiomeIds }) {
|
|
91
|
+
const R = DevelopEditionInvariantReason;
|
|
92
|
+
const shipped = new Set(lock.biomes.map((biome) => biome.id));
|
|
93
|
+
const violations = [];
|
|
94
|
+
for (const decl of declarations) {
|
|
95
|
+
if (typeof decl.consequence !== 'string' || decl.consequence.trim().length < MIN_CONSEQUENCE_LENGTH) {
|
|
96
|
+
violations.push({
|
|
97
|
+
reason: R.CONFINEMENT_CONSEQUENCE_MISSING,
|
|
98
|
+
detail: `confinement declaration "${decl.biomeId}" carries no substantive \`consequence\`; a refusal would name a rule without naming what it protects`,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
if (!knownBiomeIds.has(decl.biomeId)) {
|
|
102
|
+
violations.push({
|
|
103
|
+
reason: R.CONFINED_BIOME_UNKNOWN,
|
|
104
|
+
detail:
|
|
105
|
+
`confinement declaration names biome "${decl.biomeId}", which the frozen biome index does not carry: it would ` +
|
|
106
|
+
'guard nothing. Repoint it to the renamed biome, or delete it if the biome is gone',
|
|
107
|
+
});
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
const admitted = decl.admittedEditions.includes(id);
|
|
111
|
+
if (shipped.has(decl.biomeId) && !admitted) {
|
|
112
|
+
violations.push({
|
|
113
|
+
reason: R.CONFINED_BIOME_UNADMITTED,
|
|
114
|
+
detail:
|
|
115
|
+
`ships biome "${decl.biomeId}", which holds ${decl.holds}. That is a CONFINEMENT decision, not a packaging one: ` +
|
|
116
|
+
`${decl.consequence}. If intended, add "${id}" to its admittedEditions in edition-workspace.json in its own commit, naming who agreed`,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
if (!shipped.has(decl.biomeId) && admitted) {
|
|
120
|
+
violations.push({
|
|
121
|
+
reason: R.CONFINEMENT_ADMISSION_STALE,
|
|
122
|
+
detail: `the admission "${decl.biomeId}" -> "${id}" suppresses NOTHING: the edition does not ship the biome. Delete it`,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return violations;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Assert both invariants on develop candidate `id`. Throws
|
|
131
|
+
* {@link DevelopEditionInvariantError} naming every violation; returns the
|
|
132
|
+
* counts it graded otherwise.
|
|
133
|
+
*/
|
|
134
|
+
export function assertDevelopEditionInvariants({ id, lock, biomeIndex, schemas, declarations = editionWorkspaceConfig().confinedBiomes ?? [] }) {
|
|
135
|
+
const violations = [
|
|
136
|
+
...reservationViolations({ lock, biomeIndex, resolveFirstPartyCapabilityDomains: schemas.resolveFirstPartyCapabilityDomains }),
|
|
137
|
+
...confinementViolations({ id, lock, declarations, knownBiomeIds: new Set(biomeIndex.map((entry) => entry.id)) }),
|
|
138
|
+
];
|
|
139
|
+
if (violations.length > 0) {throw new DevelopEditionInvariantError(id, violations);}
|
|
140
|
+
return { reservedDomains: lock.capabilityDomainOwners.length, confinedBiomes: declarations.length };
|
|
141
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// develop-edition-resolve — resolve and seal one DEVELOP edition from a snapshot.
|
|
2
2
|
//
|
|
3
3
|
// The whole pipeline, in the order the release runs it, over the snapshot's
|
|
4
|
-
// injected inputs: distribution lock ->
|
|
4
|
+
// injected inputs: distribution lock -> plane invariants (reservation table,
|
|
5
|
+
// confinement; develop-edition-invariants.mjs) -> authorization base (composed, never
|
|
5
6
|
// written) -> images lock -> develop seal, plus the chart-set lock: the frozen
|
|
6
7
|
// deploy commit's develop chart set (develop-chart-set.mjs). Nothing here writes to the editions
|
|
7
8
|
// trees; the caller writes the artifact (edition-artifact.mjs).
|
|
@@ -10,6 +11,7 @@ import { adapterHostRow, assertAdapterBundlesMatchHost, fetchRegistryManifest }
|
|
|
10
11
|
import { biomeSourceTreeIds, readBiomeSourceFacts, sealLock } from './biome-content.mjs';
|
|
11
12
|
import { buildCatalogue } from './catalogue.mjs';
|
|
12
13
|
import { resolveDevelopChartSet } from './develop-chart-set.mjs';
|
|
14
|
+
import { assertDevelopEditionInvariants } from './develop-edition-invariants.mjs';
|
|
13
15
|
import { createDevelopImageProbe } from './develop-image-probe.mjs';
|
|
14
16
|
import { assertFrozenCheckouts, buildSnapshotInputs } from './develop-snapshot-inputs.mjs';
|
|
15
17
|
import { EditionChannel } from './edition-constants.mjs';
|
|
@@ -30,6 +32,7 @@ export const DEVELOP_EDITION_STEPS = Object.freeze({
|
|
|
30
32
|
assertFrozenCheckouts,
|
|
31
33
|
buildSnapshotInputs,
|
|
32
34
|
resolveDistributionWithIndex,
|
|
35
|
+
assertDevelopEditionInvariants,
|
|
33
36
|
assertAdapterBundlesMatchHost,
|
|
34
37
|
composeAuthorizationBase,
|
|
35
38
|
resolveImages,
|
|
@@ -59,6 +62,9 @@ export async function resolveDevelopEdition({ id, pins, env = process.env, sealO
|
|
|
59
62
|
// One line per phase, with the time since the resolve began, so the step is never silent for long.
|
|
60
63
|
const phase = (name) => progress(`[develop-edition] ${name} (+${Date.now() - startedAt}ms)`);
|
|
61
64
|
const { schemas, inputs, lock, index } = await resolveDevelopSnapshot({ id, pins, steps, phase });
|
|
65
|
+
// The plane invariants, against the graph this candidate froze (develop-edition-invariants.mjs).
|
|
66
|
+
const graded = steps.assertDevelopEditionInvariants({ id, lock, biomeIndex: inputs.biomeIndex, schemas });
|
|
67
|
+
phase(`reservation table asserted (${graded.reservedDomains} domains); confinement asserted (${graded.confinedBiomes} declaration(s))`);
|
|
62
68
|
await steps.assertAdapterBundlesMatchHost({ lock, hostRow: adapterHostRow(index), fetchManifest });
|
|
63
69
|
const authorizationLock = await steps.composeAuthorizationBase(id, lock, index);
|
|
64
70
|
phase('distribution lock resolved');
|
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
// [--overrides <json>] --out <file>
|
|
31
31
|
// resolve refs/heads/develop once per graph repository (and the editions
|
|
32
32
|
// root) from this checkout's runtime-image-source-index.json; the three checked-out
|
|
33
|
-
// repositories are pinned at what the workflow checked out; write the pins.
|
|
33
|
+
// repositories are pinned at what the workflow checked out; write the pins. --kernel-sha is refused
|
|
34
|
+
// unless its declared edition protocol is one this CLI supports (the check choose-kernel applies to a pin).
|
|
34
35
|
// check-existing <id> --pins <file> --artifact <dir> --engine-image <repository>@sha256:<digest>
|
|
35
36
|
// refuse to reuse a pulled artifact whose descriptor disagrees with this snapshot.
|
|
36
37
|
// check-existing --definition <file> --pins <file> --artifact <dir> --engine-image <repository>@sha256:<digest>
|
|
@@ -44,6 +45,13 @@
|
|
|
44
45
|
// annotations-missing | annotation-mismatch | not-built). Prints a table grouped by producer repo
|
|
45
46
|
// and `covered N/M` (--json: the same as data). Exit 0 only when every subject is covered, 1 when
|
|
46
47
|
// not, 2 on an operational error. Takes the roots `resolve` takes; writes nothing.
|
|
48
|
+
// choose-kernel [--kernel-pin <40-hex>] --out <file>
|
|
49
|
+
// choose the develop kernel commit in the --kernel checkout (full history; its refs/remotes/origin/develop is the develop head):
|
|
50
|
+
// the newest first-parent commit whose declared edition protocol this CLI supports
|
|
51
|
+
// (kernel-protocol-choice.mjs). Writes {chosenSha, headSha, held, reason} (reason: head-supported |
|
|
52
|
+
// head-ahead | explicit-pin); when held, prints `kernel held at v<N> (<sha12>), head at v<M> (<sha12>):
|
|
53
|
+
// raise the CLI` to stdout (never persisted). A pin wins and is still checked; nothing supported is refused.
|
|
54
|
+
// Takes only --kernel (the checkout need not be built).
|
|
47
55
|
// check-overrides --overrides <json>
|
|
48
56
|
// refuse a pins override that would select the tooling this run executes
|
|
49
57
|
// (the edition tooling's own repository); the workflow runs it before any other checkout.
|
|
@@ -68,8 +76,9 @@ import { resolveDevelopEdition } from './develop-edition-resolve.mjs';
|
|
|
68
76
|
import { assertNoToolingOverride, freezeGraph, freezeSources } from './develop-freeze.mjs';
|
|
69
77
|
import { LOCAL_WORKFLOW, assertExistingArtifactMatches, developEditionTarget, workflowFromEnv, writeEditionArtifact } from './edition-artifact.mjs';
|
|
70
78
|
import { EditionChannel } from './edition-constants.mjs';
|
|
71
|
-
import { WorkspaceRoot, configureEditionWorkspaceFromProcess, isEntryModule, runtimeImageSourceIndexPath } from './edition-workspace.mjs';
|
|
79
|
+
import { WorkspaceRoot, configureEditionWorkspaceFromProcess, isEntryModule, kernelRepoDir, runtimeImageSourceIndexPath } from './edition-workspace.mjs';
|
|
72
80
|
import { descriptorEvidenceTrust } from './evidence-trust-policy.mjs';
|
|
81
|
+
import { assertKernelCommitSupported, chooseKernelCommit } from './kernel-protocol-choice.mjs';
|
|
73
82
|
import { loadKernelDistributionSchemas } from './lib.mjs';
|
|
74
83
|
import { snapshotPinSource } from './pin-source.mjs';
|
|
75
84
|
import { composeEdition } from './resolve-distribution.mjs';
|
|
@@ -85,11 +94,15 @@ const VENDOR_ROOTS = Object.freeze([WorkspaceRoot.Data, WorkspaceRoot.Editions,
|
|
|
85
94
|
const COVERAGE_COMMAND = 'coverage';
|
|
86
95
|
const COVERAGE_OPERATIONAL_EXIT = CoverageExit.Operational;
|
|
87
96
|
const DATA_ROOT_ONLY_COMMANDS = Object.freeze(['check-overrides']);
|
|
97
|
+
// `choose-kernel` reads the kernel checkout's git history only, before the kernel is built.
|
|
98
|
+
const KERNEL_ROOT_ONLY_COMMANDS = Object.freeze(['choose-kernel']);
|
|
88
99
|
|
|
89
100
|
if (isEntryModule(import.meta.url)) {
|
|
90
101
|
const [command] = process.argv.slice(2);
|
|
91
102
|
if (DATA_ROOT_ONLY_COMMANDS.includes(command)) {
|
|
92
103
|
configureEditionWorkspaceFromProcess([WorkspaceRoot.Data], { refuseOthers: true });
|
|
104
|
+
} else if (KERNEL_ROOT_ONLY_COMMANDS.includes(command)) {
|
|
105
|
+
configureEditionWorkspaceFromProcess([WorkspaceRoot.Kernel], { refuseOthers: true });
|
|
93
106
|
} else {
|
|
94
107
|
const customerForm = process.argv.includes(DEFINITION_FLAG);
|
|
95
108
|
configureEditionWorkspaceFromProcess(customerForm ? (CUSTOMER_ROOTS[command] ?? VENDOR_ROOTS) : VENDOR_ROOTS, {
|
|
@@ -165,7 +178,14 @@ async function run(argv, env) {
|
|
|
165
178
|
assertNoToolingOverride(parseOverrides(options['--overrides']));
|
|
166
179
|
return;
|
|
167
180
|
}
|
|
181
|
+
case 'choose-kernel': {
|
|
182
|
+
const { choice, notice } = chooseKernelCommit({ repoDir: kernelRepoDir(), pin: options['--kernel-pin'] });
|
|
183
|
+
writeOnce(options['--out'], choice);
|
|
184
|
+
if (notice !== undefined) {console.log(notice);}
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
168
187
|
case 'freeze-graph': {
|
|
188
|
+
assertKernelCommitSupported({ repoDir: kernelRepoDir(), commit: options['--kernel-sha'], label: `--kernel-sha ${options['--kernel-sha']}` });
|
|
169
189
|
const pins = freezeGraph({
|
|
170
190
|
runtimeSourceIndex: readStrictJsonFile(runtimeImageSourceIndexPath()),
|
|
171
191
|
dataSha: options['--data-sha'],
|
|
@@ -22,9 +22,10 @@ export class UndeclaredSupplementalRuntimeComponentError extends Error {
|
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
// The `supplementalRuntimeComponentId` field is read as plain data
|
|
26
|
-
//
|
|
27
|
-
//
|
|
25
|
+
// The `supplementalRuntimeComponentId` field is read as plain data. Since edition
|
|
26
|
+
// protocol v10 the kernel types it (`DispatchedRuntimeComponentSchema`, a union of
|
|
27
|
+
// two strict objects); this projection keeps reading it as data and refuses a target
|
|
28
|
+
// that is neither form, or both.
|
|
28
29
|
const isNonEmptyString = (value) => typeof value === 'string' && value.length > 0;
|
|
29
30
|
|
|
30
31
|
/** True for the supplemental form of a projected edge. */
|