@githolon/dsl 0.108.2 → 0.108.4
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/dart/CHANGELOG.md +5 -0
- package/dart/lib/src/runner/node-entry.mjs +18 -2
- package/dart/lib/src/runner/offline-install.mjs +107 -3
- package/dart/pubspec.yaml +1 -1
- package/package.json +1 -1
- package/runtime/generated-application-host.js +21 -3
- package/src/codegen_ts.ts +155 -0
- package/src/compile_package_main.ts +44 -0
- package/src/framework/auth_provider_law.ts +14 -2
- package/src/framework_call_definitions.ts +3 -1
package/dart/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
## 0.65.2
|
|
2
|
+
|
|
3
|
+
- Preserve complete typed birth lineage and recover existing workspaces through the authenticated
|
|
4
|
+
installed-controller lifecycle without falling back to dynamic host-authored payloads.
|
|
5
|
+
|
|
1
6
|
## 0.65.1
|
|
2
7
|
|
|
3
8
|
- Publish the generated nominal application call and query surfaces required by current DSL output, so
|
|
@@ -14666,8 +14666,24 @@ function firstDeviceDelegationPayload(route, certificate, typedPayload) {
|
|
|
14666
14666
|
if (declared.has("delegationCertificate")) {
|
|
14667
14667
|
return { delegationCertificate: typedPayload };
|
|
14668
14668
|
}
|
|
14669
|
-
throw new
|
|
14670
|
-
`Nomos application route '${route.domain}${route.path}' does not declare the typed 'delegationCertificate' contract
|
|
14669
|
+
throw new NomosClientError(
|
|
14670
|
+
`Nomos application route '${route.domain}${route.path}' does not declare the typed 'delegationCertificate' contract`,
|
|
14671
|
+
{
|
|
14672
|
+
code: "nomos.application.contract_missing",
|
|
14673
|
+
operation: "enrollFirstDevice",
|
|
14674
|
+
recommendedAction: NomosRecommendedAction.redeployLaw,
|
|
14675
|
+
info: {
|
|
14676
|
+
code: "nomos.application.contract_missing",
|
|
14677
|
+
message: `Nomos application route '${route.domain}${route.path}' does not declare the typed 'delegationCertificate' contract`,
|
|
14678
|
+
component: "nomos.application",
|
|
14679
|
+
domain: route.domain,
|
|
14680
|
+
operation: "enrollFirstDevice",
|
|
14681
|
+
attributes: {
|
|
14682
|
+
"nomos.application.missing_contract": "delegationCertificate",
|
|
14683
|
+
"nomos.recovery.action": "repeat-parent-authorized-birth"
|
|
14684
|
+
}
|
|
14685
|
+
}
|
|
14686
|
+
}
|
|
14671
14687
|
);
|
|
14672
14688
|
}
|
|
14673
14689
|
var GIT_OBJECT_ID = /^[0-9a-f]{40}$/;
|
|
@@ -4390,6 +4390,8 @@ __export(engine_exports, {
|
|
|
4390
4390
|
author: () => author,
|
|
4391
4391
|
authorEphemeral: () => authorEphemeral,
|
|
4392
4392
|
authorKeygen: () => authorKeygen,
|
|
4393
|
+
authorModelLifecyclePromotion: () => authorModelLifecyclePromotion,
|
|
4394
|
+
authorModelLifecycleStage: () => authorModelLifecycleStage,
|
|
4393
4395
|
authorOn: () => authorOn,
|
|
4394
4396
|
authorOperatorCall: () => authorOperatorCall,
|
|
4395
4397
|
backupHead: () => backupHead,
|
|
@@ -10898,6 +10900,7 @@ var AuthoringOptionsSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_ke
|
|
|
10898
10900
|
var CapturedClockSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 49);
|
|
10899
10901
|
var BirthCertificateSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 50);
|
|
10900
10902
|
var SignBirthCertificateRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 51);
|
|
10903
|
+
var ModelLifecycleIntentSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 53);
|
|
10901
10904
|
var OfferRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 54);
|
|
10902
10905
|
var QueryRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 57);
|
|
10903
10906
|
var QueryAuthoritySchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 64);
|
|
@@ -10912,6 +10915,10 @@ var PendingConflictsQuerySchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_
|
|
|
10912
10915
|
var PendingConflictSummaryQuerySchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 77);
|
|
10913
10916
|
var NamedQuerySchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 78);
|
|
10914
10917
|
var FrontierTransitionRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 79);
|
|
10918
|
+
var FrontierTransitionDispositionMapEntrySchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 80);
|
|
10919
|
+
var FrontierTransitionDispositionsSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 81);
|
|
10920
|
+
var FrontierTransitionViolationSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 82);
|
|
10921
|
+
var FrontierTransitionResponseSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 83);
|
|
10915
10922
|
var AuthorizationObjectSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 84);
|
|
10916
10923
|
var AuthorizationSubjectSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 85);
|
|
10917
10924
|
var AuthorizationConsistencySchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 87);
|
|
@@ -10950,6 +10957,8 @@ var NomosValueSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
|
10950
10957
|
var NomosStructSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 166);
|
|
10951
10958
|
var BirthOutcomeStatusSchema = /* @__PURE__ */ enumDesc(file_nomos_kernel_v1_kernel, 0);
|
|
10952
10959
|
var BirthOutcomeStatus = /* @__PURE__ */ tsEnum(BirthOutcomeStatusSchema);
|
|
10960
|
+
var ModelLifecycleOperationSchema = /* @__PURE__ */ enumDesc(file_nomos_kernel_v1_kernel, 3);
|
|
10961
|
+
var ModelLifecycleOperation = /* @__PURE__ */ tsEnum(ModelLifecycleOperationSchema);
|
|
10953
10962
|
var QueryResultFormatSchema = /* @__PURE__ */ enumDesc(file_nomos_kernel_v1_kernel, 5);
|
|
10954
10963
|
var QueryResultFormat = /* @__PURE__ */ tsEnum(QueryResultFormatSchema);
|
|
10955
10964
|
var QueryOperationSchema = /* @__PURE__ */ enumDesc(file_nomos_kernel_v1_kernel, 6);
|
|
@@ -11586,6 +11595,100 @@ var closureInstallPayload = (hash, installedBy, options = {}) => ({
|
|
|
11586
11595
|
function authorOperatorCall(eng2, ws, call, controllerHash, opts = {}) {
|
|
11587
11596
|
return author(eng2, ws, call.domain, call.directive, call.canonicalUsda, controllerHash, opts);
|
|
11588
11597
|
}
|
|
11598
|
+
function authorModelLifecycleStage(eng2, ws, lawUsdz, installedBy, supersedes, opts = {}) {
|
|
11599
|
+
const sequence = eng2.seq++;
|
|
11600
|
+
const captured = {
|
|
11601
|
+
physical: Date.now(),
|
|
11602
|
+
logical: 0,
|
|
11603
|
+
replica: eng2.replica
|
|
11604
|
+
};
|
|
11605
|
+
const response = offerRequestResponse(eng2, create(OfferRequestSchema, {
|
|
11606
|
+
target: protoTarget(ws),
|
|
11607
|
+
intent: {
|
|
11608
|
+
case: "modelLifecycle",
|
|
11609
|
+
value: create(ModelLifecycleIntentSchema, {
|
|
11610
|
+
operation: ModelLifecycleOperation.STAGE,
|
|
11611
|
+
installedBy,
|
|
11612
|
+
supersedes
|
|
11613
|
+
})
|
|
11614
|
+
},
|
|
11615
|
+
authoring: create(AuthoringOptionsSchema, {
|
|
11616
|
+
actor: opts.actor ?? "",
|
|
11617
|
+
authToken: opts.authToken ? enc3.encode(opts.authToken) : new Uint8Array(),
|
|
11618
|
+
authorSecret: opts.authorSecret ? bytesFromB64(opts.authorSecret) : new Uint8Array(),
|
|
11619
|
+
validFromEpoch: opts.validFromEpoch === void 0 ? void 0 : BigInt(opts.validFromEpoch),
|
|
11620
|
+
rng: osEntropyBuffer(opts.rngDraws ?? 64),
|
|
11621
|
+
deferProjection: opts.deferProjection !== false,
|
|
11622
|
+
spans: opts.spans ?? false,
|
|
11623
|
+
sequence: BigInt(sequence),
|
|
11624
|
+
clock: create(CapturedClockSchema, {
|
|
11625
|
+
physicalMillis: BigInt(captured.physical),
|
|
11626
|
+
logical: captured.logical,
|
|
11627
|
+
replica: BigInt(captured.replica)
|
|
11628
|
+
})
|
|
11629
|
+
}),
|
|
11630
|
+
lawUsdz
|
|
11631
|
+
}));
|
|
11632
|
+
return offerResult(response);
|
|
11633
|
+
}
|
|
11634
|
+
function authorModelLifecyclePromotion(eng2, ws, transition, replaces, acceptanceReason, opts = {}) {
|
|
11635
|
+
const sequence = eng2.seq++;
|
|
11636
|
+
const captured = {
|
|
11637
|
+
physical: Date.now(),
|
|
11638
|
+
logical: 0,
|
|
11639
|
+
replica: eng2.replica
|
|
11640
|
+
};
|
|
11641
|
+
const dispositions = transition.dispositions === void 0 ? void 0 : create(FrontierTransitionDispositionsSchema, {
|
|
11642
|
+
retired: [...transition.dispositions.retired],
|
|
11643
|
+
retyped: Object.entries(transition.dispositions.retyped).map(
|
|
11644
|
+
([sourceStableId, acknowledgement]) => create(FrontierTransitionDispositionMapEntrySchema, { sourceStableId, acknowledgement })
|
|
11645
|
+
),
|
|
11646
|
+
rebinds: Object.entries(transition.dispositions.rebinds).map(
|
|
11647
|
+
([sourceStableId, acknowledgement]) => create(FrontierTransitionDispositionMapEntrySchema, { sourceStableId, acknowledgement })
|
|
11648
|
+
),
|
|
11649
|
+
acknowledgedBy: transition.dispositions.ackBy
|
|
11650
|
+
});
|
|
11651
|
+
const response = offerRequestResponse(eng2, create(OfferRequestSchema, {
|
|
11652
|
+
target: protoTarget(ws),
|
|
11653
|
+
intent: {
|
|
11654
|
+
case: "modelLifecycle",
|
|
11655
|
+
value: create(ModelLifecycleIntentSchema, {
|
|
11656
|
+
operation: ModelLifecycleOperation.PROMOTE,
|
|
11657
|
+
replaces,
|
|
11658
|
+
acceptanceReason,
|
|
11659
|
+
transition: create(FrontierTransitionResponseSchema, {
|
|
11660
|
+
atHash: transition.atHash,
|
|
11661
|
+
currentHash: transition.currentHash,
|
|
11662
|
+
atStateRoot: transition.atStateRoot ?? "",
|
|
11663
|
+
candidateHash: transition.candidateHash,
|
|
11664
|
+
domain: transition.domain,
|
|
11665
|
+
domains: [...transition.domains ?? []],
|
|
11666
|
+
ready: transition.ready,
|
|
11667
|
+
violations: transition.evolve.violations.map(
|
|
11668
|
+
({ domain, detail }) => create(FrontierTransitionViolationSchema, { domain, detail })
|
|
11669
|
+
),
|
|
11670
|
+
dispositions
|
|
11671
|
+
})
|
|
11672
|
+
})
|
|
11673
|
+
},
|
|
11674
|
+
authoring: create(AuthoringOptionsSchema, {
|
|
11675
|
+
actor: opts.actor ?? "",
|
|
11676
|
+
authToken: opts.authToken ? enc3.encode(opts.authToken) : new Uint8Array(),
|
|
11677
|
+
authorSecret: opts.authorSecret ? bytesFromB64(opts.authorSecret) : new Uint8Array(),
|
|
11678
|
+
validFromEpoch: opts.validFromEpoch === void 0 ? void 0 : BigInt(opts.validFromEpoch),
|
|
11679
|
+
rng: osEntropyBuffer(opts.rngDraws ?? 64),
|
|
11680
|
+
deferProjection: opts.deferProjection !== false,
|
|
11681
|
+
spans: opts.spans ?? false,
|
|
11682
|
+
sequence: BigInt(sequence),
|
|
11683
|
+
clock: create(CapturedClockSchema, {
|
|
11684
|
+
physicalMillis: BigInt(captured.physical),
|
|
11685
|
+
logical: captured.logical,
|
|
11686
|
+
replica: BigInt(captured.replica)
|
|
11687
|
+
})
|
|
11688
|
+
})
|
|
11689
|
+
}));
|
|
11690
|
+
return offerResult(response);
|
|
11691
|
+
}
|
|
11589
11692
|
function initializeWorkspace(eng2, ws, installedBy = eng2.installedBy) {
|
|
11590
11693
|
const sequence = eng2.seq++;
|
|
11591
11694
|
const captured = {
|
|
@@ -14457,11 +14560,12 @@ function promotePreflighted(eng2, ws, domain, candidateHash, opts = {}) {
|
|
|
14457
14560
|
acceptanceReason: _acceptance,
|
|
14458
14561
|
...authorOpts
|
|
14459
14562
|
} = opts;
|
|
14460
|
-
const result =
|
|
14563
|
+
const result = authorModelLifecyclePromotion(
|
|
14461
14564
|
eng2,
|
|
14462
14565
|
ws,
|
|
14463
|
-
|
|
14464
|
-
|
|
14566
|
+
report,
|
|
14567
|
+
prepared.payload.replaces,
|
|
14568
|
+
prepared.payload.preflight.acceptanceReason,
|
|
14465
14569
|
{
|
|
14466
14570
|
...authorOpts,
|
|
14467
14571
|
...actingPrincipal ? { actor: actingPrincipal } : {}
|
package/dart/pubspec.yaml
CHANGED
|
@@ -7,7 +7,7 @@ repository: https://github.com/Captain-App/nomos2
|
|
|
7
7
|
description: >-
|
|
8
8
|
Nomos 2 Dart client — generated domain values, intent payloads and application
|
|
9
9
|
lifecycle types over the typed Nomos kernel protocol and USDA custody model.
|
|
10
|
-
version: 0.65.
|
|
10
|
+
version: 0.65.2
|
|
11
11
|
|
|
12
12
|
environment:
|
|
13
13
|
sdk: ^3.5.0
|
package/package.json
CHANGED
|
@@ -13088,8 +13088,24 @@ function firstDeviceDelegationPayload(route, certificate, typedPayload) {
|
|
|
13088
13088
|
if (declared.has("delegationCertificate")) {
|
|
13089
13089
|
return { delegationCertificate: typedPayload };
|
|
13090
13090
|
}
|
|
13091
|
-
throw new
|
|
13092
|
-
`Nomos application route '${route.domain}${route.path}' does not declare the typed 'delegationCertificate' contract
|
|
13091
|
+
throw new NomosClientError(
|
|
13092
|
+
`Nomos application route '${route.domain}${route.path}' does not declare the typed 'delegationCertificate' contract`,
|
|
13093
|
+
{
|
|
13094
|
+
code: "nomos.application.contract_missing",
|
|
13095
|
+
operation: "enrollFirstDevice",
|
|
13096
|
+
recommendedAction: NomosRecommendedAction.redeployLaw,
|
|
13097
|
+
info: {
|
|
13098
|
+
code: "nomos.application.contract_missing",
|
|
13099
|
+
message: `Nomos application route '${route.domain}${route.path}' does not declare the typed 'delegationCertificate' contract`,
|
|
13100
|
+
component: "nomos.application",
|
|
13101
|
+
domain: route.domain,
|
|
13102
|
+
operation: "enrollFirstDevice",
|
|
13103
|
+
attributes: {
|
|
13104
|
+
"nomos.application.missing_contract": "delegationCertificate",
|
|
13105
|
+
"nomos.recovery.action": "repeat-parent-authorized-birth"
|
|
13106
|
+
}
|
|
13107
|
+
}
|
|
13108
|
+
}
|
|
13093
13109
|
);
|
|
13094
13110
|
}
|
|
13095
13111
|
var GIT_OBJECT_ID = /^[0-9a-f]{40}$/;
|
|
@@ -22497,7 +22513,9 @@ async function nomosInternalOpenGeneratedApplication(options, bind, internals =
|
|
|
22497
22513
|
try {
|
|
22498
22514
|
await measureOpen("confirm private-custody signer enrolment", enroll);
|
|
22499
22515
|
} catch (error) {
|
|
22500
|
-
|
|
22516
|
+
const errorCode = typeof error === "object" && error !== null && "code" in error ? String(error.code ?? "") : "";
|
|
22517
|
+
const parentAuthorizedMigrationRequired = errorCode === "nomos.application.contract_missing" || String(error).includes("receiving-group-additional-device-requires-current-device-or-guardian");
|
|
22518
|
+
if (!parentAuthorizedMigrationRequired) throw error;
|
|
22501
22519
|
await birthOrRepeat();
|
|
22502
22520
|
await measureOpen("verify recovered private-custody signer enrolment", enroll);
|
|
22503
22521
|
}
|
package/src/codegen_ts.ts
CHANGED
|
@@ -1127,6 +1127,9 @@ export interface TsClientOptions {
|
|
|
1127
1127
|
/** Emit the structural holon factory for the compiler-owned headless artifact. The ordinary tenant
|
|
1128
1128
|
* client leaves this false so framework transport types never enter its public declaration graph. */
|
|
1129
1129
|
readonly exportHolonFactory?: boolean;
|
|
1130
|
+
/** Emit only the fixed framework operator call set (identity, lifecycle and birth). This is the
|
|
1131
|
+
* small server/operator companion: exact generated USDA calls, no application/read runtime. */
|
|
1132
|
+
readonly frameworkOperatorOnly?: boolean;
|
|
1130
1133
|
/** Exact law identities and paths from the same in-memory USDA render which produced the shipped
|
|
1131
1134
|
* closure. This is compiler input for generated call encoders, never a checked-in sidecar. */
|
|
1132
1135
|
readonly callUsda?: readonly {
|
|
@@ -2136,6 +2139,158 @@ export function generateTsClient(
|
|
|
2136
2139
|
}
|
|
2137
2140
|
}
|
|
2138
2141
|
}
|
|
2142
|
+
if (opts.frameworkOperatorOnly === true) {
|
|
2143
|
+
const fixedGroups = new Set(["identity", "governance", "lifecycle", "birth"]);
|
|
2144
|
+
const operatorDefinitions = frameworkCallMethodDefinitions.filter(
|
|
2145
|
+
(definition) => fixedGroups.has(definition.group)
|
|
2146
|
+
);
|
|
2147
|
+
const operatorEncoders = frameworkCallEncoders.filter((entry) =>
|
|
2148
|
+
fixedGroups.has(entry.group)
|
|
2149
|
+
);
|
|
2150
|
+
const capabilityReceiptByKey = new Map<string, {
|
|
2151
|
+
readonly domain: string;
|
|
2152
|
+
readonly directiveId: string;
|
|
2153
|
+
readonly payloadType: string;
|
|
2154
|
+
readonly encoder: ReturnType<typeof emitTsCallUsdaEncoder>;
|
|
2155
|
+
}>();
|
|
2156
|
+
const capabilityReferenceTypes = new Set<string>();
|
|
2157
|
+
for (const mod of modules) {
|
|
2158
|
+
const domain = mod.domain ?? mod.name;
|
|
2159
|
+
const law = callUsdaByDomain.get(domain);
|
|
2160
|
+
if (law === undefined) continue;
|
|
2161
|
+
const authored = authoredDirectivesByDomain.get(domain) ?? [];
|
|
2162
|
+
for (const capability of mod.impureCapabilities ?? []) {
|
|
2163
|
+
for (const receipt of [
|
|
2164
|
+
capability.complete,
|
|
2165
|
+
capability.fail,
|
|
2166
|
+
capability.block,
|
|
2167
|
+
capability.deadLetter,
|
|
2168
|
+
]) {
|
|
2169
|
+
const directive = authored.find((candidate) => candidate.id === receipt.id);
|
|
2170
|
+
if (directive === undefined) {
|
|
2171
|
+
throw new Error(
|
|
2172
|
+
`TypeScript capability receipt codegen: '${domain}/${receipt.id}' has no authored directive`,
|
|
2173
|
+
);
|
|
2174
|
+
}
|
|
2175
|
+
const payloadType = tsTypeOfPayload(
|
|
2176
|
+
directive.payloadSchema as z.ZodTypeAny,
|
|
2177
|
+
[],
|
|
2178
|
+
);
|
|
2179
|
+
for (const referenceType of payloadReferenceTypes(
|
|
2180
|
+
directive.payloadSchema as z.ZodTypeAny,
|
|
2181
|
+
)) {
|
|
2182
|
+
capabilityReferenceTypes.add(referenceType);
|
|
2183
|
+
}
|
|
2184
|
+
capabilityReceiptByKey.set(`${domain}\u0000${receipt.id}`, {
|
|
2185
|
+
domain,
|
|
2186
|
+
directiveId: receipt.id,
|
|
2187
|
+
payloadType,
|
|
2188
|
+
encoder: emitTsCallUsdaEncoder(
|
|
2189
|
+
law.graph,
|
|
2190
|
+
law.paths,
|
|
2191
|
+
domain,
|
|
2192
|
+
receipt.id,
|
|
2193
|
+
payloadType,
|
|
2194
|
+
),
|
|
2195
|
+
});
|
|
2196
|
+
}
|
|
2197
|
+
}
|
|
2198
|
+
}
|
|
2199
|
+
const capabilityReceipts = [...capabilityReceiptByKey.values()].sort((left, right) =>
|
|
2200
|
+
left.domain.localeCompare(right.domain) || left.directiveId.localeCompare(right.directiveId)
|
|
2201
|
+
);
|
|
2202
|
+
return [
|
|
2203
|
+
`// AUTO-GENERATED by nomos-compile — exact framework operators for package "${opts.packageName}".`,
|
|
2204
|
+
`// No application runtime and no authority live here. Do not edit.`,
|
|
2205
|
+
``,
|
|
2206
|
+
...TS_CALL_USDA_PRELUDE,
|
|
2207
|
+
`/** A SHA-256 digest in canonical Nomos wire form. */`,
|
|
2208
|
+
`export type Sha256Digest = string & { readonly __nomosSha256Digest: unique symbol };`,
|
|
2209
|
+
`/** A Git object address in canonical gix custody form. */`,
|
|
2210
|
+
`export type GitObjectId = string & { readonly __nomosGitObjectId: unique symbol };`,
|
|
2211
|
+
`/** Exact compiler-authored framework call. Bytes are internal transport, while callers retain the nominal method and payload type. */`,
|
|
2212
|
+
`export interface NomosFrameworkCall<Domain extends string = string, Directive extends string = string> {`,
|
|
2213
|
+
` readonly domain: Domain;`,
|
|
2214
|
+
` readonly directive: Directive;`,
|
|
2215
|
+
` readonly canonicalUsda: Uint8Array;`,
|
|
2216
|
+
` readonly routingCandidates: readonly string[];`,
|
|
2217
|
+
`}`,
|
|
2218
|
+
`declare const _nomosAggregateType: unique symbol;`,
|
|
2219
|
+
...[...capabilityReferenceTypes].sort().map(
|
|
2220
|
+
(id) => `export type ${id} = { readonly [_nomosAggregateType]?: ${JSON.stringify(id)} };`,
|
|
2221
|
+
),
|
|
2222
|
+
`export interface NomosRef<TAggregate> {`,
|
|
2223
|
+
` readonly [_nomosAggregateType]: (aggregate: TAggregate) => TAggregate;`,
|
|
2224
|
+
` readonly workspace: string;`,
|
|
2225
|
+
` readonly type: string;`,
|
|
2226
|
+
` readonly id: string;`,
|
|
2227
|
+
` readonly address: string;`,
|
|
2228
|
+
`}`,
|
|
2229
|
+
`/** Construct a typed address after the operator has independently established that the referenced task exists. A reference is not authority. */`,
|
|
2230
|
+
`export const nomosRef = <TAggregate>(workspace: string, type: string, id: string): NomosRef<TAggregate> => ({`,
|
|
2231
|
+
` workspace, type, id,`,
|
|
2232
|
+
` address: "nomos://" + encodeURIComponent(workspace) + "/" + encodeURIComponent(type) + "/" + encodeURIComponent(id),`,
|
|
2233
|
+
`} as unknown as NomosRef<TAggregate>);`,
|
|
2234
|
+
`const _nmsReferenceTypeMatches = (actual: string, expected: string): boolean =>`,
|
|
2235
|
+
` expected === "" || actual === expected || actual.endsWith("." + expected);`,
|
|
2236
|
+
`const _nmsReferenceId = (value: unknown, expectedType: string, workspace: string, field: string): string => {`,
|
|
2237
|
+
` if (typeof value !== "object" || value === null) throw new TypeError(field + " must be a NomosRef");`,
|
|
2238
|
+
` const ref = value as { workspace?: unknown; type?: unknown; id?: unknown };`,
|
|
2239
|
+
` if (typeof ref.id !== "string" || ref.id.length === 0 || typeof ref.type !== "string" || ref.type.length === 0 || typeof ref.workspace !== "string" || ref.workspace.length === 0) throw new TypeError(field + " must carry a complete NomosRef { workspace, type, id }");`,
|
|
2240
|
+
` if (!_nmsReferenceTypeMatches(ref.type, expectedType)) throw new TypeError(field + " refers to " + ref.type + "; expected " + expectedType);`,
|
|
2241
|
+
` if (workspace !== "" && ref.workspace !== workspace) throw new TypeError(field + " belongs to workspace " + ref.workspace + "; this call is bound to " + workspace);`,
|
|
2242
|
+
` return ref.id;`,
|
|
2243
|
+
`};`,
|
|
2244
|
+
...operatorEncoders.flatMap((entry) => entry.encoder.source),
|
|
2245
|
+
...capabilityReceipts.flatMap((entry) => entry.encoder.source),
|
|
2246
|
+
`export const nomosFrameworkCalls = {`,
|
|
2247
|
+
...[...new Set(operatorDefinitions.map((entry) => entry.group))].flatMap(
|
|
2248
|
+
(group) => [
|
|
2249
|
+
` ${group}: {`,
|
|
2250
|
+
...operatorDefinitions
|
|
2251
|
+
.filter((entry) => entry.group === group)
|
|
2252
|
+
.flatMap((definition) => {
|
|
2253
|
+
const alternatives = operatorEncoders.filter(
|
|
2254
|
+
(entry) => entry.group === group && entry.kind === definition.kind
|
|
2255
|
+
);
|
|
2256
|
+
const domainType = alternatives
|
|
2257
|
+
.map((entry) => JSON.stringify(entry.domain))
|
|
2258
|
+
.join(" | ") || "never";
|
|
2259
|
+
return [
|
|
2260
|
+
` ${definition.kind}(input: { readonly domain: ${domainType}; readonly workspace: string } & ${definition.payloadType}): NomosFrameworkCall<${domainType}, ${JSON.stringify(definition.directiveId)}> {`,
|
|
2261
|
+
` const { domain, workspace, ...payload } = input;`,
|
|
2262
|
+
` switch (domain) {`,
|
|
2263
|
+
...alternatives
|
|
2264
|
+
.map(
|
|
2265
|
+
(entry) =>
|
|
2266
|
+
` case ${JSON.stringify(entry.domain)}: return ${entry.encoder.functionName}(payload, workspace);`
|
|
2267
|
+
),
|
|
2268
|
+
` default: throw new Error("The compiled application has no '${definition.kind}' call in domain '" + domain + "'.");`,
|
|
2269
|
+
` }`,
|
|
2270
|
+
` },`,
|
|
2271
|
+
];
|
|
2272
|
+
}),
|
|
2273
|
+
` },`,
|
|
2274
|
+
]
|
|
2275
|
+
),
|
|
2276
|
+
`} as const;`,
|
|
2277
|
+
`export const nomosCapabilityReceipts = {`,
|
|
2278
|
+
...[...new Set(capabilityReceipts.map((entry) => entry.domain))].flatMap((domain) => [
|
|
2279
|
+
` ${tsKey(domain)}: {`,
|
|
2280
|
+
...capabilityReceipts
|
|
2281
|
+
.filter((entry) => entry.domain === domain)
|
|
2282
|
+
.flatMap((entry) => [
|
|
2283
|
+
` ${tsKey(entry.directiveId)}(input: { readonly workspace: string } & ${entry.payloadType}): NomosFrameworkCall<${JSON.stringify(domain)}, ${JSON.stringify(entry.directiveId)}> {`,
|
|
2284
|
+
` const { workspace, ...payload } = input;`,
|
|
2285
|
+
` return ${entry.encoder.functionName}(payload, workspace);`,
|
|
2286
|
+
` },`,
|
|
2287
|
+
]),
|
|
2288
|
+
` },`,
|
|
2289
|
+
]),
|
|
2290
|
+
`} as const;`,
|
|
2291
|
+
``,
|
|
2292
|
+
].join("\n");
|
|
2293
|
+
}
|
|
2139
2294
|
out.push(
|
|
2140
2295
|
`// AUTO-GENERATED by nomos-compile — typed TS application implementation for package "${opts.packageName}".`,
|
|
2141
2296
|
`// Regenerated on every compile; do not edit. Framework binding types below are deliberately private:`,
|
|
@@ -5646,6 +5646,9 @@ async function main(): Promise<void> {
|
|
|
5646
5646
|
const headlessClientDeclarationPath = path.join(outDir, `${cfg.name}.headless.d.mts`);
|
|
5647
5647
|
const operatorPath = path.join(outDir, `${cfg.name}.operator.mjs`);
|
|
5648
5648
|
const operatorDeclarationPath = path.join(outDir, `${cfg.name}.operator.d.mts`);
|
|
5649
|
+
const frameworkOperatorPath = path.join(outDir, `${cfg.name}.framework.mjs`);
|
|
5650
|
+
const frameworkOperatorDeclarationPath = path.join(outDir, `${cfg.name}.framework.d.mts`);
|
|
5651
|
+
const frameworkOperatorSourcePath = path.join(outDir, `${cfg.name}.framework.ts`);
|
|
5649
5652
|
const clientOptions = {
|
|
5650
5653
|
packageName: cfg.name,
|
|
5651
5654
|
domainHash,
|
|
@@ -5665,6 +5668,10 @@ async function main(): Promise<void> {
|
|
|
5665
5668
|
exportHolonFactory: true,
|
|
5666
5669
|
});
|
|
5667
5670
|
const operatorSource = generateTsLifecycleOperator(clientOptions.callUsda);
|
|
5671
|
+
const frameworkOperatorSource = generateTsClient(presentationDomainModules, {
|
|
5672
|
+
...clientOptions,
|
|
5673
|
+
frameworkOperatorOnly: true,
|
|
5674
|
+
});
|
|
5668
5675
|
const runtimePath = path.join(DSL_DIR, "runtime", "generated-application-host.js");
|
|
5669
5676
|
if (!existsSync(runtimePath)) {
|
|
5670
5677
|
fail("the compiler-private generated application runtime is missing — reinstall @githolon/dsl");
|
|
@@ -6050,6 +6057,43 @@ async function main(): Promise<void> {
|
|
|
6050
6057
|
rmSync(operatorPath, { force: true });
|
|
6051
6058
|
rmSync(operatorDeclarationPath, { force: true });
|
|
6052
6059
|
}
|
|
6060
|
+
const frameworkOperatorDeclaration = ts.transpileDeclaration(frameworkOperatorSource, {
|
|
6061
|
+
fileName: `${cfg.name}.framework.ts`,
|
|
6062
|
+
compilerOptions: {
|
|
6063
|
+
target: ts.ScriptTarget.ES2022,
|
|
6064
|
+
module: ts.ModuleKind.ESNext,
|
|
6065
|
+
strict: true,
|
|
6066
|
+
},
|
|
6067
|
+
reportDiagnostics: true,
|
|
6068
|
+
});
|
|
6069
|
+
const frameworkOperatorErrors = (frameworkOperatorDeclaration.diagnostics ?? []).filter(
|
|
6070
|
+
(diagnostic) => diagnostic.category === ts.DiagnosticCategory.Error,
|
|
6071
|
+
);
|
|
6072
|
+
if (frameworkOperatorErrors.length > 0) {
|
|
6073
|
+
fail(`generated TypeScript framework operator declarations are invalid — this is a Nomos codegen bug:\n${frameworkOperatorErrors.map((diagnostic) => ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n")).join("\n")}`);
|
|
6074
|
+
}
|
|
6075
|
+
writeFileSync(frameworkOperatorDeclarationPath, frameworkOperatorDeclaration.outputText, "utf8");
|
|
6076
|
+
writeFileSync(frameworkOperatorSourcePath, frameworkOperatorSource, "utf8");
|
|
6077
|
+
await esbuildMod.build({
|
|
6078
|
+
stdin: {
|
|
6079
|
+
contents: frameworkOperatorSource,
|
|
6080
|
+
loader: "ts",
|
|
6081
|
+
resolveDir: outDir,
|
|
6082
|
+
sourcefile: `${cfg.name}.framework.ts`,
|
|
6083
|
+
},
|
|
6084
|
+
outfile: frameworkOperatorPath,
|
|
6085
|
+
bundle: true,
|
|
6086
|
+
platform: "neutral",
|
|
6087
|
+
format: "esm",
|
|
6088
|
+
target: "es2022",
|
|
6089
|
+
legalComments: "none",
|
|
6090
|
+
logLevel: "silent",
|
|
6091
|
+
});
|
|
6092
|
+
writeFileSync(
|
|
6093
|
+
frameworkOperatorPath,
|
|
6094
|
+
canonicalizeGeneratedClientJavascript(readFileSync(frameworkOperatorPath, "utf8")),
|
|
6095
|
+
"utf8",
|
|
6096
|
+
);
|
|
6053
6097
|
} catch (e) {
|
|
6054
6098
|
fail(`generated TypeScript application could not be sealed — this is a Nomos codegen bug: ${(e as Error).message}`);
|
|
6055
6099
|
} finally {
|
|
@@ -199,8 +199,20 @@ function readCurrentAuthProviderRows() {
|
|
|
199
199
|
try {
|
|
200
200
|
return readFrameworkDeclaredRows(authProvider, AuthProvider, { scope: "platform" });
|
|
201
201
|
} catch (error) {
|
|
202
|
-
|
|
203
|
-
|
|
202
|
+
// Law plans execute in the deterministic VM, not in the compiler's Node
|
|
203
|
+
// realm. Imported class identity therefore cannot be used as an
|
|
204
|
+
// `instanceof` discriminator here: the compiler may carry the property
|
|
205
|
+
// path without carrying a constructible host class. Zod's issue list is
|
|
206
|
+
// already the nominal failure disclosure we need; inspect that bounded
|
|
207
|
+
// shape without depending on host-realm prototype identity.
|
|
208
|
+
const issues = error !== null && typeof error === "object" &&
|
|
209
|
+
"issues" in error && Array.isArray(error.issues)
|
|
210
|
+
? error.issues
|
|
211
|
+
: [];
|
|
212
|
+
if (issues.some((issue: unknown) =>
|
|
213
|
+
issue !== null && typeof issue === "object" &&
|
|
214
|
+
"code" in issue && issue.code === "unrecognized_keys" &&
|
|
215
|
+
"keys" in issue && Array.isArray(issue.keys) && issue.keys.includes("keys")
|
|
204
216
|
)) {
|
|
205
217
|
throw new Error(
|
|
206
218
|
"the AuthProvider still uses the historical serialized key field; migrate it to a typed keySet first",
|
|
@@ -18,9 +18,10 @@ import {
|
|
|
18
18
|
seedReceivingGroupPolicy,
|
|
19
19
|
} from "./framework/home.js";
|
|
20
20
|
import { enrollDelegation, enrollFirstDevice, enrollSigner } from "./framework/signing_identity.js";
|
|
21
|
+
import { grantAdmin } from "./framework/workspaces.js";
|
|
21
22
|
|
|
22
23
|
export interface FixedFrameworkCallDefinition {
|
|
23
|
-
readonly group: "identity" | "lifecycle" | "birth";
|
|
24
|
+
readonly group: "identity" | "governance" | "lifecycle" | "birth";
|
|
24
25
|
readonly kind: string;
|
|
25
26
|
readonly directive: Directive<any>;
|
|
26
27
|
/** Needed by the pre-bind Dart birth ceremony before an application exists. */
|
|
@@ -40,6 +41,7 @@ export const fixedFrameworkCallDefinitions: readonly FixedFrameworkCallDefinitio
|
|
|
40
41
|
{ group: "identity", kind: "enrollSigner", directive: enrollSigner, dartBirth: true, requiredApplicationHome: true },
|
|
41
42
|
{ group: "identity", kind: "setAuthProvider", directive: setAuthProvider, requiredApplicationHome: true },
|
|
42
43
|
{ group: "identity", kind: "birthReceivingGroup", directive: receivingGroupBirth, dartBirth: true, requiredApplicationHome: true },
|
|
44
|
+
{ group: "governance", kind: "grantAdmin", directive: grantAdmin },
|
|
43
45
|
{ group: "lifecycle", kind: "installDomain", directive: installDomain },
|
|
44
46
|
{ group: "lifecycle", kind: "stageDomain", directive: stageDomain },
|
|
45
47
|
{ group: "lifecycle", kind: "promoteDomain", directive: promoteDomain },
|