@githolon/dsl 0.107.4 → 0.108.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/dart/CHANGELOG.md +24 -0
  2. package/dart/lib/src/application_framework_calls.dart +299 -0
  3. package/dart/lib/src/generated_call.dart +96 -0
  4. package/dart/lib/src/nms_generated_runtime.dart +29 -0
  5. package/dart/lib/src/node_runner_transport.dart +77 -1
  6. package/dart/lib/src/result_usda.dart +487 -0
  7. package/dart/lib/src/runner/node-entry.mjs +10634 -6122
  8. package/dart/lib/src/runner/offline-install.mjs +4187 -2716
  9. package/dart/lib/src/runtime_v2_gateway.dart +54 -0
  10. package/dart/lib/src/runtime_v2_transport.dart +117 -0
  11. package/dart/lib/src/session_bound.dart +7 -2
  12. package/dart/lib/src/test_harness.dart +373 -282
  13. package/dart/lib/src/webview_bridge.dart +2146 -725
  14. package/dart/pubspec.lock +17 -1
  15. package/dart/pubspec.yaml +3 -2
  16. package/dart/test/acquire_session_credentials_test.dart +1 -1
  17. package/dart/test/acquire_session_test.dart +68 -14
  18. package/dart/test/adv_realm_interference_test.dart +6 -4
  19. package/dart/test/cluster_births_test.dart +11 -8
  20. package/dart/test/cluster_local_autosync_test.dart +1 -1
  21. package/dart/test/cluster_scale_test.dart +3 -2
  22. package/dart/test/dlq_session_surface_test.dart +52 -35
  23. package/dart/test/first_app_gauntlet_test.dart +1 -1
  24. package/dart/test/local_sync_inert_test.dart +23 -26
  25. package/dart/test/offer_authentication_proof_test.dart +193 -0
  26. package/dart/test/result_usda_test.dart +49 -0
  27. package/dart/test/session_bound_test.dart +8 -11
  28. package/dart/test/stale_bundle_test.dart +18 -3
  29. package/dart/test/test_harness_test.dart +14 -27
  30. package/dart/test/webview_bridge_test.dart +504 -83
  31. package/dart_types/CHANGELOG.md +17 -0
  32. package/dart_types/lib/nomos_kernel_protocol.dart +11 -0
  33. package/dart_types/lib/src/custody.dart +64 -19
  34. package/dart_types/lib/src/local_work_rejected.dart +30 -45
  35. package/dart_types/lib/src/proto/nomos/custody/v1/snapshot.pb.dart +169 -0
  36. package/dart_types/lib/src/proto/nomos/custody/v1/snapshot.pbenum.dart +11 -0
  37. package/dart_types/lib/src/proto/nomos/kernel/v1/kernel.pb.dart +17945 -0
  38. package/dart_types/lib/src/proto/nomos/kernel/v1/kernel.pbenum.dart +933 -0
  39. package/dart_types/lib/src/proto/nomos/kernel/v1/progress.pb.dart +245 -0
  40. package/dart_types/lib/src/proto/nomos/kernel/v1/progress.pbenum.dart +160 -0
  41. package/dart_types/lib/src/proto/nomos/runtime/v2/runtime.pb.dart +8664 -0
  42. package/dart_types/lib/src/proto/nomos/runtime/v2/runtime.pbenum.dart +369 -0
  43. package/dart_types/lib/src/surfaced.dart +30 -25
  44. package/dart_types/pubspec.lock +16 -0
  45. package/dart_types/pubspec.yaml +3 -1
  46. package/dart_types/test/surfaced_test.dart +2 -1
  47. package/package.json +1 -1
  48. package/runtime/generated-application-host.js +5760 -1879
  49. package/src/authoring.ts +3 -2
  50. package/src/birth_meter_ensure.ts +2 -0
  51. package/src/births.ts +21 -0
  52. package/src/build_package.ts +30 -0
  53. package/src/business_birth.ts +41 -35
  54. package/src/codegen_call_usda.ts +1111 -0
  55. package/src/codegen_dart.ts +207 -282
  56. package/src/codegen_dart_application.ts +195 -252
  57. package/src/codegen_dart_client.ts +1978 -593
  58. package/src/codegen_dart_framework_calls.ts +291 -0
  59. package/src/codegen_dart_scenario.ts +7 -0
  60. package/src/codegen_proof.ts +3 -4
  61. package/src/codegen_provider_dart.ts +21 -7
  62. package/src/codegen_query_usda.ts +214 -0
  63. package/src/codegen_result_usda.ts +685 -0
  64. package/src/codegen_ts.ts +3945 -1111
  65. package/src/compile_package_main.ts +392 -46
  66. package/src/directive.ts +19 -4
  67. package/src/engine_entry.ts +45 -4
  68. package/src/framework/application_home.ts +4 -0
  69. package/src/framework/auth_provider_law.ts +296 -20
  70. package/src/framework/birth_certificate_law.ts +24 -0
  71. package/src/framework/home.ts +83 -40
  72. package/src/framework/owned_custody.ts +25 -12
  73. package/src/framework/owned_custody_value.ts +51 -0
  74. package/src/framework/relations.ts +47 -21
  75. package/src/framework/signing_identity.ts +100 -17
  76. package/src/framework/workspaces.ts +39 -10
  77. package/src/framework_call_definitions.ts +53 -0
  78. package/src/framework_read_definitions.ts +45 -0
  79. package/src/identity_frontier.ts +58 -0
  80. package/src/index.ts +22 -1
  81. package/src/intent.ts +216 -16
  82. package/src/law_check.ts +19 -1
  83. package/src/law_graph.ts +57 -8
  84. package/src/law_graph_usda.ts +73 -5
  85. package/src/law_value_type.ts +106 -19
  86. package/src/read.ts +47 -0
  87. package/src/read_projection_namespace.ts +7 -0
  88. package/src/shape_compat.ts +44 -42
  89. package/src/stable_ids.ts +37 -2
  90. package/src/test_call_usda.ts +83 -0
  91. package/src/wire.ts +36 -2
  92. package/src/wire_encode.ts +45 -1
  93. package/src/workspace_sharing.ts +27 -10
