@githolon/dsl 0.113.4 → 0.114.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.
Files changed (58) hide show
  1. package/assets/operation-contract.wasm +0 -0
  2. package/compile_package.mjs +23 -3
  3. package/compile_proof.d.mts +7 -0
  4. package/compile_proof.mjs +38 -3
  5. package/dart/CHANGELOG.md +20 -0
  6. package/dart/lib/src/application_framework_calls.dart +9 -5
  7. package/dart/lib/src/generated_call.dart +14 -3
  8. package/dart/lib/src/nms_generated_runtime.dart +7 -0
  9. package/dart/lib/src/node_runner_transport.dart +77 -8
  10. package/dart/lib/src/nomos_trace.dart +107 -0
  11. package/dart/lib/src/reception/dart_reception.dart +148 -11
  12. package/dart/lib/src/rows_watch.dart +390 -0
  13. package/dart/lib/src/runner/node-entry.mjs +2803 -690
  14. package/dart/lib/src/sync_status_projection.dart +94 -1
  15. package/dart/lib/src/sync_status_reducer.dart +5 -2
  16. package/dart/lib/src/test_harness.dart +107 -41
  17. package/dart/lib/src/testing/test_peer.dart +107 -99
  18. package/dart/lib/src/testing/test_peer_host.dart +305 -0
  19. package/dart/lib/src/typed_watch_registry.dart +26 -3
  20. package/dart/pubspec.lock +1 -1
  21. package/dart/pubspec.yaml +2 -2
  22. package/dart/test/background_model_adoption_test.dart +1 -0
  23. package/dart/test/custodian_warming_test.dart +105 -0
  24. package/dart/test/fixtures/offer_watch_order_peer.dart +74 -0
  25. package/dart/test/kernel_author_after_read_test.dart +6 -3
  26. package/dart/test/kernel_fence_test.dart +4 -1
  27. package/dart/test/model_adoption_test.dart +17 -0
  28. package/dart/test/nomos_trace_test.dart +91 -0
  29. package/dart/test/own_offer_watch_order_test.dart +90 -0
  30. package/dart/test/receiving_group_open_test.dart +4 -8
  31. package/dart/test/replica_readiness_test.dart +14 -4
  32. package/dart/test/rows_watch_test.dart +331 -0
  33. package/dart/test/test_peer_host_selection_test.dart +49 -0
  34. package/dart_types/CHANGELOG.md +15 -0
  35. package/dart_types/lib/src/approved_model.dart +22 -5
  36. package/dart_types/lib/src/proto/nomos/kernel/v1/kernel.pb.dart +535 -1
  37. package/dart_types/lib/src/proto/nomos/kernel/v1/kernel.pbenum.dart +65 -0
  38. package/dart_types/lib/src/proto/nomos/runtime/v2/application_desk.pb.dart +14 -0
  39. package/dart_types/lib/src/proto/nomos/runtime/v2/correspondence_desk.pb.dart +359 -2
  40. package/dart_types/lib/src/proto/nomos/runtime/v2/correspondence_desk.pbenum.dart +65 -0
  41. package/dart_types/lib/src/proto/nomos/runtime/v2/model_adoption_desk.pb.dart +20 -2
  42. package/dart_types/lib/src/proto/nomos/runtime/v2/observability_desk.pb.dart +278 -9
  43. package/dart_types/lib/src/proto/nomos/runtime/v2/receiving_group_desk.pb.dart +7 -85
  44. package/dart_types/lib/src/proto/nomos/runtime/v2/residency_desk.pb.dart +35 -0
  45. package/dart_types/pubspec.yaml +1 -1
  46. package/package.json +4 -2
  47. package/src/build_provenance.ts +7 -2
  48. package/src/codegen_dart_client.ts +21 -9
  49. package/src/codegen_dart_facade.ts +1 -0
  50. package/src/codegen_dart_framework_calls.ts +12 -9
  51. package/src/codegen_dart_scenario.ts +7 -0
  52. package/src/codegen_ts.ts +26 -24
  53. package/src/compile_package_main.ts +65 -61
  54. package/src/engine_entry.ts +4 -48
  55. package/src/law_unit_set_identity.ts +44 -0
  56. package/src/query/compile.ts +0 -0
  57. package/src/release_inspection.ts +24 -0
  58. package/src/release_publication.ts +298 -0
