@githolon/dsl 0.108.4 → 0.108.7
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/application_framework_calls.dart +21 -0
- package/dart/lib/src/dev_cloud.dart +67 -0
- package/dart/lib/src/nms_test_environment.dart +1 -1
- package/dart/lib/src/runner/node-entry.mjs +354 -104
- package/dart/lib/src/runner/offline-install.mjs +64 -8
- package/dart/lib/src/session_bound.dart +58 -30
- package/dart/lib/src/test_harness.dart +60 -98
- package/dart/lib/src/webview_bridge.dart +212 -32
- package/dart/pubspec.lock +1 -1
- package/dart/pubspec.yaml +2 -2
- package/dart/test/node_runner_transport_test.dart +5 -5
- package/dart/test/webview_bridge_test.dart +6 -0
- package/dart_types/CHANGELOG.md +4 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/runtime.pb.dart +428 -2
- package/dart_types/pubspec.yaml +1 -1
- package/package.json +1 -1
- package/runtime/generated-application-host.js +293 -79
- package/src/application_topology.ts +120 -28
- package/src/births.ts +27 -0
- package/src/codegen_call_usda.ts +9 -4
- package/src/codegen_dart_application.ts +146 -37
- package/src/codegen_dart_client.ts +225 -160
- package/src/codegen_dart_framework_calls.ts +89 -4
- package/src/codegen_ts.ts +135 -60
- package/src/compile_package_main.ts +3598 -1484
- package/src/directive.ts +320 -118
- package/src/fields.ts +2 -3
- package/src/framework/application_home.ts +3 -0
- package/src/framework/auth_provider_law.ts +20 -28
- package/src/framework/genesis.ts +32 -1
- package/src/framework/home.ts +45 -8
- package/src/framework/signing_identity.ts +78 -0
- package/src/framework/workspaces.ts +9 -1
- package/src/framework_call_dart_enums.ts +33 -0
- package/src/framework_call_definitions.ts +11 -2
- package/src/index.ts +12 -0
- package/src/intent.ts +525 -194
- package/src/law_graph.ts +32 -4
- package/src/law_graph_usda.ts +3 -0
- package/src/package_config.ts +16 -1
- package/src/read.ts +33 -11
- package/src/wire.ts +1 -0
- package/src/wire_encode.ts +3 -3
|
@@ -10,7 +10,9 @@ import {
|
|
|
10
10
|
type DartCallUsdaFieldAccess,
|
|
11
11
|
} from "./codegen_call_usda.js";
|
|
12
12
|
import type { LawGraph } from "./law_graph.js";
|
|
13
|
+
import { isBusinessIntent } from "./intent.js";
|
|
13
14
|
import { fixedFrameworkCallDefinitions } from "./framework_call_definitions.js";
|
|
15
|
+
import { collectFixedFrameworkDartEnums } from "./framework_call_dart_enums.js";
|
|
14
16
|
import { APPLICATION_HOME_DOMAIN } from "./framework/application_home_domain.js";
|
|
15
17
|
import { workspaceSharingInvitationRedeemPayload } from "./workspace_sharing.js";
|
|
16
18
|
import { zodArrayElement, zodDef, zodObjectShape } from "./zod_introspection.js";
|
|
@@ -104,6 +106,7 @@ export interface DartFrameworkCallLaw {
|
|
|
104
106
|
export function generateDartApplicationFrameworkCalls(
|
|
105
107
|
laws: readonly DartFrameworkCallLaw[],
|
|
106
108
|
): string | undefined {
|
|
109
|
+
const frameworkEnumDartTypes = collectFixedFrameworkDartEnums().dartTypes;
|
|
107
110
|
const fixedEmitted = FIXED_CALLS.flatMap((definition) => laws.flatMap((law) => {
|
|
108
111
|
const declares = law.graph.nodes.some((node) =>
|
|
109
112
|
node.kind === "intent" &&
|
|
@@ -118,7 +121,7 @@ export function generateDartApplicationFrameworkCalls(
|
|
|
118
121
|
}
|
|
119
122
|
const fields = introspectPayload(
|
|
120
123
|
directive.payloadSchema as z.ZodTypeAny,
|
|
121
|
-
|
|
124
|
+
frameworkEnumDartTypes,
|
|
122
125
|
);
|
|
123
126
|
const parameterType = (field: (typeof fields)[number]) => field.nullAdmits === true
|
|
124
127
|
? `NomosSlot<${field.dartType}>`
|
|
@@ -170,7 +173,67 @@ export function generateDartApplicationFrameworkCalls(
|
|
|
170
173
|
routeByDirective: true as const,
|
|
171
174
|
};
|
|
172
175
|
}));
|
|
173
|
-
|
|
176
|
+
// Existing-home device recovery is APPLICATION LAW, not a framework backdoor.
|
|
177
|
+
// Select it structurally from the composed graph: an enrolled-device-authored
|
|
178
|
+
// public intent with no local effects, directing one or more atomic effects through
|
|
179
|
+
// the target child's verified-birth-parent recovery door. A recovery may need to
|
|
180
|
+
// advance several typed child-owned facts together (for example policy, signer, and
|
|
181
|
+
// verifier epoch); every target must independently declare the narrow recovery door.
|
|
182
|
+
// The host never chooses an operation name and the compiler refuses an ambiguous or
|
|
183
|
+
// differently-shaped candidate.
|
|
184
|
+
const recoveryCandidates = laws.flatMap((law) =>
|
|
185
|
+
(law.module.applicationIntents ?? []).flatMap((candidate) => {
|
|
186
|
+
if (
|
|
187
|
+
!isBusinessIntent(candidate) ||
|
|
188
|
+
candidate.offerAuthenticationProof !== "enrolledDevice" ||
|
|
189
|
+
candidate.steps.length !== 0 ||
|
|
190
|
+
candidate.workspaceEffects.length === 0 ||
|
|
191
|
+
!candidate.workspaceEffects.every(
|
|
192
|
+
(effect) => effect.target.acceptsVerifiedBirthParentRecoveryGate === true,
|
|
193
|
+
)
|
|
194
|
+
) return [];
|
|
195
|
+
const fields = introspectPayload(candidate.contract.accepts, new Map());
|
|
196
|
+
if (
|
|
197
|
+
fields.length !== 1 ||
|
|
198
|
+
fields[0]!.name !== "user" ||
|
|
199
|
+
fields[0]!.dartType !== "String" ||
|
|
200
|
+
fields[0]!.shape !== "scalar" ||
|
|
201
|
+
fields[0]!.optional ||
|
|
202
|
+
fields[0]!.nullAdmits === true
|
|
203
|
+
) {
|
|
204
|
+
throw new Error(
|
|
205
|
+
`Dart framework call codegen: existing receiving-group recovery intent '${candidate.id}' must accept exactly { user: string }`,
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
const payloadType = `({String user})`;
|
|
209
|
+
const access = new Map<string, DartCallUsdaFieldAccess>([[
|
|
210
|
+
"user",
|
|
211
|
+
{ value: "payload.user" },
|
|
212
|
+
]]);
|
|
213
|
+
const encoder = emitDartCallUsdaEncoder(
|
|
214
|
+
law.graph,
|
|
215
|
+
law.paths,
|
|
216
|
+
law.graph.domain.entity.label,
|
|
217
|
+
candidate.id,
|
|
218
|
+
payloadType,
|
|
219
|
+
access,
|
|
220
|
+
);
|
|
221
|
+
return [{
|
|
222
|
+
kind: "recoverExistingReceivingGroupDevice",
|
|
223
|
+
directive: candidate.id,
|
|
224
|
+
domain: law.graph.domain.entity.label,
|
|
225
|
+
fields,
|
|
226
|
+
payloadType,
|
|
227
|
+
encoder,
|
|
228
|
+
routeByDirective: false as const,
|
|
229
|
+
}];
|
|
230
|
+
}));
|
|
231
|
+
if (recoveryCandidates.length > 1) {
|
|
232
|
+
throw new Error(
|
|
233
|
+
`Dart framework call codegen: application composes ${recoveryCandidates.length} existing receiving-group recovery intents; exactly one is allowed`,
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
const emitted = [...fixedEmitted, ...invitationEmitted, ...recoveryCandidates];
|
|
174
237
|
if (emitted.length === 0) return undefined;
|
|
175
238
|
|
|
176
239
|
const certificateEntry = emitted.find((entry) =>
|
|
@@ -211,7 +274,10 @@ export function generateDartApplicationFrameworkCalls(
|
|
|
211
274
|
.filter((definition) => definition.dartBirth === true)
|
|
212
275
|
.map((definition) => [
|
|
213
276
|
definition.kind,
|
|
214
|
-
introspectPayload(
|
|
277
|
+
introspectPayload(
|
|
278
|
+
definition.directive.payloadSchema as z.ZodTypeAny,
|
|
279
|
+
frameworkEnumDartTypes,
|
|
280
|
+
),
|
|
215
281
|
] as const),
|
|
216
282
|
);
|
|
217
283
|
// The runtime interface is deliberately exhaustive. A composed application implements every
|
|
@@ -221,10 +287,29 @@ export function generateDartApplicationFrameworkCalls(
|
|
|
221
287
|
...fixedFrameworkCallDefinitions
|
|
222
288
|
.filter((definition) => definition.dartBirth === true)
|
|
223
289
|
.map((definition) => definition.kind),
|
|
290
|
+
"recoverExistingReceivingGroupDevice",
|
|
224
291
|
"redeemInvitation",
|
|
225
292
|
])].flatMap((kind) => {
|
|
226
293
|
const alternatives = emitted.filter((entry) => entry.kind === kind);
|
|
227
|
-
const fields = alternatives[0]?.fields ?? fixedMethodFields.get(kind) ??
|
|
294
|
+
const fields = alternatives[0]?.fields ?? fixedMethodFields.get(kind) ??
|
|
295
|
+
(kind === "recoverExistingReceivingGroupDevice"
|
|
296
|
+
? [{ name: "user", dartType: "String", shape: "scalar", optional: false } satisfies PayloadFieldSpec]
|
|
297
|
+
: invitationContractFields);
|
|
298
|
+
if (kind === "recoverExistingReceivingGroupDevice") {
|
|
299
|
+
const recovery = alternatives[0];
|
|
300
|
+
return [
|
|
301
|
+
` @override`,
|
|
302
|
+
` NmsGeneratedCall recoverExistingReceivingGroupDevice({required String user}) {`,
|
|
303
|
+
...(recovery === undefined
|
|
304
|
+
? [` throw StateError("The compiled application has no existing receiving-group device recovery law.");`]
|
|
305
|
+
: [
|
|
306
|
+
` final payload = (user: user,);`,
|
|
307
|
+
` return ${recovery.encoder.functionName}(payload);`,
|
|
308
|
+
]),
|
|
309
|
+
` }`,
|
|
310
|
+
``,
|
|
311
|
+
];
|
|
312
|
+
}
|
|
228
313
|
const routeByDirective = kind === "redeemInvitation" || alternatives.some((entry) => entry.routeByDirective);
|
|
229
314
|
const parameterType = (field: (typeof fields)[number]) => field.nullAdmits === true
|
|
230
315
|
? `NomosSlot<${field.dartType}>`
|
package/src/codegen_ts.ts
CHANGED
|
@@ -955,7 +955,7 @@ function tsBaseTypeOfField(field: Field): string {
|
|
|
955
955
|
function tsQueryReferenceId(field: Field, expression: string): string {
|
|
956
956
|
if (field.kind !== "ref") {
|
|
957
957
|
throw new Error(
|
|
958
|
-
`TypeScript query codegen: '${expression}' is not a declared reference field
|
|
958
|
+
`TypeScript query codegen: '${expression}' is not a declared reference field`
|
|
959
959
|
);
|
|
960
960
|
}
|
|
961
961
|
return field.foreignRef !== undefined
|
|
@@ -1980,7 +1980,7 @@ export function generateTsClient(
|
|
|
1980
1980
|
.map((definition) => ({
|
|
1981
1981
|
group: definition.group,
|
|
1982
1982
|
kind: definition.kind,
|
|
1983
|
-
directiveId: definition.directive.id,
|
|
1983
|
+
directiveId: definition.routeId ?? definition.directive.id,
|
|
1984
1984
|
payloadType: tsTypeOfPayload(
|
|
1985
1985
|
definition.directive.payloadSchema as z.ZodTypeAny,
|
|
1986
1986
|
[]
|
|
@@ -2056,7 +2056,7 @@ export function generateTsClient(
|
|
|
2056
2056
|
];
|
|
2057
2057
|
const fixedFrameworkPayloadSchemas = new Map<string, z.ZodTypeAny>(
|
|
2058
2058
|
fixedFrameworkCallDefinitions.map((definition) => [
|
|
2059
|
-
definition.directive.id,
|
|
2059
|
+
definition.routeId ?? definition.directive.id,
|
|
2060
2060
|
definition.directive.payloadSchema as z.ZodTypeAny,
|
|
2061
2061
|
])
|
|
2062
2062
|
);
|
|
@@ -2140,19 +2140,27 @@ export function generateTsClient(
|
|
|
2140
2140
|
}
|
|
2141
2141
|
}
|
|
2142
2142
|
if (opts.frameworkOperatorOnly === true) {
|
|
2143
|
-
const fixedGroups = new Set([
|
|
2143
|
+
const fixedGroups = new Set([
|
|
2144
|
+
"identity",
|
|
2145
|
+
"governance",
|
|
2146
|
+
"lifecycle",
|
|
2147
|
+
"birth",
|
|
2148
|
+
]);
|
|
2144
2149
|
const operatorDefinitions = frameworkCallMethodDefinitions.filter(
|
|
2145
2150
|
(definition) => fixedGroups.has(definition.group)
|
|
2146
2151
|
);
|
|
2147
2152
|
const operatorEncoders = frameworkCallEncoders.filter((entry) =>
|
|
2148
2153
|
fixedGroups.has(entry.group)
|
|
2149
2154
|
);
|
|
2150
|
-
const capabilityReceiptByKey = new Map<
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2155
|
+
const capabilityReceiptByKey = new Map<
|
|
2156
|
+
string,
|
|
2157
|
+
{
|
|
2158
|
+
readonly domain: string;
|
|
2159
|
+
readonly directiveId: string;
|
|
2160
|
+
readonly payloadType: string;
|
|
2161
|
+
readonly encoder: ReturnType<typeof emitTsCallUsdaEncoder>;
|
|
2162
|
+
}
|
|
2163
|
+
>();
|
|
2156
2164
|
const capabilityReferenceTypes = new Set<string>();
|
|
2157
2165
|
for (const mod of modules) {
|
|
2158
2166
|
const domain = mod.domain ?? mod.name;
|
|
@@ -2166,18 +2174,20 @@ export function generateTsClient(
|
|
|
2166
2174
|
capability.block,
|
|
2167
2175
|
capability.deadLetter,
|
|
2168
2176
|
]) {
|
|
2169
|
-
const directive = authored.find(
|
|
2177
|
+
const directive = authored.find(
|
|
2178
|
+
(candidate) => candidate.id === receipt.id
|
|
2179
|
+
);
|
|
2170
2180
|
if (directive === undefined) {
|
|
2171
2181
|
throw new Error(
|
|
2172
|
-
`TypeScript capability receipt codegen: '${domain}/${receipt.id}' has no authored directive
|
|
2182
|
+
`TypeScript capability receipt codegen: '${domain}/${receipt.id}' has no authored directive`
|
|
2173
2183
|
);
|
|
2174
2184
|
}
|
|
2175
2185
|
const payloadType = tsTypeOfPayload(
|
|
2176
2186
|
directive.payloadSchema as z.ZodTypeAny,
|
|
2177
|
-
[]
|
|
2187
|
+
[]
|
|
2178
2188
|
);
|
|
2179
2189
|
for (const referenceType of payloadReferenceTypes(
|
|
2180
|
-
directive.payloadSchema as z.ZodTypeAny
|
|
2190
|
+
directive.payloadSchema as z.ZodTypeAny
|
|
2181
2191
|
)) {
|
|
2182
2192
|
capabilityReferenceTypes.add(referenceType);
|
|
2183
2193
|
}
|
|
@@ -2190,14 +2200,16 @@ export function generateTsClient(
|
|
|
2190
2200
|
law.paths,
|
|
2191
2201
|
domain,
|
|
2192
2202
|
receipt.id,
|
|
2193
|
-
payloadType
|
|
2203
|
+
payloadType
|
|
2194
2204
|
),
|
|
2195
2205
|
});
|
|
2196
2206
|
}
|
|
2197
2207
|
}
|
|
2198
2208
|
}
|
|
2199
|
-
const capabilityReceipts = [...capabilityReceiptByKey.values()].sort(
|
|
2200
|
-
left
|
|
2209
|
+
const capabilityReceipts = [...capabilityReceiptByKey.values()].sort(
|
|
2210
|
+
(left, right) =>
|
|
2211
|
+
left.domain.localeCompare(right.domain) ||
|
|
2212
|
+
left.directiveId.localeCompare(right.directiveId)
|
|
2201
2213
|
);
|
|
2202
2214
|
return [
|
|
2203
2215
|
`// AUTO-GENERATED by nomos-compile — exact framework operators for package "${opts.packageName}".`,
|
|
@@ -2216,9 +2228,14 @@ export function generateTsClient(
|
|
|
2216
2228
|
` readonly routingCandidates: readonly string[];`,
|
|
2217
2229
|
`}`,
|
|
2218
2230
|
`declare const _nomosAggregateType: unique symbol;`,
|
|
2219
|
-
...[...capabilityReferenceTypes]
|
|
2220
|
-
|
|
2221
|
-
|
|
2231
|
+
...[...capabilityReferenceTypes]
|
|
2232
|
+
.sort()
|
|
2233
|
+
.map(
|
|
2234
|
+
(id) =>
|
|
2235
|
+
`export type ${id} = { readonly [_nomosAggregateType]?: ${JSON.stringify(
|
|
2236
|
+
id
|
|
2237
|
+
)} };`
|
|
2238
|
+
),
|
|
2222
2239
|
`export interface NomosRef<TAggregate> {`,
|
|
2223
2240
|
` readonly [_nomosAggregateType]: (aggregate: TAggregate) => TAggregate;`,
|
|
2224
2241
|
` readonly workspace: string;`,
|
|
@@ -2251,42 +2268,59 @@ export function generateTsClient(
|
|
|
2251
2268
|
.filter((entry) => entry.group === group)
|
|
2252
2269
|
.flatMap((definition) => {
|
|
2253
2270
|
const alternatives = operatorEncoders.filter(
|
|
2254
|
-
(entry) =>
|
|
2271
|
+
(entry) =>
|
|
2272
|
+
entry.group === group && entry.kind === definition.kind
|
|
2255
2273
|
);
|
|
2256
|
-
const domainType =
|
|
2257
|
-
|
|
2258
|
-
|
|
2274
|
+
const domainType =
|
|
2275
|
+
alternatives
|
|
2276
|
+
.map((entry) => JSON.stringify(entry.domain))
|
|
2277
|
+
.join(" | ") || "never";
|
|
2259
2278
|
return [
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
.
|
|
2279
|
+
` ${
|
|
2280
|
+
definition.kind
|
|
2281
|
+
}(input: { readonly domain: ${domainType}; readonly workspace: string } & ${
|
|
2282
|
+
definition.payloadType
|
|
2283
|
+
}): NomosFrameworkCall<${domainType}, ${JSON.stringify(
|
|
2284
|
+
definition.directiveId
|
|
2285
|
+
)}> {`,
|
|
2286
|
+
` const { domain, workspace, ...payload } = input;`,
|
|
2287
|
+
` switch (domain) {`,
|
|
2288
|
+
...alternatives.map(
|
|
2265
2289
|
(entry) =>
|
|
2266
|
-
` case ${JSON.stringify(entry.domain)}: return ${
|
|
2290
|
+
` case ${JSON.stringify(entry.domain)}: return ${
|
|
2291
|
+
entry.encoder.functionName
|
|
2292
|
+
}(payload, workspace);`
|
|
2267
2293
|
),
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2294
|
+
` default: throw new Error("The compiled application has no '${definition.kind}' call in domain '" + domain + "'.");`,
|
|
2295
|
+
` }`,
|
|
2296
|
+
` },`,
|
|
2297
|
+
];
|
|
2272
2298
|
}),
|
|
2273
2299
|
` },`,
|
|
2274
2300
|
]
|
|
2275
2301
|
),
|
|
2276
2302
|
`} as const;`,
|
|
2277
2303
|
`export const nomosCapabilityReceipts = {`,
|
|
2278
|
-
...[...new Set(capabilityReceipts.map((entry) => entry.domain))].flatMap(
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2304
|
+
...[...new Set(capabilityReceipts.map((entry) => entry.domain))].flatMap(
|
|
2305
|
+
(domain) => [
|
|
2306
|
+
` ${tsKey(domain)}: {`,
|
|
2307
|
+
...capabilityReceipts
|
|
2308
|
+
.filter((entry) => entry.domain === domain)
|
|
2309
|
+
.flatMap((entry) => [
|
|
2310
|
+
` ${tsKey(
|
|
2311
|
+
entry.directiveId
|
|
2312
|
+
)}(input: { readonly workspace: string } & ${
|
|
2313
|
+
entry.payloadType
|
|
2314
|
+
}): NomosFrameworkCall<${JSON.stringify(
|
|
2315
|
+
domain
|
|
2316
|
+
)}, ${JSON.stringify(entry.directiveId)}> {`,
|
|
2317
|
+
` const { workspace, ...payload } = input;`,
|
|
2318
|
+
` return ${entry.encoder.functionName}(payload, workspace);`,
|
|
2319
|
+
` },`,
|
|
2320
|
+
]),
|
|
2321
|
+
` },`,
|
|
2322
|
+
]
|
|
2323
|
+
),
|
|
2290
2324
|
`} as const;`,
|
|
2291
2325
|
``,
|
|
2292
2326
|
].join("\n");
|
|
@@ -3514,10 +3548,7 @@ export function generateTsClient(
|
|
|
3514
3548
|
: ("string" as const),
|
|
3515
3549
|
value:
|
|
3516
3550
|
kind === "reference"
|
|
3517
|
-
? tsQueryReferenceId(
|
|
3518
|
-
field,
|
|
3519
|
-
`input[${JSON.stringify(key)}]`,
|
|
3520
|
-
)
|
|
3551
|
+
? tsQueryReferenceId(field, `input[${JSON.stringify(key)}]`)
|
|
3521
3552
|
: `input[${JSON.stringify(key)}]`,
|
|
3522
3553
|
kind,
|
|
3523
3554
|
};
|
|
@@ -5144,25 +5175,69 @@ export function generateTsClient(
|
|
|
5144
5175
|
`TypeScript source-trust codegen: '${domain}/${sourceTrust.viaDirectiveId}' has no nominal encoder`
|
|
5145
5176
|
);
|
|
5146
5177
|
}
|
|
5178
|
+
const satisfactionQuery =
|
|
5179
|
+
sourceTrust.satisfiedByQueryId === undefined
|
|
5180
|
+
? undefined
|
|
5181
|
+
: (mod.queries as QueryDecl[]).find(
|
|
5182
|
+
(query) => query.id === sourceTrust.satisfiedByQueryId
|
|
5183
|
+
);
|
|
5184
|
+
if (
|
|
5185
|
+
sourceTrust.satisfiedByQueryId !== undefined &&
|
|
5186
|
+
satisfactionQuery === undefined
|
|
5187
|
+
) {
|
|
5188
|
+
throw new Error(
|
|
5189
|
+
`TypeScript source-trust codegen: '${domain}/${d.id}' names missing satisfaction query '${sourceTrust.satisfiedByQueryId}'`
|
|
5190
|
+
);
|
|
5191
|
+
}
|
|
5192
|
+
if (
|
|
5193
|
+
satisfactionQuery !== undefined &&
|
|
5194
|
+
satisfactionQuery.returns !==
|
|
5195
|
+
authoredDirectivesByDomain
|
|
5196
|
+
.get(domain)
|
|
5197
|
+
?.find(
|
|
5198
|
+
(directive) => directive.id === sourceTrust.viaDirectiveId
|
|
5199
|
+
)?.aggregateId
|
|
5200
|
+
) {
|
|
5201
|
+
throw new Error(
|
|
5202
|
+
`TypeScript source-trust codegen: '${domain}/${d.id}' satisfaction query '${satisfactionQuery.id}' does not return the trust aggregate`
|
|
5203
|
+
);
|
|
5204
|
+
}
|
|
5205
|
+
const satisfactionArgs = sourceTrust.satisfiedByQueryArgs ?? {};
|
|
5206
|
+
if (
|
|
5207
|
+
satisfactionQuery !== undefined &&
|
|
5208
|
+
(satisfactionQuery.key.some(
|
|
5209
|
+
(key) => satisfactionArgs[key] === undefined
|
|
5210
|
+
) ||
|
|
5211
|
+
Object.keys(satisfactionArgs).some(
|
|
5212
|
+
(key) => !satisfactionQuery.key.includes(key)
|
|
5213
|
+
))
|
|
5214
|
+
) {
|
|
5215
|
+
throw new Error(
|
|
5216
|
+
`TypeScript source-trust codegen: '${domain}/${d.id}' satisfaction query '${satisfactionQuery.id}' has mismatched keys`
|
|
5217
|
+
);
|
|
5218
|
+
}
|
|
5219
|
+
// A typed satisfaction query makes source trust a law fact. The
|
|
5220
|
+
// kernel's foreign-read policy gates the single business offer;
|
|
5221
|
+
// the client must not query and silently grant authority first.
|
|
5222
|
+
if (satisfactionQuery !== undefined) return [];
|
|
5223
|
+
const indent = " ";
|
|
5147
5224
|
return [
|
|
5148
|
-
|
|
5225
|
+
`${indent}const _sourceWorkspace = String(${payloadPath(
|
|
5149
5226
|
inputPayload,
|
|
5150
5227
|
sourceTrust.fromPayload
|
|
5151
5228
|
)} ?? "");`,
|
|
5152
|
-
|
|
5229
|
+
`${indent}if (!_sourceWorkspace.trim()) throw new Error(${JSON.stringify(
|
|
5153
5230
|
`${d.id} needs a source workspace`
|
|
5154
5231
|
)});`,
|
|
5155
|
-
|
|
5156
|
-
|
|
5232
|
+
`${indent}const _sourceGenesis = await holon.__nomosWorkspaceGenesis(_sourceWorkspace);`,
|
|
5233
|
+
`${indent}const _sourceTrustCall = {`,
|
|
5157
5234
|
...copiedTrustFields,
|
|
5158
|
-
|
|
5235
|
+
`${indent} ${JSON.stringify(
|
|
5159
5236
|
sourceTrust.genesisField
|
|
5160
5237
|
)}: _sourceGenesis,`,
|
|
5161
|
-
|
|
5162
|
-
|
|
5163
|
-
)
|
|
5164
|
-
` } satisfies ${payloadType};`,
|
|
5165
|
-
` await _commit(holon.offerCall(${encoder}(_sourceTrustCall, holon.workspace), { domainHash, actor, returnCreated: true }) as Promise<_NomosRawWriteResult>);`,
|
|
5238
|
+
`${indent} ${JSON.stringify(sourceTrust.keyHashesField)}: [],`,
|
|
5239
|
+
`${indent}} satisfies ${payloadType};`,
|
|
5240
|
+
`${indent}await _commit(holon.offerCall(${encoder}(_sourceTrustCall, holon.workspace), { domainHash, actor, returnCreated: true }) as Promise<_NomosRawWriteResult>);`,
|
|
5166
5241
|
];
|
|
5167
5242
|
})();
|
|
5168
5243
|
const sealPrelude =
|