@@ -20,6 +20,8 @@
20
20
  * LATER coordinated migration — we target the current serde_json shape now.
21
21
  */
22
22
  import type { z } from "zod";
23
+ import { voMetaOf } from "./value_object.js";
24
+ import { OwnedCustodyValue, OwnedDeviceRequestValue } from "./framework/owned_custody_value.js";
23
25
 
24
26
  import { encodeDriver } from "./drivers.js";
25
27
  import { __qualifyAggregateType, __setDispatchDomain } from "./framework/relations.js";
@@ -40,6 +42,7 @@ import {
40
42
  } from "./aggregate.js";
41
43
  import { admitsNull, type Field, type EvidenceRefValue } from "./fields.js";
42
44
  import type { Directive, ReferentialMarker } from "./directive.js";
45
+ import { isBusinessIntent } from "./intent.js";
43
46
  import type { PlannedOp, FieldOp } from "./ops.js";
44
47
  import { deterministicPorts, type Ports } from "./ctx.js";
45
48
  import type { PrincipalFacet } from "./principal_evidence.js";
@@ -174,6 +177,15 @@ function encodeKernelValue(field: Field | undefined, value: unknown, op?: FieldO
174
177
  },
175
178
  };
176
179
  }
180
+ // Framework-owned custody is a nominal kernel value. It uses the same authored value-object
181
+ // descriptor as generated TS/Dart clients, but never falls through to the tenant `Json` escape
182
+ // hatch merely because value objects currently share the DSL's wholesale-LWW field kind.
183
+ if (field?.kind === "json" && voMetaOf(field.zod)?.name === OwnedCustodyValue.name) {
184
+ return { OwnedCustody: OwnedCustodyValue.zod.parse(value) };
185
+ }
186
+ if (field?.kind === "json" && voMetaOf(field.zod)?.name === OwnedDeviceRequestValue.name) {
187
+ return { OwnedDeviceRequest: OwnedDeviceRequestValue.zod.parse(value) };
188
+ }
177
189
  // A `t.json()` leaf lowers to the FIRST-CLASS kernel `Value::Json` (RFC 8785 / JCS), NOT a
178
190
  // `Value::Str` holding JSON-shaped text. Checked BEFORE the scalar fallthroughs so EVERY json
179
191
  // value — object, array, string, number, boolean, null — commits as one consistent value kind