@@ -247,6 +247,8 @@ class ResidentWorkspaceDetail extends $pb.GeneratedMessage {
247
247
  ResidentOutbox? outbox,
248
248
  ResidentAggregateCensus? census,
249
249
  $core.String? fullReplayHead,
250
+ $fixnum.Int64? localHistoryCommits,
251
+ $core.String? placementUnobservedReason,
250
252
  }) {
251
253
  final result = create();
252
254
  if (workspace != null) result.workspace = workspace;
@@ -267,6 +269,10 @@ class ResidentWorkspaceDetail extends $pb.GeneratedMessage {
267
269
  if (outbox != null) result.outbox = outbox;
268
270
  if (census != null) result.census = census;
269
271
  if (fullReplayHead != null) result.fullReplayHead = fullReplayHead;
272
+ if (localHistoryCommits != null)
273
+ result.localHistoryCommits = localHistoryCommits;
274
+ if (placementUnobservedReason != null)
275
+ result.placementUnobservedReason = placementUnobservedReason;
270
276
  return result;
271
277
  }
272
278
 
@@ -319,6 +325,10 @@ class ResidentWorkspaceDetail extends $pb.GeneratedMessage {
319
325
  ..aOM<ResidentAggregateCensus>(14, _omitFieldNames ? '' : 'census',
320
326
  subBuilder: ResidentAggregateCensus.create)
321
327
  ..aOS(15, _omitFieldNames ? '' : 'fullReplayHead')
328
+ ..a<$fixnum.Int64>(
329
+ 16, _omitFieldNames ? '' : 'localHistoryCommits', $pb.PbFieldType.OU6,
330
+ defaultOrMaker: $fixnum.Int64.ZERO)
331
+ ..aOS(17, _omitFieldNames ? '' : 'placementUnobservedReason')
322
332
  ..hasRequiredFields = false;
323
333
 
324
334
  @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
@@ -511,6 +521,31 @@ class ResidentWorkspaceDetail extends $pb.GeneratedMessage {
511
521
  $core.bool hasFullReplayHead() => $_has(14);
512
522
  @$pb.TagNumber(15)
513
523
  void clearFullReplayHead() => $_clearField(15);
524
+
525
+ /// The size of a PARTIAL local history: commits this host holds on main's first-parent chain,
526
+ /// from git_head down to the shallow boundary inclusive. Exact for git_head. Measured once by a
527
+ /// bounded idle-lane walk after a custody event that moves the boundary or the head by an unknown
528
+ /// amount (acquisition, sync fast-forward, deepening), then advanced by one per admitted offer;
529
+ /// health never walks history. Absent when not yet measured for this head, and for COMPLETE
530
+ /// history, which is never walked for telemetry.
531
+ @$pb.TagNumber(16)
532
+ $fixnum.Int64 get localHistoryCommits => $_getI64(15);
533
+ @$pb.TagNumber(16)
534
+ set localHistoryCommits($fixnum.Int64 value) => $_setInt64(15, value);
535
+ @$pb.TagNumber(16)
536
+ $core.bool hasLocalHistoryCommits() => $_has(15);
537
+ @$pb.TagNumber(16)
538
+ void clearLocalHistoryCommits() => $_clearField(16);
539
+
540
+ /// Why `placement` is absent, in the office's words. Set only when placement is absent.
541
+ @$pb.TagNumber(17)
542
+ $core.String get placementUnobservedReason => $_getSZ(16);
543
+ @$pb.TagNumber(17)
544
+ set placementUnobservedReason($core.String value) => $_setString(16, value);
545
+ @$pb.TagNumber(17)
546
+ $core.bool hasPlacementUnobservedReason() => $_has(16);
547
+ @$pb.TagNumber(17)
548
+ void clearPlacementUnobservedReason() => $_clearField(17);
514
549
  }
515
550
 
516
551
  /// The frontier's authenticated aggregate count, and the most numerous types from the resident
@@ -9,7 +9,7 @@ description: >-
9
9
  Pure kernel wire/data types for Nomos Dart frontends — no transport, no bridge,
10
10
  no runtime. Typed protobuf and USDA boundary values plus the offer codec,
11
11
  reactive read engine, schema validation, and data-only error/trace types.
12
- version: 0.12.0
12
+ version: 0.13.0
13
13
 
14
14
  environment:
15
15
  sdk: ^3.5.0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@githolon/dsl",
3
- "version": "0.113.4",
3
+ "version": "0.114.0",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "description": "Nomos 2 domain-authoring DSL: aggregates + directives in TS, executed and encoded to the Rust kernel's wire shapes.",
@@ -25,6 +25,8 @@
25
25
  "types": "./compile_proof.d.mts",
26
26
  "default": "./compile_proof.mjs"
27
27
  },
28
+ "./release-publication": "./src/release_publication.ts",
29
+ "./release-inspection": "./src/release_inspection.ts",
28
30
  "./workspace-type": "./src/workspace_type.ts",
29
31
  "./workspace-routing": "./src/workspace_routing.ts",
30
32
  "./workspace-sharding": "./src/workspace_sharding.ts",
@@ -73,7 +75,7 @@
73
75
  "test": "vitest run"
74
76
  },
