@githolon/dsl 0.113.3 → 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.
- package/assets/operation-contract.wasm +0 -0
- package/compile_package.mjs +23 -3
- package/compile_proof.d.mts +7 -0
- package/compile_proof.mjs +38 -3
- package/dart/CHANGELOG.md +24 -0
- package/dart/lib/src/application_framework_calls.dart +9 -5
- package/dart/lib/src/generated_call.dart +14 -3
- package/dart/lib/src/nms_generated_runtime.dart +7 -0
- package/dart/lib/src/node_runner_transport.dart +77 -8
- package/dart/lib/src/nomos_trace.dart +107 -0
- package/dart/lib/src/reception/dart_reception.dart +148 -11
- package/dart/lib/src/rows_watch.dart +390 -0
- package/dart/lib/src/runner/node-entry.mjs +2807 -691
- package/dart/lib/src/sync_status_projection.dart +94 -1
- package/dart/lib/src/sync_status_reducer.dart +5 -2
- package/dart/lib/src/test_harness.dart +107 -41
- package/dart/lib/src/testing/test_peer.dart +107 -99
- package/dart/lib/src/testing/test_peer_host.dart +305 -0
- package/dart/lib/src/typed_watch_registry.dart +26 -3
- package/dart/pubspec.lock +1 -1
- package/dart/pubspec.yaml +2 -2
- package/dart/test/background_model_adoption_test.dart +1 -0
- package/dart/test/custodian_warming_test.dart +105 -0
- package/dart/test/fixtures/offer_watch_order_peer.dart +74 -0
- package/dart/test/kernel_author_after_read_test.dart +6 -3
- package/dart/test/kernel_fence_test.dart +4 -1
- package/dart/test/model_adoption_test.dart +17 -0
- package/dart/test/nomos_trace_test.dart +91 -0
- package/dart/test/own_offer_watch_order_test.dart +90 -0
- package/dart/test/receiving_group_open_test.dart +4 -8
- package/dart/test/replica_readiness_test.dart +14 -4
- package/dart/test/rows_watch_test.dart +331 -0
- package/dart/test/test_peer_host_selection_test.dart +49 -0
- package/dart_types/CHANGELOG.md +15 -0
- package/dart_types/lib/src/approved_model.dart +22 -5
- package/dart_types/lib/src/proto/nomos/kernel/v1/kernel.pb.dart +535 -1
- package/dart_types/lib/src/proto/nomos/kernel/v1/kernel.pbenum.dart +65 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/application_desk.pb.dart +14 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/correspondence_desk.pb.dart +359 -2
- package/dart_types/lib/src/proto/nomos/runtime/v2/correspondence_desk.pbenum.dart +65 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/model_adoption_desk.pb.dart +20 -2
- package/dart_types/lib/src/proto/nomos/runtime/v2/observability_desk.pb.dart +278 -9
- package/dart_types/lib/src/proto/nomos/runtime/v2/receiving_group_desk.pb.dart +7 -85
- package/dart_types/lib/src/proto/nomos/runtime/v2/residency_desk.pb.dart +35 -0
- package/dart_types/pubspec.yaml +1 -1
- package/package.json +4 -2
- package/src/build_provenance.ts +7 -2
- package/src/codegen_dart_client.ts +21 -9
- package/src/codegen_dart_facade.ts +1 -0
- package/src/codegen_dart_framework_calls.ts +12 -9
- package/src/codegen_dart_scenario.ts +7 -0
- package/src/codegen_ts.ts +26 -24
- package/src/compile_package_main.ts +65 -61
- package/src/engine_entry.ts +4 -48
- package/src/law_unit_set_identity.ts +44 -0
- package/src/query/compile.ts +0 -0
- package/src/release_inspection.ts +24 -0
- 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
|
package/dart_types/pubspec.yaml
CHANGED
|
@@ -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
|
+
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.
|
|
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.
|
|
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",
|
package/src/build_provenance.ts
CHANGED
|
@@ -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
|
-
/**
|
|
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
|
|
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
|
-
/**
|
|
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) =>
|
|
2293
|
-
|
|
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: {'
|
|
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
|
-
`///
|
|
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
|
-
/**
|
|
177
|
-
readonly
|
|
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
|
-
|
|
181
|
-
|
|
182
|
-
`Dart framework call codegen: the application
|
|
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
|
|
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
|
-
`
|
|
650
|
-
`
|
|
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
|
-
/**
|
|
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
|
-
`/**
|
|
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?: {
|
|
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;
|
|
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;
|
|
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: {
|
|
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;
|
|
3005
|
-
` const { domain,
|
|
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 }, {
|
|
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, {
|
|
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, {
|
|
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,
|
|
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,
|
|
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), {
|
|
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, {
|
|
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
|
-
)}, {
|
|
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
|
-
)}, {
|
|
5493
|
+
)}, { actor, returnCreated: true }) as Promise<_NomosRawWriteResult>)`
|
|
5492
5494
|
: `_commit(holon.offerCall(${encodeCall(
|
|
5493
5495
|
body
|
|
5494
|
-
)}, {
|
|
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
|
-
)}, {
|
|
5546
|
+
)}, { actor, returnCreated: true }) as Promise<_NomosRawWriteResult>)`
|
|
5545
5547
|
: `_commit(holon.offerCall(${encodeCall(
|
|
5546
5548
|
offerPayload
|
|
5547
|
-
)}, {
|
|
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), {
|
|
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), {
|
|
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), {
|
|
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
|
-
)},
|
|
6682
|
+
)}, actor, scopes: ${JSON.stringify(
|
|
6681
6683
|
domScopes
|
|
6682
6684
|
)} }) as NomosEncryption,`,
|
|
6683
6685
|
]
|