@@ -321,6 +333,7 @@ export function executeDirectiveToIntent<P>(
321
333
  agg: AggregateHandle,
322
334
  payload: NoInfer<P>,
323
335
  ctx: Ports,
336
+ encodeWorkspaceEffect?: (target: Directive<unknown>, payload: unknown, workspace: string) => Uint8Array,
324
337
  ): WireIntent {
325
338
  if (directive.aggregateId !== agg.id) {
326
339
  throw new Error(
@@ -373,7 +386,7 @@ export function executeDirectiveToIntent<P>(
373
386
  ctx,
374
387
  String(hlc.physical),
375
388
  typeof ownedKeySubject === "string" ? ownedKeySubject : undefined,
376
- typeof ownedCustody === "string" ? ownedCustody : null,
389
+ ownedCustody === undefined ? null : OwnedCustodyValue.zod.parse(ownedCustody),
377
390
  preMintedRecords,
378
391
  );
379
392
  __resetReads();
@@ -405,6 +418,36 @@ export function executeDirectiveToIntent<P>(
405
418
  for (const b of births) meterOps.push(...planBirthRecordOps(b, subject, bornAt));
406
419
  }
407
420
  const planned = [...__drainAuthoring(), ...returned, ...meterOps];
421
+ const workspaceEffects = isBusinessIntent(directive)
422
+ ? directive.workspaceEffects.map((effect) => {
423
+ if (encodeWorkspaceEffect === undefined) {
424
+ throw new Error(
425
+ `Directive '${directive.id}' declares a workspace effect, but its compiled plan has no target-call encoder`,
426
+ );
427
+ }
428
+ const workspace = effect.destination.kind === "workspace"
429
+ ? effect.destination.address(parsed)
430
+ : "";
431
+ if (effect.destination.kind === "workspace" && workspace.trim().length === 0) {
432
+ throw new Error(`Directive '${directive.id}' produced an empty target workspace address`);
433
+ }
434
+ const targetPayload = effect.target.payloadSchema.parse(effect.payload(parsed));
435
+ return {
436
+ destination: effect.destination.kind === "workspace"
437
+ ? { workspace }
438
+ : effect.destination.kind === "verifiedParent"
439
+ ? { verifiedParent: true as const }
440
+ : { verifiedSource: true as const },
441
+ targetCallUsda: encodeWorkspaceEffect(
442
+ effect.target as Directive<unknown>,
443
+ targetPayload,
444
+ workspace,
445
+ ),
446
+ };
447
+ })
448
+ : [];
449
+ // Workspace-effect payload mappers are source law and may perform declared captured reads while
450
+ // constructing the target payload. Drain only after both local and cross-workspace consequences.
408
451
  const reads = __drainReads();
409
452
 
410
453
  // Partition the plan output: STRIKE ops route onto the intent's `strikes` channel
@@ -523,6 +566,7 @@ export function executeDirectiveToIntent<P>(
523
566
  ...(reads.length ? { reads } : {}),
524
567
  ...(endorse.length ? { endorse } : {}),
525
568
  ...(births.length ? { births } : {}),
569
+ ...(workspaceEffects.length ? { workspaceEffects } : {}),
526
570
  };
527
571
  }
528
572
 
@@ -60,6 +60,32 @@ export interface WorkspaceSharingInvitationLaw {
60
60
  readonly pendingByRecipient: QueryDecl;
61
61
  }
62
62
 
63
+ /** The one framework-owned invitation redemption payload. Individual business
64
+ * sharing policies choose the directive id and projection fields, but never a
65
+ * second wire shape. Compiler and host contracts are generated from this same
66
+ * schema. */
67
+ export const workspaceSharingInvitationRedeemPayload = z.object({
68
+ orderId: z.string().min(1),
69
+ object: z.string().min(1),
70
+ relation: z.string().min(1),
71
+ invitationPublicKey: z.string().regex(/^[A-Za-z0-9+/]+={0,2}$/, "expected base64"),
72
+ invitationSignature: z.string().regex(/^[A-Za-z0-9+/]+={0,2}$/, "expected base64"),
73
+ invitationId: z.string().regex(/^nomos-invitation-[0-9a-f]{64}$/),
74
+ redeemedAt: z.string().min(1),
75
+ });
76
+
77
+ /** The private bearer material transported in an invitation URL fragment.
78
+ * This is canonical USDA, not a JSON web protocol. The literal is part of the
79
+ * typed framework schema so both generated clients refuse another generation. */
80
+ export const WORKSPACE_SHARING_INVITATION_FORMAT = "nomos-invitation-v1" as const;
81
+
82
+ export const workspaceSharingInvitationMaterialPayload = z.object({
83
+ format: z.literal(WORKSPACE_SHARING_INVITATION_FORMAT),
84
+ source: z.string().min(1),
85
+ secret: z.string().min(1),
86
+ publicKey: z.string().min(1),
87
+ });
88
+
63
89
  /**
64
90
  * Fold the generated invitation law into the same export bag consumed by both
65
91
  * package composition and the executable engine registry. Keeping one seam is
@@ -189,19 +215,10 @@ export function workspaceSharing(options: WorkspaceSharingOptions): WorkspaceSha
189
215
  .returns(options.orders),
190
216
  businessBirthInternal: true as const,
191
217
  };
192
- const b64 = z.string().regex(/^[A-Za-z0-9+/]+={0,2}$/, "expected base64");
193
218
  const redeem = nomosImplementationDetail({
194
219
  ...directive(redeemId)
195
220
  .mutates(options.orders)
196
- .payload(z.object({
197
- orderId: z.string().min(1),
198
- object: z.string().min(1),
199
- relation: z.string().min(1),
200
- invitationPublicKey: b64,
201
- invitationSignature: b64,
202
- invitationId: z.string().regex(/^nomos-invitation-[0-9a-f]{64}$/),
203
- redeemedAt: z.string().min(1),
204
- }))
221
+ .payload(workspaceSharingInvitationRedeemPayload)
205
222
  .plan((facts, ctx) => {
206
223
  const principal = endorsementOf(ctx.principal().asAttribution())?.principal ?? "";
207
224
  const claim = instance(NomosInvitationClaim, facts.invitationId);