75
77
  "dependencies": {
76
- "@githolon/runtime": "^0.113.4",
78
+ "@githolon/runtime": "^0.114.0",
77
79
  "@bufbuild/protobuf": "^2.13.0",
78
80
  "@bufbuild/protoc-gen-es": "^2.13.0",
79
81
  "esbuild": "0.24.2",
@@ -43,8 +43,10 @@ export interface ProvenanceSubject {
43
43
  export interface BuildProvenanceInput {
44
44
  /** Package name from the project config. */
45
45
  readonly packageName: string;
46
- /** `sha256(package bytes)` — the composed typed USDA closure identity. */
46
+ /** The PACKAGE identity: this compiler's closure of `<name>.law.usdz`. Not what a unit-lane target serves. */
47
47
  readonly domainHash: string;
48
+ /** THE LAW IDENTITY: the unit set identity of `<name>.units` (law_unit_set_identity.ts, CAP-773). */
49
+ readonly unitSetIdentity: string;
48
50
  /** The transports the domainHash addresses (law archive, package asset, …). */
49
51
  readonly artifacts: readonly { readonly name: string; readonly sha256?: string }[];
50
52
  /** Per-domain compiled surface, already computed for the summary. */
@@ -71,8 +73,11 @@ export interface BuildProvenanceInput {
71
73
  */
72
74
  export function buildProvenanceStatement(input: BuildProvenanceInput): Record<string, unknown> {
73
75
  const subject: ProvenanceSubject[] = [
74
- // The law closure identity is THE subject: `sha256(package bytes) = domainHash`.
76
+ // The package: `<name>.law` is the compiler's closure of the `.law.usdz` bytes (the package identity).
75
77
  { name: `${input.packageName}.law`, digest: { sha256: input.domainHash } },
78
+ // The law: `<name>.units` names the unit set identity, what releases, clients and qualification name.
79
+ // A target serves a closure its own kernel composes from these units, which neither digest names.
80
+ { name: `${input.packageName}.units`, digest: { sha256: input.unitSetIdentity } },
76
81
  ...input.artifacts
77
82
  .filter((a): a is { name: string; sha256: string } => typeof a.sha256 === "string")
78
83
  .map((a) => ({ name: a.name, digest: { sha256: a.sha256 } })),
@@ -815,7 +815,7 @@ function emitDartUsdaResultDecoder(
815
815
  }
816
816
 
817
817
  export interface DartClientOptions {
818
- /** Content identity of the built typed USDA closure (`.law.usdz`). */
818
+ /** THE LAW the client is generated against: the unit set identity of `build/<name>.units` (CAP-773). */
819
819
  readonly domainHash: string;
820
820
  /** Flutter asset key for the compiler-authored USDZ transport. Generated
821
821
  * child openers use it to inherit an accepted parent model through the
@@ -2282,19 +2282,30 @@ export function generateDartDomainClient(
2282
2282
  const qOwned = qScopes.some((scope) => scope.owned === true);
2283
2283
  const qPrivate = needsReadPrincipal(q.returns);
2284
2284
  const qScopesExpr = scopesExpr(qScopes);
2285
+ // CAP-731: a declared rows watch whose keys the client does not re-derive per read merges
2286
+ // kernel row deltas (O(changed) per local write) instead of re-decoding the whole result.
2287
+ // Ordered reads keep complete results: their order is the law's, not the id's.
2288
+ const rowsWatch = (keys: string) =>
2289
+ `session.nmsWatchRows(${queryCall}, decode: (result) => ${decodeRows}(result, _ws), idOf: (row) => row.ref.id${keys}${
2290
+ qPrivate ? ", principal: actor" : ""
2291
+ })`;
2285
2292
  const nominalWatch = qOwned
2286
2293
  ? `session.nmsWatch(${queryCall}${
2287
2294
  qPrivate ? ", principal: actor" : ""
2288
2295
  }).asyncMap((result) async => _readWithOwnedKeys(${qScopesExpr}, (keys) async => ${decodeRows}(await session.nmsQuery(${queryCall}, keys${
2289
2296
  qPrivate ? ", actor" : ""
2290
2297
  }), _ws), (row) => row.ref, initial: await ${decodeRows}(result, _ws)))`
2298
+ : ordered !== undefined
2299
+ ? qScopes.length
2300
+ ? `Stream.fromFuture(_readKeys(${qScopesExpr})).asyncExpand((keys) => session.nmsWatch(${queryCall}, keys: keys${
2301
+ qPrivate ? ", principal: actor" : ""
2302
+ }).asyncMap((result) => ${decodeRows}(result, _ws)))`
2303
+ : `session.nmsWatch(${queryCall}${
2304
+ qPrivate ? ", principal: actor" : ""
2305
+ }).asyncMap((result) => ${decodeRows}(result, _ws))`
2291
2306
  : qScopes.length
2292
- ? `Stream.fromFuture(_readKeys(${qScopesExpr})).asyncExpand((keys) => session.nmsWatch(${queryCall}, keys: keys${
2293
- qPrivate ? ", principal: actor" : ""
2294
- }).asyncMap((result) => ${decodeRows}(result, _ws)))`
2295
- : `session.nmsWatch(${queryCall}${
2296
- qPrivate ? ", principal: actor" : ""
2297
- }).asyncMap((result) => ${decodeRows}(result, _ws))`;
2307
+ ? `Stream.fromFuture(_readKeys(${qScopesExpr})).asyncExpand((keys) => ${rowsWatch(", keys: keys")})`
2308
+ : rowsWatch("");
2298
2309
  if (ordered !== undefined) {
2299
2310
  const resultType = ordered.limit === 1 ? `${model}?` : `List<${model}>`;
2300
2311
  const select = ordered.limit === 1 ? "rows.isEmpty ? null : rows.single" : "rows";
@@ -3530,7 +3541,7 @@ export function generateDartDomainClient(
3530
3541
  ` final latest = events.isEmpty ? null : events.first;`,
3531
3542
  ` items = [`,
3532
3543
  ` NomosDescribeItem(kind: 'evidence', id: 'workspace', label: 'Workspace', summary: _ws, details: {'workspace': _ws}),`,
3533
- ` NomosDescribeItem(kind: 'evidence', id: 'law', label: 'Generated law', summary: domainHash, details: {'domainHash': domainHash}),`,
3544
+ ` NomosDescribeItem(kind: 'evidence', id: 'law', label: 'Generated law (unit set)', summary: domainHash, details: {'lawUnitSet': domainHash}),`,
3534
3545
  ` NomosDescribeItem(kind: 'evidence', id: 'reader', label: 'Verified reader', summary: this.actor ?? 'anonymous', details: {'actor': this.actor}),`,
3535
3546
  ` if (latest != null) NomosDescribeItem(kind: 'evidence', id: latest.eventId, label: 'Latest verified moment', summary: latest.eventId,`,
3536
3547
  ` details: {'occurredAt': latest.occurredAt, 'performedBy': latest.performedBy, 'domain': latest.domain, 'kind': latest.kind}),`,
@@ -3630,7 +3641,8 @@ export function generateDartDomainClient(
3630
3641
  ? [`export '${opts.frameworkImportUri}';`]
3631
3642
  : []),
3632
3643
  ``,
3633
- `/// Content identity of the installed typed USDA closure (transported as \`.law.usdz\`).`,
3644
+ `/// The law this client was generated against: its unit set identity (\`build/<name>.units.sha256\`).`,
3645
+ `/// Each workspace serves a closure its own kernel composes from those units; never sent with an offer.`,
3634
3646
  `const String ${hashConst} = ${dartStr(opts.domainHash)};`,
3635
3647
  ``,
3636
3648
  ...(opts.emitActivity === true
@@ -1907,6 +1907,7 @@ export function generateDartApplication(
1907
1907
  `// AUTO-GENERATED by nomos-compile — the tenant application surface for "${domain}".`,
1908
1908
  `// Business facts in, business records out. Runtime lifecycle is deliberately absent.`,
1909
1909
  `export 'package:nomos_client/src/write_progress.dart' show NomosWrite, NomosWriteProgress, NomosWritePhase;`,
1910
+ `export 'package:nomos_client/src/rows_watch.dart' show NomosRows, NomosRowProjection, NomosRowsProjectionStream;`,
1910
1911
  ...((mod.workspaceInvariants ?? []).some(rule => rule.refusal) ? [
1911
1912
  `export 'package:nomos_types/nomos_types.dart' show AdmissionDecision, Admitted, DomainRefused, FrameworkRefused, UnsupportedRefusalContract, NomosDomainRefusalEvidence, KernelRefusalCode;`,
1912
1913
  ] : []),
@@ -173,14 +173,16 @@ export function dartFrameworkOperationDirectiveIds(
173
173
  export function generateDartApplicationFrameworkCalls(
174
174
  laws: readonly DartFrameworkCallLaw[],
175
175
  descriptor: {
176
- /** The compiled law package identity — the descriptor's own closure, `currentLaw[<application-home domain>]`. */
177
- readonly lawSha256: string;
176
+ /** THE LAW the application is compiled as: the unit set identity of `build/<name>.units` (CAP-773). */
177
+ readonly lawUnitSet: string;
178
+ /** The compiled package closure (`build/<name>.law.usdz`): the bytes a device stages. Not what a target serves. */
179
+ readonly lawPackageSha256: string;
178
180
  },
179
181
  ): string | undefined {
180
- if (!/^[0-9a-f]{64}$/.test(descriptor.lawSha256)) {
181
- throw new Error(
182
- `Dart framework call codegen: the application birth contract needs the compiled law package sha256 identity, not '${descriptor.lawSha256}'`,
183
- );
182
+ for (const [name, value] of [["law unit set", descriptor.lawUnitSet], ["package", descriptor.lawPackageSha256]] as const) {
183
+ if (!/^[0-9a-f]{64}$/.test(value)) {
184
+ throw new Error(`Dart framework call codegen: the application's ${name} identity must be 64 lowercase hex, not '${value}'`);
185
+ }
184
186
  }
185
187
  const frameworkEnumDartTypes = collectFixedFrameworkDartEnums().dartTypes;
186
188
  const fixedEmitted = FIXED_CALLS.flatMap((definition) => laws.flatMap((law) => {
@@ -619,7 +621,7 @@ export function generateDartApplicationFrameworkCalls(
619
621
  `import 'dart:typed_data' show Uint8List;`,
620
622
  `import 'package:fixnum/fixnum.dart' show Int64;`,
621
623
  `import 'operation_payloads.pb.dart' as _nmsop;`,
622
- `import 'package:nomos_types/nomos_kernel_protocol.dart' show ApplicationBirthContract, BirthCertificate;`,
624
+ `import 'package:nomos_types/nomos_kernel_protocol.dart' show BirthCertificate;`,
623
625
  `import 'package:nomos_types/nomos_types.dart' show NomosSlot, Sha256Digest;`,
624
626
  `import 'package:nomos_client/src/application_framework_calls.dart';`,
625
627
  `import 'package:nomos_client/src/generated_call.dart';`,
@@ -646,8 +648,9 @@ export function generateDartApplicationFrameworkCalls(
646
648
  ` @override`,
647
649
  ` String get parentModelAuthoritySeatId => ${JSON.stringify(PARENT_MODEL_AUTHORITY_SEAT_ID)};`,
648
650
  ` @override`,
649
- ` ApplicationBirthContract get applicationBirthContract =>`,
650
- ` ApplicationBirthContract(lawSha256: ${JSON.stringify(descriptor.lawSha256)});`,
651
+ ` String get lawUnitSet => ${JSON.stringify(descriptor.lawUnitSet)};`,
652
+ ` @override`,
653
+ ` String get lawPackageSha256 => ${JSON.stringify(descriptor.lawPackageSha256)};`,
651
654
  ``,
652
655
  ...methods,
653
656
  `}`,
@@ -123,6 +123,7 @@ export function generateDartScenario(
123
123
  `import 'package:nomos_client/src/reception/reception_session.dart' show NmsReceptionUser, NmsReceptionSessionView;`,
124
124
  `import 'package:nomos_client/src/nms_generated_runtime.dart' show NomosSession;`,
125
125
  `import 'package:nomos_client/src/nms_test_environment.dart' show NomosTestCloud, NomosTestHarness, NomosTestFrontier;`,
126
+ `import 'package:nomos_flutter/testing.dart' show registerNomosNativeTestPeerHost;`,
126
127
  ``,
127
128
  `// The office names the framework's identity anchor; a scenario never re-derives it.`,
128
129
  `Future<NmsReceptionSessionView> _nmsTestReception(`,
@@ -212,6 +213,9 @@ export function generateDartScenario(
212
213
  ` void Function(Future<void> Function())? registerTearDown,`,
213
214
  ` }) async {`,
214
215
  ` final person = signedInAs ?? ${testPerson}.named('test');`,
216
+ ` // Make the Apple native test peer host available; NOMOS_TEST_PEER_HOST=native selects it.`,
217
+ ` // Registering never selects it, so the default Node peer is unchanged.`,
218
+ ` registerNomosNativeTestPeerHost();`,
215
219
  ` final packageFiles = await _applicationPackages();`,
216
220
  ` final environment = await NomosTestHarness.ephemeral(`,
217
221
  ` lawUsdzPaths: packageFiles.map((file) => file.path).toList(growable: false),`,
@@ -244,6 +248,9 @@ export function generateDartScenario(
244
248
  ` if (serverEntry == null || serverEntry.isEmpty) {`,
245
249
  ` throw StateError('Connected scenarios require the Nomos test cloud. Run this test through githolon test.');`,
246
250
  ` }`,
251
+ ` // Make the Apple native test peer host available; NOMOS_TEST_PEER_HOST=native selects it.`,
252
+ ` // Registering never selects it, so the default Node peer is unchanged.`,
253
+ ` registerNomosNativeTestPeerHost();`,
247
254
  ` final applicationName = 'test-application-\${DateTime.now().microsecondsSinceEpoch}';`,
248
255
  ` final packageFiles = await _applicationPackages();`,
249
256
  ` final cloud = await NomosTestCloud.start(`,
package/src/codegen_ts.ts CHANGED
@@ -1128,7 +1128,8 @@ function aggregatesOf(mod: Record<string, unknown>): AggregateHandle[] {
1128
1128
  export interface TsClientOptions {
1129
1129
  /** The package name (`nomos.project.ts` `name`) — used for the hash constant. */
1130
1130
  readonly packageName: string;
1131
- /** Content identity of the built typed USDA closure (`.law.usdz`). */
1131
+ /** THE LAW this client is generated against: the unit set identity of `build/<name>.units` (CAP-773,
1132
+ * law_unit_set_identity.ts). Never the package closure, and never sent to the kernel with an offer. */
1132
1133
  readonly domainHash: string;
1133
1134
  /** Sibling lossless USDZ transport carried by the generated client when its signed-in workspace
1134
1135
  * still serves the predecessor model. The archive is never canonical state and is not embedded. */
@@ -2211,7 +2212,8 @@ export function generateTsClient(
2211
2212
  ]
2212
2213
  : []),
2213
2214
  ``,
2214
- `/** Content identity of the installed typed USDA closure (transported as \`.law.usdz\`). */`,
2215
+ `/** The law this client was generated against: its unit set identity (\`build/<name>.units.sha256\`). Each`,
2216
+ ` * workspace serves a closure its own kernel composes from those units; compatibility is the kernel's verdict. */`,
2215
2217
  `const ${hashConst} = ${JSON.stringify(opts.domainHash)};`,
2216
2218
  ``,
2217
2219
  ...(clientInterface !== undefined
@@ -2579,7 +2581,7 @@ export function generateTsClient(
2579
2581
  `export interface NomosHolonBinding { readonly workspace: string }`,
2580
2582
  `interface NomosHolon {`,
2581
2583
  ` /** Carry one compiler-generated nominal USDA call. Routing identity and bytes cannot be paired independently. */`,
2582
- ` offerCall(call: NmsGeneratedCall, opts?: { domainHash?: string; actor?: string; returnCreated?: boolean; __nomosConflictSnapshots?: readonly { aggregateType: string; aggregateId: string; field: string; targetSchema: string; token: string }[] }): Promise<string | { head: string; created?: { type: string; id: string }[]; affected?: { type: string; id: string }[]; workspace?: string; born?: unknown; birthOutcomes?: unknown }>;`,
2584
+ ` offerCall(call: NmsGeneratedCall, opts?: { actor?: string; returnCreated?: boolean; __nomosConflictSnapshots?: readonly { aggregateType: string; aggregateId: string; field: string; targetSchema: string; token: string }[] }): Promise<string | { head: string; created?: { type: string; id: string }[]; affected?: { type: string; id: string }[]; workspace?: string; born?: unknown; birthOutcomes?: unknown }>;`,
2583
2585
  ...(sourceTrustPresent
2584
2586
  ? [
2585
2587
  ` /** FRAMEWORK-INTERNAL: inspect a sibling's immutable custody identity before authoring`,
@@ -2590,7 +2592,7 @@ export function generateTsClient(
2590
2592
  ...(hasCorrections
2591
2593
  ? [
2592
2594
  ` /** Framework-private seam used by generated \`corrections\`; apps never supply an intent id. */`,
2593
- ` correctMostRecent?(opts: { kind: "undo" | "redo"; domain: string; actions: string[]; reason: string; domainHash?: string; actor?: string }): Promise<NomosCorrectionOutcome>;`,
2595
+ ` correctMostRecent?(opts: { kind: "undo" | "redo"; domain: string; actions: string[]; reason: string; actor?: string }): Promise<NomosCorrectionOutcome>;`,
2594
2596
  ]
2595
2597
  : []),
2596
2598
  ...(hasBirths
@@ -2598,7 +2600,7 @@ export function generateTsClient(
2598
2600
  ` /** BIRTH A CHILD WORKSPACE (a signed CROSS-WORKSPACE governance offer to \`parent\`) — OPTIONAL:`,
2599
2601
  ` * @githolon/runtime's connect() attaches it. The generated \`.births()\` methods call this, binding`,
2600
2602
  ` * the declaring domain/directiveId/law hash so a frontend dev never hand-writes those raw strings. */`,
2601
- ` createWorkspace?(opts: { domain: string; directiveId: string; domainHash?: string; parent: string; actor: string; authorSecret?: string; payload?: unknown; name?: string; authToken?: string }): Promise<{ ok?: boolean; status?: number; body?: unknown }>;`,
2603
+ ` createWorkspace?(opts: { domain: string; directiveId: string; parent: string; actor: string; authorSecret?: string; payload?: unknown; name?: string; authToken?: string }): Promise<{ ok?: boolean; status?: number; body?: unknown }>;`,
2602
2604
  ]
2603
2605
  : []),
2604
2606
  ` /** The workspace this holon is bound to — the \`workspace\` of every [NomosRef] this client composes. */`,
@@ -2769,7 +2771,7 @@ export function generateTsClient(
2769
2771
  ? [
2770
2772
  `/** Framework-private merge lane used only by generated conflict capabilities. The snapshot`,
2771
2773
  ` * proves the exact observation set being merged; application code never supplies it. */`,
2772
- `type __NomosConflictOffer = (call: NmsGeneratedCall, opts: { domainHash?: string; actor?: string; returnCreated: true; __nomosConflictSnapshots: readonly { aggregateType: string; aggregateId: string; field: string; targetSchema: string; token: string }[] }) => ReturnType<NomosHolon["offerCall"]>;`,
2774
+ `type __NomosConflictOffer = (call: NmsGeneratedCall, opts: { actor?: string; returnCreated: true; __nomosConflictSnapshots: readonly { aggregateType: string; aggregateId: string; field: string; targetSchema: string; token: string }[] }) => ReturnType<NomosHolon["offerCall"]>;`,
2773
2775
  ``,
2774
2776
  ]
2775
2777
  : []),
@@ -3001,8 +3003,8 @@ export function generateTsClient(
3001
3003
  `}`,
3002
3004
  ``,
3003
3005
  `/** Build the owner ceremony for one domain (thin: all mechanism lives here; the factory just wires it). */`,
3004
- `function _ownerEncryption(holon: NomosHolon, cfg: { domain: string; domainHash?: string; actor?: string; scopes: readonly string[] }): NomosEncryption {`,
3005
- ` const { domain, domainHash, actor, scopes } = cfg;`,
3006
+ `function _ownerEncryption(holon: NomosHolon, cfg: { domain: string; actor?: string; scopes: readonly string[] }): NomosEncryption {`,
3007
+ ` const { domain, actor, scopes } = cfg;`,
3006
3008
  ` const defScope = (scope?: string): string => {`,
3007
3009
  ` if (scope) return scope;`,
3008
3010
  ` if (scopes.length === 1) return scopes[0]!;`,
@@ -3076,7 +3078,7 @@ export function generateTsClient(
3076
3078
  ` wraps.push({ recipientPrincipal: principal, recipientPubKey: pub, hpkeEpk: w.hpkeEpk, ct: w.ct });`,
3077
3079
  ` }`,
3078
3080
  ` const epoch = (await currentEpoch(scope)) + 1; // forward-only: strictly increments`,
3079
- ' const head = await holon.offerDirective(domain, "advanceKeyEpoch", { scope, epoch, openedAt: opts.openedAt ?? new Date().toISOString(), wraps }, { domainHash, actor });',
3081
+ ' const head = await holon.offerDirective(domain, "advanceKeyEpoch", { scope, epoch, openedAt: opts.openedAt ?? new Date().toISOString(), wraps }, { actor });',
3080
3082
  ` return { head, epoch, roster: members };`,
3081
3083
  ` };`,
3082
3084
  ` return {`,
@@ -3084,12 +3086,12 @@ export function generateTsClient(
3084
3086
  ` roster: (scope) => readRoster(defScope(scope)),`,
3085
3087
  ` async grantAndWrap(args) {`,
3086
3088
  ` const scope = defScope(args.scope);`,
3087
- ` await holon.offerDirective(domain, args.grantDirective, args.grantPayload, { domainHash, actor });`,
3089
+ ` await holon.offerDirective(domain, args.grantDirective, args.grantPayload, { actor });`,
3088
3090
  ` return advance(scope, { add: { principal: args.principal, publicKey: args.publicKey }, scopeKey: args.scopeKey, memberKeys: args.memberKeys, expectRoster: args.expectRoster, openedAt: args.openedAt });`,
3089
3091
  ` },`,
3090
3092
  ` async revokeAndRotate(args) {`,
3091
3093
  ` const scope = defScope(args.scope);`,
3092
- ` await holon.offerDirective(domain, args.revokeDirective, args.revokePayload, { domainHash, actor });`,
3094
+ ` await holon.offerDirective(domain, args.revokeDirective, args.revokePayload, { actor });`,
3093
3095
  ` return advance(scope, { remove: [args.principal], scopeKey: args.scopeKey, memberKeys: args.memberKeys, expectRoster: args.expectRoster, openedAt: args.openedAt });`,
3094
3096
  ` },`,
3095
3097
  ` async rotate(args) {`,
@@ -4668,7 +4670,7 @@ export function generateTsClient(
4668
4670
  domain
4669
4671
  )}, actions: ${JSON.stringify(
4670
4672
  correctionActions.map((d) => d.id)
4671
- )}, reason, domainHash, actor: actor ?? holon.principal });`,
4673
+ )}, reason, actor: actor ?? holon.principal });`,
4672
4674
  ` },`,
4673
4675
  ` redo: async (reason: string): Promise<NomosCorrectionOutcome> => {`,
4674
4676
  ` if (!reason.trim()) throw new Error("corrections.redo() needs a reason");`,
@@ -4677,7 +4679,7 @@ export function generateTsClient(
4677
4679
  domain
4678
4680
  )}, actions: ${JSON.stringify(
4679
4681
  correctionActions.map((d) => d.id)
4680
- )}, reason, domainHash, actor: actor ?? holon.principal });`,
4682
+ )}, reason, actor: actor ?? holon.principal });`,
4681
4683
  ` },`,
4682
4684
  ` },`
4683
4685
  );
@@ -5044,7 +5046,7 @@ export function generateTsClient(
5044
5046
  )}: _sourceGenesis,`,
5045
5047
  `${indent} ${JSON.stringify(sourceTrust.keyHashesField)}: [],`,
5046
5048
  `${indent}} satisfies ${payloadType};`,
5047
- `${indent}await _commit(holon.offerCall(${encoder}(_sourceTrustCall, holon.workspace), { domainHash, actor, returnCreated: true }) as Promise<_NomosRawWriteResult>);`,
5049
+ `${indent}await _commit(holon.offerCall(${encoder}(_sourceTrustCall, holon.workspace), { actor, returnCreated: true }) as Promise<_NomosRawWriteResult>);`,
5048
5050
  ...(satisfactionQuery === undefined ? [] : [" }"]),
5049
5051
  ];
5050
5052
  })();
@@ -5420,7 +5422,7 @@ export function generateTsClient(
5420
5422
  : ""
5421
5423
  } }`
5422
5424
  )};`,
5423
- ` const result = await holon.offerCall(_call, { domainHash, actor: principal, returnCreated: true });`,
5425
+ ` const result = await holon.offerCall(_call, { actor: principal, returnCreated: true });`,
5424
5426
  ` const born = typeof result === "object" && result !== null && Array.isArray(result.born) ? result.born[0] : undefined;`,
5425
5427
  ` if (typeof born !== "object" || born === null || typeof born.workspace !== "string" || !born.workspace) throw new Error("birth() committed without returning the born workspace");`,
5426
5428
  ...(ownedBirthDescriptor !== undefined
@@ -5453,7 +5455,7 @@ export function generateTsClient(
5453
5455
  ...(gateGuard ? [gateGuard.replace(/\n$/, "")] : []),
5454
5456
  ` return _commit(holon.offerCall(${encodeCall(
5455
5457
  birthPayload
5456
- )}, { domainHash, actor, returnCreated: true }) as Promise<_NomosRawWriteResult>);`,
5458
+ )}, { actor, returnCreated: true }) as Promise<_NomosRawWriteResult>);`,
5457
5459
  ` },`
5458
5460
  );
5459
5461
  continue;
@@ -5488,10 +5490,10 @@ export function generateTsClient(
5488
5490
  const mintedCall = hasBusinessResult
5489
5491
  ? `_businessResult<${resultName}>(holon.workspace, ${resultSpec}, holon.offerCall(${encodeCall(
5490
5492
  body
5491
- )}, { domainHash, actor, returnCreated: true }) as Promise<_NomosRawWriteResult>)`
5493
+ )}, { actor, returnCreated: true }) as Promise<_NomosRawWriteResult>)`
5492
5494
  : `_commit(holon.offerCall(${encodeCall(
5493
5495
  body
5494
- )}, { domainHash, actor, returnCreated: true }) as Promise<_NomosRawWriteResult>)`;
5496
+ )}, { actor, returnCreated: true }) as Promise<_NomosRawWriteResult>)`;
5495
5497
  methods.push(
5496
5498
  ` /** Author \`${domain}/${d.id}\`: the generated client MINTS \`${mint.field}\` internally`,
5497
5499
  ` * — ids are not application input — ${
@@ -5541,10 +5543,10 @@ export function generateTsClient(
5541
5543
  const commitCall = hasBusinessResult
5542
5544
  ? `_businessResult<${resultName}>(holon.workspace, ${resultSpec}, holon.offerCall(${encodeCall(
5543
5545
  offerPayload
5544
- )}, { domainHash, actor, returnCreated: true }) as Promise<_NomosRawWriteResult>)`
5546
+ )}, { actor, returnCreated: true }) as Promise<_NomosRawWriteResult>)`
5545
5547
  : `_commit(holon.offerCall(${encodeCall(
5546
5548
  offerPayload
5547
- )}, { domainHash, actor, returnCreated: true }) as Promise<_NomosRawWriteResult>)`;
5549
+ )}, { actor, returnCreated: true }) as Promise<_NomosRawWriteResult>)`;
5548
5550
  const outcomeDoc =
5549
5551
  d.marker === "creates"
5550
5552
  ? `Author \`${domain}/${d.id}\`: the LAW mints the ${
@@ -6181,7 +6183,7 @@ export function generateTsClient(
6181
6183
  ` merge: (reconcile: (versions: readonly SurfacedObservation<${valueType}>[]) => ${valueType}, rest?: ${restType}): Promise<void> => {`,
6182
6184
  ` const merged = reconcile(versions);`,
6183
6185
  ` const resolution = ${resolutionLiteral} satisfies ${payloadName};`,
6184
- ` return _commit((holon.offerCall as __NomosConflictOffer)(${resolverCallEncoder}(resolution, holon.workspace), { domainHash, actor, returnCreated: true, __nomosConflictSnapshots: [{ aggregateType: ${JSON.stringify(
6186
+ ` return _commit((holon.offerCall as __NomosConflictOffer)(${resolverCallEncoder}(resolution, holon.workspace), { actor, returnCreated: true, __nomosConflictSnapshots: [{ aggregateType: ${JSON.stringify(
6185
6187
  runtimeAggregateType
6186
6188
  )}, aggregateId, field: ${JSON.stringify(
6187
6189
  b.field
@@ -6617,7 +6619,7 @@ export function generateTsClient(
6617
6619
  ` const payload = await holon.__nomosPrepareOwnedRecordAction({ action: ${JSON.stringify(
6618
6620
  descriptor.action
6619
6621
  )}, scope: ${JSON.stringify(ownedScope)}, record, peer });`,
6620
- ` return _commit(holon.offerCall(${descriptor.functionName}(payload, holon.workspace), { domainHash, actor, returnCreated: true }) as Promise<_NomosRawWriteResult>);`,
6622
+ ` return _commit(holon.offerCall(${descriptor.functionName}(payload, holon.workspace), { actor, returnCreated: true }) as Promise<_NomosRawWriteResult>);`,
6621
6623
  ` }`,
6622
6624
  ]),
6623
6625
  ` default: throw new Error(\`${"${action}()"} has no generated canonical offer encoder\`);`,
@@ -6666,7 +6668,7 @@ export function generateTsClient(
6666
6668
  ` const payload = await holon.__nomosPrepareOwnedDeviceApproval({ request, scope: ${JSON.stringify(
6667
6669
  ownedScope
6668
6670
  )} });`,
6669
- ` return _commit(holon.offerCall(${ownedDeviceApprovalCallEncoder!}(payload, holon.workspace), { domainHash, actor: principal, returnCreated: true }) as Promise<_NomosRawWriteResult>);`,
6671
+ ` return _commit(holon.offerCall(${ownedDeviceApprovalCallEncoder!}(payload, holon.workspace), { actor: principal, returnCreated: true }) as Promise<_NomosRawWriteResult>);`,
6670
6672
  ` },`,
6671
6673
  ` },`,
6672
6674
  ]
@@ -6677,7 +6679,7 @@ export function generateTsClient(
6677
6679
  ` /** Owner policy: grant, revoke and rotate under the signed-in identity. */`,
6678
6680
  ` encryption: _ownerEncryption(holon, { domain: ${JSON.stringify(
6679
6681
  domain
6680
- )}, domainHash, actor, scopes: ${JSON.stringify(
6682
+ )}, actor, scopes: ${JSON.stringify(
6681
6683
  domScopes
6682
6684
  )} }) as NomosEncryption,`,
6683
6685
  ]