@githolon/dsl 0.102.4 → 0.103.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 (131) hide show
  1. package/compile_package.mjs +43 -2
  2. package/compile_proof.d.mts +47 -0
  3. package/compile_proof.mjs +343 -0
  4. package/dart/CHANGELOG.md +7 -0
  5. package/dart/lib/src/dev_cloud.dart +8 -8
  6. package/dart/lib/src/nms_generated_runtime.dart +2 -0
  7. package/dart/lib/src/runner/node-entry.mjs +5504 -1236
  8. package/dart/lib/src/runner/offline-install.mjs +4578 -528
  9. package/dart/lib/src/test_harness.dart +206 -152
  10. package/dart/lib/src/webview_bridge.dart +196 -89
  11. package/dart/pubspec.lock +1 -1
  12. package/dart/pubspec.yaml +2 -2
  13. package/dart/test/acquire_session_credentials_test.dart +4 -3
  14. package/dart/test/adv_realm_interference_test.dart +7 -6
  15. package/dart/test/cloud_bound_topology_test.dart +3 -3
  16. package/dart/test/cluster_births_test.dart +4 -3
  17. package/dart/test/cluster_device_keyed_acceptance_test.dart +10 -16
  18. package/dart/test/cluster_local_autosync_test.dart +3 -2
  19. package/dart/test/cluster_scale_test.dart +3 -2
  20. package/dart/test/dlq_session_surface_test.dart +7 -6
  21. package/dart/test/first_app_gauntlet_test.dart +14 -21
  22. package/dart/test/fixtures/wedge/fake-install.mjs +1 -1
  23. package/dart/test/four_layer_nested_topology_test.dart +4 -4
  24. package/dart/test/harness_phase_timeout_test.dart +2 -2
  25. package/dart/test/local_sync_inert_test.dart +1 -1
  26. package/dart/test/parent_signer_recovery_test.dart +2 -2
  27. package/dart/test/sealing_client_test.dart +4 -3
  28. package/dart/test/session_bound_test.dart +8 -7
  29. package/dart/test/test_harness_test.dart +13 -12
  30. package/dart/test/vo_read_typing_test.dart +4 -3
  31. package/dart/test/watch_after_offer_stall_test.dart +4 -3
  32. package/dart/test/webview_bridge_test.dart +102 -5
  33. package/dart_types/CHANGELOG.md +5 -0
  34. package/dart_types/lib/nomos_types.dart +9 -0
  35. package/dart_types/lib/src/nomos_ref.dart +20 -0
  36. package/dart_types/lib/src/optional_ref.dart +85 -0
  37. package/dart_types/lib/src/sha256_digest.dart +41 -0
  38. package/dart_types/lib/src/versioned_nomos_ref.dart +81 -0
  39. package/dart_types/pubspec.yaml +1 -1
  40. package/dart_types/test/optional_ref_test.dart +44 -0
  41. package/dart_types/test/sha256_digest_test.dart +18 -0
  42. package/package.json +9 -5
  43. package/runtime/generated-application-host.js +5365 -1105
  44. package/src/aggregate.ts +18 -0
  45. package/src/application_composition.ts +6 -32
  46. package/src/attested_core.ts +6 -3
  47. package/src/birth_meter.ts +1 -0
  48. package/src/birth_meter_ensure.ts +28 -2
  49. package/src/births.ts +1 -1
  50. package/src/build_package.ts +162 -538
  51. package/src/business_birth.ts +19 -3
  52. package/src/canonical_json.ts +21 -0
  53. package/src/check_package_main.ts +76 -35
  54. package/src/clear_directive.ts +19 -8
  55. package/src/codegen_dart.ts +305 -22
  56. package/src/codegen_dart_application.ts +844 -292
  57. package/src/codegen_dart_client.ts +1084 -407
  58. package/src/codegen_dart_scenario.ts +12 -12
  59. package/src/codegen_proof.ts +169 -39
  60. package/src/codegen_provider_dart.ts +17 -1
  61. package/src/codegen_ts.ts +298 -106
  62. package/src/compat_manifest.ts +2 -2
  63. package/src/compat_package_main.ts +8 -12
  64. package/src/compile_package_main.ts +1866 -597
  65. package/src/compose.ts +1 -1
  66. package/src/directive.ts +208 -15
  67. package/src/engine_entry.ts +165 -111
  68. package/src/evolve_preview.ts +43 -81
  69. package/src/extremum.ts +1 -1
  70. package/src/fields.ts +183 -4
  71. package/src/flow_gate.ts +75 -2
  72. package/src/framework/application_home.ts +2 -0
  73. package/src/framework/auth_provider_law.ts +2 -2
  74. package/src/framework/birth_meter.ts +7 -19
  75. package/src/framework/bootstrap.ts +0 -2
  76. package/src/framework/business_corrections.ts +9 -5
  77. package/src/framework/domain_lifecycle.ts +15 -29
  78. package/src/framework/encryption_scope.ts +2 -1
  79. package/src/framework/framework_aggregates.ts +2 -0
  80. package/src/framework/genesis.ts +16 -14
  81. package/src/framework/home.ts +20 -14
  82. package/src/framework/owned_custody.ts +9 -3
  83. package/src/framework/platform_admin.ts +3 -3
  84. package/src/framework/relations.ts +21 -13
  85. package/src/framework/signing_identity.ts +45 -40
  86. package/src/framework/workspace_invariant.ts +245 -0
  87. package/src/framework/workspaces.ts +23 -29
  88. package/src/index.ts +36 -16
  89. package/src/intent.ts +178 -6
  90. package/src/law_check.ts +32 -11
  91. package/src/law_graph.ts +2902 -0
  92. package/src/law_graph_usda.ts +1799 -0
  93. package/src/law_identity.ts +435 -0
  94. package/src/law_value_type.ts +230 -0
  95. package/src/lsp_server.ts +61 -31
  96. package/src/ops.ts +7 -0
  97. package/src/package_config.ts +141 -0
  98. package/src/package_dependencies.ts +108 -0
  99. package/src/package_dependency_usage.ts +150 -0
  100. package/src/package_source_imports.ts +71 -0
  101. package/src/plan_source_slice.ts +335 -0
  102. package/src/point_guard.ts +192 -0
  103. package/src/precondition.ts +44 -9
  104. package/src/read_projection_namespace.ts +1 -1
  105. package/src/runtime_zod.ts +44 -0
  106. package/src/secondary_ensure.ts +67 -14
  107. package/src/shape_compat.ts +1 -1
  108. package/src/stable_id_identity_bridge.ts +149 -0
  109. package/src/stable_id_lockfile.ts +278 -0
  110. package/src/stable_ids.ts +7 -2
  111. package/src/stable_ids_for_module.ts +348 -0
  112. package/src/stable_ids_types.ts +1 -1
  113. package/src/sum.ts +1 -1
  114. package/src/usd_state.ts +1 -1
  115. package/src/usda_relationship_integrity.ts +66 -0
  116. package/src/usda_text.ts +18 -0
  117. package/src/usdz.ts +78 -0
  118. package/src/value_object.ts +95 -0
  119. package/src/wire.ts +19 -0
  120. package/src/wire_encode.ts +22 -0
  121. package/src/workspace_sharding.ts +52 -36
  122. package/src/workspace_sharing.ts +28 -4
  123. package/src/zod_introspection.ts +1 -1
  124. package/dart/test/cluster_attested_test.dart +0 -201
  125. package/src/compile_engine.ts +0 -595
  126. package/src/manifest.ts +0 -1476
  127. package/src/read_projection_composition.ts +0 -117
  128. package/src/read_projection_manifest.ts +0 -115
  129. package/src/relation_composition.ts +0 -286
  130. package/src/usd.ts +0 -1967
  131. package/src/usd_layers.ts +0 -1776
@@ -16,6 +16,7 @@ class FakeRunner implements BridgeTransport {
16
16
  final _incoming = StreamController<Map<String, Object?>>.broadcast();
17
17
  final List<Map<String, Object?>> sent = [];
18
18
  String? lastWatchSubId;
19
+ bool acknowledgeWatch = true;
19
20
  bool acknowledgeUnwatch = true;
20
21
 
21
22
  FakeRunner() {
@@ -109,6 +110,18 @@ class FakeRunner implements BridgeTransport {
109
110
  ]
110
111
  }));
111
112
  break;
113
+ case 'queryPage':
114
+ _incoming.add(reply({
115
+ 'rows': [
116
+ {
117
+ 'id': 'page-a',
118
+ 'data': {'q': args['queryId']}
119
+ }
120
+ ],
121
+ 'cursor': 'opaque-next',
122
+ 'done': false,
123
+ }));
124
+ break;
112
125
  case 'queryById':
113
126
  _incoming.add(reply({
114
127
  'rows': [
@@ -119,6 +132,24 @@ class FakeRunner implements BridgeTransport {
119
132
  ]
120
133
  }));
121
134
  break;
135
+ case 'checkRefFreshness':
136
+ _incoming.add(reply({
137
+ 'unique': [
138
+ {
139
+ 'ref': (args['refs'] as List).single,
140
+ 'outcome': {
141
+ 'status': 'stale',
142
+ 'latest': {
143
+ 'workspace': 'catalogue',
144
+ 'type': 'catalogue.Publication',
145
+ 'id': 'publication:2',
146
+ },
147
+ },
148
+ },
149
+ ],
150
+ 'order': [0],
151
+ }));
152
+ break;
122
153
  case 'count':
123
154
  _incoming.add(reply({'count': 7}));
124
155
  break;
@@ -232,7 +263,9 @@ class FakeRunner implements BridgeTransport {
232
263
  break;
233
264
  case 'watch':
234
265
  lastWatchSubId = args['subId'] as String;
235
- _incoming.add(reply({'subId': args['subId']}));
266
+ if (acknowledgeWatch) {
267
+ _incoming.add(reply({'subId': args['subId']}));
268
+ }
236
269
  break;
237
270
  case 'unwatch':
238
271
  if (acknowledgeUnwatch) {
@@ -341,9 +374,6 @@ Future<Object?> _invoke(
341
374
  payload: a['payload'],
342
375
  actor: a['actor'] as String?,
343
376
  domainHash: a['domainHash'] as String?,
344
- attestations: (a['attestations'] as List?)
345
- ?.map((e) => (e as Map).cast<String, Object?>())
346
- .toList(),
347
377
  force: a['force'] as bool?,
348
378
  );
349
379
  default:
@@ -515,6 +545,39 @@ void main() {
515
545
  await bridge.ready.timeout(const Duration(seconds: 1));
516
546
  });
517
547
 
548
+ test('dispose closes active watches without mutating its iteration',
549
+ () async {
550
+ await bridge.ready;
551
+ final subscription =
552
+ bridge.watch('entriesByOwner', {'owner': 'user:ada'}).listen((_) {});
553
+ await Future<void>.delayed(Duration.zero);
554
+
555
+ await bridge.dispose();
556
+ await subscription.cancel();
557
+ });
558
+
559
+ test('dispose does not wait for a paused watch consumer', () async {
560
+ await bridge.ready;
561
+ final subscription =
562
+ bridge.watch('entriesByOwner', {'owner': 'user:ada'}).listen((_) {});
563
+ await Future<void>.delayed(Duration.zero);
564
+ subscription.pause();
565
+
566
+ await bridge.dispose().timeout(const Duration(seconds: 1));
567
+ await subscription.cancel();
568
+ });
569
+
570
+ test('dispose contains an unacknowledged watch registration error', () async {
571
+ await bridge.ready;
572
+ runner.acknowledgeWatch = false;
573
+ final subscription =
574
+ bridge.watch('entriesByOwner', {'owner': 'user:ada'}).listen((_) {});
575
+ await Future<void>.delayed(Duration.zero);
576
+
577
+ await bridge.dispose();
578
+ await subscription.cancel();
579
+ });
580
+
518
581
  test('offer round-trips a typed head; args reach the runner verbatim',
519
582
  () async {
520
583
  await bridge.ready;
@@ -602,12 +665,17 @@ void main() {
602
665
  });
603
666
 
604
667
  test(
605
- 'connect / query / queryById / count / sync / lawStatus all wrap the runner',
668
+ 'connect / query / queryPage / queryById / count / sync / lawStatus all wrap the runner',
606
669
  () async {
607
670
  await bridge.ready;
608
671
  await bridge.connect(cloud: 'https://c', workspace: 'ws', clientId: 'c1');
609
672
  expect((await bridge.query('byAuthor', {'author': 'ada'})).first['data'],
610
673
  {'q': 'byAuthor'});
674
+ final page = await bridge.queryPage('byAuthor',
675
+ params: {'author': 'ada'}, pageSize: 1);
676
+ expect(page.rows.single['id'], 'page-a');
677
+ expect(page.cursor, 'opaque-next');
678
+ expect(page.done, isFalse);
611
679
  expect((await bridge.queryById('Entry_1')).first['id'], 'Entry_1');
612
680
  expect(await bridge.count('entries'), 7);
613
681
  expect(await bridge.sync(), {'pushed': true});
@@ -615,6 +683,35 @@ void main() {
615
683
  await bridge.lawStatus('abc'), {'installed': true, 'drifted': false});
616
684
  });
617
685
 
686
+ test('version freshness returns the required sum type without resolving history',
687
+ () async {
688
+ await bridge.ready;
689
+ final reference = NmsInternalVersionedNomosRefs.create<Object, Object>(
690
+ pinned: NmsInternalNomosRefs.create<Object>(
691
+ workspace: 'catalogue',
692
+ type: 'catalogue.Publication',
693
+ id: 'publication:1',
694
+ ),
695
+ series: NmsInternalNomosRefs.create<Object>(
696
+ workspace: 'catalogue',
697
+ type: 'catalogue.Series',
698
+ id: 'series:1',
699
+ ),
700
+ currentField: 'currentPublication',
701
+ );
702
+
703
+ final freshness = await bridge.checkReferenceFreshness(reference);
704
+ expect(freshness, isA<ReferenceStale<Object>>());
705
+ expect((freshness as ReferenceStale<Object>).latest.id, 'publication:2');
706
+ final request = runner.sent.last;
707
+ expect(request['op'], 'checkRefFreshness');
708
+ final args = (request['args'] as Map).cast<String, Object?>();
709
+ final check = ((args['refs'] as List).single as Map).cast<String, Object?>();
710
+ expect(check['currentField'], 'currentPublication');
711
+ expect((check['pinned'] as Map)['id'], 'publication:1');
712
+ expect((check['series'] as Map)['id'], 'series:1');
713
+ });
714
+
618
715
  test(
619
716
  'moments and historic reads keep commit plumbing behind an opaque handle',
620
717
  () async {
@@ -1,3 +1,8 @@
1
+ ## 0.8.1
2
+
3
+ - Carry the typed USDA-native kernel protocol, plan diagnostics, reference freshness and application
4
+ readiness shapes used by generated clients without exposing transport or runtime implementation details.
5
+
1
6
  ## 0.8.0
2
7
 
3
8
  - Make `NomosRef<T>` the canonical identity of generated business records. References carry their workspace,
@@ -33,10 +33,19 @@ export 'src/foreign_ref.dart' show ForeignRef;
33
33
  export 'src/activity.dart';
34
34
  // NomosRef is inspectable but framework-created. Its constructor and wire codec stay behind the runtime.
35
35
  export 'src/nomos_ref.dart' show NomosRef;
36
+ export 'src/versioned_nomos_ref.dart'
37
+ show
38
+ VersionedNomosRef,
39
+ ReferenceFreshness,
40
+ ReferenceCurrent,
41
+ ReferenceStale,
42
+ ReferenceFreshnessUnavailable;
43
+ export 'src/optional_ref.dart' show NomosOptionalRef;
36
44
  export 'src/invitation.dart' show Identity, User, Recipient, Invitation;
37
45
  // Branded identity wrappers (NomosPrincipal / NomosDeviceSecret) for the generated cross-workspace
38
46
  // birth methods — actor/authorSecret are distinct types, so a transposition is a compile error.
39
47
  export 'src/principal.dart';
48
+ export 'src/sha256_digest.dart';
40
49
  // The CUSTODY-LIFECYCLE types (rebirth_and_custody_lifecycle.md): NomosCustodyBreak / NomosCustodyStatus /
41
50
  // CustodyBreakPolicy — custody incompatibility as a first-class, typed, app-decidable event. Pure data.
42
51
  export 'src/custody.dart';
@@ -69,6 +69,26 @@ abstract final class NmsInternalNomosRefs {
69
69
 
70
70
  static String id<TAggregate>(NomosRef<TAggregate> reference) => reference._id;
71
71
 
72
+ /// Retype a concrete aggregate reference to a compiled public contract after
73
+ /// checking the stable wire kind. Generated version-pin factories use this
74
+ /// when a concrete catalogue row satisfies a cross-domain contract.
75
+ static NomosRef<TTo> retype<TTo>(
76
+ NomosRef<Object?> reference, {
77
+ required String expectedType,
78
+ }) {
79
+ final actual = reference._type;
80
+ if (actual != expectedType && !actual.endsWith('.$expectedType')) {
81
+ throw ArgumentError(
82
+ 'Reference carries $actual; expected $expectedType',
83
+ );
84
+ }
85
+ return NomosRef<TTo>._(
86
+ reference._workspace,
87
+ reference._type,
88
+ reference._id,
89
+ );
90
+ }
91
+
72
92
  static NomosRef<TAggregate> fromJson<TAggregate>(Object? value) {
73
93
  if (value is String) return fromUri<TAggregate>(value);
74
94
  final map = (value as Map).cast<String, dynamic>();
@@ -0,0 +1,85 @@
1
+ // NOMOS — an optional relationship is a required business decision.
2
+ //
3
+ // Storage may legitimately omit a reference. Generated application inputs must
4
+ // not turn that into an optional named argument: callers choose absent or present.
5
+ library;
6
+
7
+ import 'nomos_ref.dart';
8
+
9
+ /// An explicit choice for an optional first-class Nomos relationship.
10
+ ///
11
+ /// Generated business inputs use this instead of `NomosRef<T>?`. The input
12
+ /// parameter itself is required, so accidentally forgetting a relationship is a
13
+ /// compile error while a deliberately absent relationship remains representable.
14
+ sealed class NomosOptionalRef<TAggregate> {
15
+ const NomosOptionalRef();
16
+
17
+ /// Deliberately omit this relationship from the offered business facts.
18
+ const factory NomosOptionalRef.absent() = _AbsentNomosRef<TAggregate>;
19
+
20
+ /// Supply a framework-created reference for this relationship.
21
+ const factory NomosOptionalRef.present(NomosRef<TAggregate> reference) =
22
+ _PresentNomosRef<TAggregate>;
23
+
24
+ /// True when the relationship is deliberately absent.
25
+ bool get isAbsent => this is _AbsentNomosRef<TAggregate>;
26
+
27
+ /// True when the relationship carries a reference.
28
+ bool get isPresent => this is _PresentNomosRef<TAggregate>;
29
+
30
+ /// The supplied reference, or `null` when absence was chosen explicitly.
31
+ NomosRef<TAggregate>? get referenceOrNull => switch (this) {
32
+ _PresentNomosRef<TAggregate>(:final reference) => reference,
33
+ _ => null,
34
+ };
35
+
36
+ /// Exhaustively handle the two relationship choices.
37
+ R when<R>({
38
+ required R Function() absent,
39
+ required R Function(NomosRef<TAggregate> reference) present,
40
+ }) =>
41
+ switch (this) {
42
+ _AbsentNomosRef<TAggregate>() => absent(),
43
+ _PresentNomosRef<TAggregate>(:final reference) => present(reference),
44
+ };
45
+
46
+ /// Write this choice into an action payload. Absence omits the key; presence
47
+ /// writes the encoded reference value.
48
+ void writeTo(
49
+ Map<String, Object?> data,
50
+ String key,
51
+ Object? Function(NomosRef<TAggregate> reference) encode,
52
+ ) {
53
+ switch (this) {
54
+ case _AbsentNomosRef<TAggregate>():
55
+ break;
56
+ case _PresentNomosRef<TAggregate>(:final reference):
57
+ data[key] = encode(reference);
58
+ }
59
+ }
60
+
61
+ @override
62
+ bool operator ==(Object other) =>
63
+ other is NomosOptionalRef<TAggregate> &&
64
+ other.runtimeType == runtimeType &&
65
+ other.referenceOrNull == referenceOrNull;
66
+
67
+ @override
68
+ int get hashCode => Object.hash(runtimeType, referenceOrNull);
69
+ }
70
+
71
+ final class _AbsentNomosRef<TAggregate> extends NomosOptionalRef<TAggregate> {
72
+ const _AbsentNomosRef();
73
+
74
+ @override
75
+ String toString() => 'NomosOptionalRef<$TAggregate>.absent()';
76
+ }
77
+
78
+ final class _PresentNomosRef<TAggregate> extends NomosOptionalRef<TAggregate> {
79
+ final NomosRef<TAggregate> reference;
80
+
81
+ const _PresentNomosRef(this.reference);
82
+
83
+ @override
84
+ String toString() => 'NomosOptionalRef<$TAggregate>.present($reference)';
85
+ }
@@ -0,0 +1,41 @@
1
+ // NOMOS — Nomos Sovereign: participants act · verify · remember LOCALLY; hosted
2
+ // remotes are replaceable custody/transport, not truth.
3
+
4
+ /// A SHA-256 digest in Nomos's canonical wire spelling: exactly 64 lowercase
5
+ /// hexadecimal characters.
6
+ ///
7
+ /// This extension type is zero-cost on the wire and nominal in Dart: a bare
8
+ /// [String], or a different semantic string type, cannot be passed where a
9
+ /// [Sha256Digest] is required. Construction validates before an offer can be
10
+ /// assembled, rather than deferring the mistake to kernel-side Zod validation.
11
+ extension type const Sha256Digest._(String value) {
12
+ factory Sha256Digest(String value) {
13
+ if (!_isLowercaseSha256(value)) {
14
+ throw FormatException(
15
+ 'expected a 64-character lowercase hexadecimal SHA-256 digest',
16
+ value,
17
+ );
18
+ }
19
+ return Sha256Digest._(value);
20
+ }
21
+
22
+ /// Parse a wire value. This is an explicit alias for generated decode sites
23
+ /// and application boundaries that prefer parser vocabulary.
24
+ static Sha256Digest parse(String value) => Sha256Digest(value);
25
+
26
+ /// Parse without throwing.
27
+ static Sha256Digest? tryParse(String value) {
28
+ if (!_isLowercaseSha256(value)) return null;
29
+ return Sha256Digest._(value);
30
+ }
31
+ }
32
+
33
+ bool _isLowercaseSha256(String value) {
34
+ if (value.length != 64) return false;
35
+ for (final codeUnit in value.codeUnits) {
36
+ final digit = codeUnit >= 0x30 && codeUnit <= 0x39;
37
+ final lowercaseHex = codeUnit >= 0x61 && codeUnit <= 0x66;
38
+ if (!digit && !lowercaseHex) return false;
39
+ }
40
+ return true;
41
+ }
@@ -0,0 +1,81 @@
1
+ // NOMOS — a version pin and its stable series (architecture/foreign_ref.md).
2
+ //
3
+ // This is deliberately a pure data type. The generated application owns the
4
+ // effectful freshness check because it owns the authenticated multi-workspace
5
+ // kernel bridge; a projected DTO never hides a runtime or global singleton.
6
+ library;
7
+
8
+ import 'nomos_ref.dart';
9
+
10
+ /// An immutable publication pin together with the stable series that declares
11
+ /// which publication is current.
12
+ ///
13
+ /// Nomos can check this reference in O(current state): it reads the series' one
14
+ /// compiled current-pointer field and compares that address with [pinned]. It
15
+ /// does not resolve [pinned], reconstruct history, or retain an index of every
16
+ /// version ever published.
17
+ final class VersionedNomosRef<TVersion, TSeries> {
18
+ final NomosRef<TVersion> pinned;
19
+ final NomosRef<TSeries> series;
20
+ final String _currentField;
21
+
22
+ const VersionedNomosRef._(this.pinned, this.series, this._currentField);
23
+
24
+ @override
25
+ bool operator ==(Object other) =>
26
+ other is VersionedNomosRef<TVersion, TSeries> &&
27
+ other.pinned == pinned &&
28
+ other.series == series;
29
+
30
+ @override
31
+ int get hashCode => Object.hash(pinned, series);
32
+
33
+ @override
34
+ String toString() => 'VersionedNomosRef<$TVersion, $TSeries>';
35
+ }
36
+
37
+ /// The typed answer to a generated application's current-version check.
38
+ sealed class ReferenceFreshness<TVersion> {
39
+ const ReferenceFreshness();
40
+ }
41
+
42
+ /// The pinned publication is still the series' current publication.
43
+ final class ReferenceCurrent<TVersion> extends ReferenceFreshness<TVersion> {
44
+ final NomosRef<TVersion> latest;
45
+ const ReferenceCurrent(this.latest);
46
+ }
47
+
48
+ /// The series now points at [latest], while the reference remains pinned to an
49
+ /// older immutable publication.
50
+ final class ReferenceStale<TVersion> extends ReferenceFreshness<TVersion> {
51
+ final NomosRef<TVersion> latest;
52
+ const ReferenceStale(this.latest);
53
+ }
54
+
55
+ /// Nomos could not establish freshness without guessing (for example, the
56
+ /// series is not local, denied, missing, or does not satisfy the compiled law).
57
+ final class ReferenceFreshnessUnavailable<TVersion>
58
+ extends ReferenceFreshness<TVersion> {
59
+ final String reason;
60
+ const ReferenceFreshnessUnavailable(this.reason);
61
+ }
62
+
63
+ /// Framework-only construction and wire access for generated implementation
64
+ /// code. Tenant code receives [VersionedNomosRef] and the required sum result.
65
+ abstract final class NmsInternalVersionedNomosRefs {
66
+ static VersionedNomosRef<TVersion, TSeries> create<TVersion, TSeries>({
67
+ required NomosRef<TVersion> pinned,
68
+ required NomosRef<TSeries> series,
69
+ required String currentField,
70
+ }) =>
71
+ VersionedNomosRef<TVersion, TSeries>._(
72
+ pinned,
73
+ series,
74
+ currentField,
75
+ );
76
+
77
+ static String currentField<TVersion, TSeries>(
78
+ VersionedNomosRef<TVersion, TSeries> reference,
79
+ ) =>
80
+ reference._currentField;
81
+ }
@@ -9,7 +9,7 @@ description: >-
9
9
  Pure kernel wire/data types for Nomos Dart frontends — no transport, no bridge,
10
10
  no runtime. The hand-written serde-JSON-compatible types plus the offer codec,
11
11
  reactive read engine, schema validation, and data-only error/trace types.
12
- version: 0.8.0
12
+ version: 0.8.1
13
13
 
14
14
  environment:
15
15
  sdk: ^3.5.0
@@ -0,0 +1,44 @@
1
+ import 'package:nomos_types/nomos_types.dart';
2
+ import 'package:nomos_types/src/nomos_ref.dart' show NmsInternalNomosRefs;
3
+ import 'package:test/test.dart';
4
+
5
+ final class Site {}
6
+
7
+ void main() {
8
+ test('NomosOptionalRef requires an explicit absent or present choice', () {
9
+ const absent = NomosOptionalRef<Site>.absent();
10
+ final site = NmsInternalNomosRefs.create<Site>(
11
+ workspace: 'estate',
12
+ type: 'EstateSite',
13
+ id: 'site-1',
14
+ );
15
+ final present = NomosOptionalRef.present(site);
16
+
17
+ expect(absent.isAbsent, isTrue);
18
+ expect(absent.referenceOrNull, isNull);
19
+ expect(present.isPresent, isTrue);
20
+ expect(present.referenceOrNull, site);
21
+ });
22
+
23
+ test('NomosOptionalRef omits absence and encodes presence', () {
24
+ final data = <String, Object?>{};
25
+ const NomosOptionalRef<Site>.absent().writeTo(
26
+ data,
27
+ 'siteId',
28
+ NmsInternalNomosRefs.id,
29
+ );
30
+ expect(data, isEmpty);
31
+
32
+ final site = NmsInternalNomosRefs.create<Site>(
33
+ workspace: 'estate',
34
+ type: 'EstateSite',
35
+ id: 'site-1',
36
+ );
37
+ NomosOptionalRef.present(site).writeTo(
38
+ data,
39
+ 'siteId',
40
+ NmsInternalNomosRefs.id,
41
+ );
42
+ expect(data, {'siteId': 'site-1'});
43
+ });
44
+ }
@@ -0,0 +1,18 @@
1
+ import 'package:nomos_types/nomos_types.dart';
2
+ import 'package:test/test.dart';
3
+
4
+ void main() {
5
+ test('accepts exactly 64 lowercase hexadecimal characters', () {
6
+ final digest = Sha256Digest('0123456789abcdef' * 4);
7
+ expect(digest.value, '0123456789abcdef' * 4);
8
+ expect(digest.toString(), digest.value);
9
+ });
10
+
11
+ test('refuses malformed, uppercase, and incorrectly sized values', () {
12
+ expect(() => Sha256Digest('abc'), throwsFormatException);
13
+ expect(() => Sha256Digest('A' * 64), throwsFormatException);
14
+ expect(() => Sha256Digest('g' * 64), throwsFormatException);
15
+ expect(Sha256Digest.tryParse('0' * 64)?.value, '0' * 64);
16
+ expect(Sha256Digest.tryParse('0' * 63), isNull);
17
+ });
18
+ }
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@githolon/dsl",
3
- "version": "0.102.4",
3
+ "version": "0.103.0",
4
4
  "type": "module",
5
+ "sideEffects": false,
5
6
  "description": "Nomos 2 domain-authoring DSL: aggregates + directives in TS, executed and encoded to the Rust kernel's wire shapes.",
6
7
  "license": "SEE LICENSE IN LICENSE.md",
7
8
  "repository": {
@@ -16,21 +17,22 @@
16
17
  },
17
18
  "exports": {
18
19
  ".": "./src/index.ts",
19
- "./manifest": "./src/manifest.ts",
20
20
  "./stable-ids": "./src/stable_ids.ts",
21
21
  "./compose": "./src/compose.ts",
22
- "./usd": "./src/usd.ts",
23
- "./usd-layers": "./src/usd_layers.ts",
24
22
  "./application-composition": "./src/application_composition.ts",
25
23
  "./usd-state": "./src/usd_state.ts",
26
24
  "./engine-entry": "./src/engine_entry.ts",
25
+ "./compile-proof": {
26
+ "types": "./compile_proof.d.mts",
27
+ "default": "./compile_proof.mjs"
28
+ },
27
29
  "./workspace-type": "./src/workspace_type.ts",
28
30
  "./workspace-routing": "./src/workspace_routing.ts",
29
31
  "./workspace-sharding": "./src/workspace_sharding.ts",
30
32
  "./build-package": "./src/build_package.ts",
31
- "./compile-engine": "./src/compile_engine.ts",
32
33
  "./codegen-dart": "./src/codegen_dart.ts",
33
34
  "./codegen-dot": "./src/codegen_dot.ts",
35
+ "./codegen-usda": "./src/codegen_usda.ts",
34
36
  "./codegen-provider": "./src/codegen_provider_dart.ts",
35
37
  "./framework/disclosure": "./src/framework/disclosure.ts",
36
38
  "./framework/bootstrap": "./src/framework/bootstrap.ts",
@@ -51,6 +53,8 @@
51
53
  "!dart_types/.dart_tool",
52
54
  "!dart_types/build",
53
55
  "runtime",
56
+ "compile_proof.mjs",
57
+ "compile_proof.d.mts",
54
58
  "compile_package.mjs",
55
59
  "check_package.mjs",
56
60
  "compat_package.mjs",