@githolon/dsl 0.66.0 → 0.68.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/dart/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## 0.45.0
2
+
3
+ - `offerOutcome(...)` — the one outcome-returning offer lane generated clients now call for EVERY directive:
4
+ returns `NomosOfferOutcome` with workspace-stamped `created` (`NomosCreated` gains `workspace` + a
5
+ `NomosRef get ref` view). Activity raw rows carry `created` + `workspace`. Requires `nomos_types >= 0.1.3`.
6
+
7
+ ## 0.44.0
8
+
9
+ - Activity-feed runtime reads on `NomosBridge`/`NomosSession`: `activityLog({base, limit})` — the committed
10
+ intent log as raw rows `{intentId, domain, directiveId, actorSubject, occurredAt, payload}` (decoded
11
+ payload; the verified author; the physical HLC) — and `watchActivity({base})`, a stream re-deriving the
12
+ feed on every sync tick. Generic (raw Maps); the generated `renderActivity` (from directives' declared
13
+ `.activity()` metadata) types them into `ActivityEvent`s. Requires `nomos_types >= 0.1.2`.
14
+
1
15
  ## 0.43.0
2
16
 
3
17
  - `NomosBridge.foreignReader({cloud})` — a `NomosForeignReader` backed by the device's multi-workspace bridge
@@ -23,6 +23,7 @@ import 'package:nomos_types/nomos_types.dart'
23
23
  nomosErrorFromInfo,
24
24
  NomosTraceContext,
25
25
  NomosErrorInfo,
26
+ NomosRef,
26
27
  NomosForeignReader,
27
28
  NomosForeignWorkspaceReader,
28
29
  ForeignAttestation;
@@ -104,7 +105,15 @@ class SyncStatus {
104
105
  class NomosCreated {
105
106
  final String type;
106
107
  final String id;
107
- const NomosCreated({required this.type, required this.id});
108
+
109
+ /// The workspace the offer ran on (NomosRef). Additive — defaults to '' on older runners that
110
+ /// don't stamp it; then [ref] is workspace-blank (still a valid locator on the local plane).
111
+ final String workspace;
112
+ const NomosCreated({required this.type, required this.id, this.workspace = ''});
113
+
114
+ /// The canonical [NomosRef] view — the `{workspace,type,id}` triple, followable/serializable
115
+ /// (`nomos://<workspace>/<type>/<id>`). One reference, everywhere.
116
+ NomosRef get ref => NomosRef(workspace: workspace, type: type, id: id);
108
117
  @override
109
118
  String toString() => id;
110
119
  }
@@ -604,6 +613,10 @@ class NomosOfferOutcome {
604
613
  final String head;
605
614
  final List<NomosCreated> created;
606
615
 
616
+ /// The workspace the offer ran on (NomosRef). Additive; '' on older runners. Each [created] ref already
617
+ /// carries this, so `outcome.created.first.ref` is the full followable `{workspace,type,id}` locator.
618
+ final String workspace;
619
+
607
620
  /// The born child workspace name(s), when the offer ran a `.births()` directive (else empty). Each is a
608
621
  /// LOCAL workspace on this device's plane, resident in the shared engine plane the moment it is born:
609
622
  /// `bridge.session(name)` returns its handle, and `bridge.connect(session: name)` (no `restoreFrom`) mounts
@@ -616,6 +629,7 @@ class NomosOfferOutcome {
616
629
  const NomosOfferOutcome({
617
630
  required this.head,
618
631
  required this.created,
632
+ this.workspace = '',
619
633
  this.born = const [],
620
634
  this.birthOutcomes = const [],
621
635
  });
@@ -965,6 +979,32 @@ class NomosBridge {
965
979
  List<Map<String, Object?>>? attestations,
966
980
  bool? force,
967
981
  String? session,
982
+ }) =>
983
+ offerOutcome(
984
+ domain: domain,
985
+ directiveId: directiveId,
986
+ payload: payload,
987
+ actor: actor,
988
+ domainHash: domainHash,
989
+ attestations: attestations,
990
+ force: force,
991
+ session: session,
992
+ );
993
+
994
+ /// THE ONE OUTCOME-RETURNING OFFER LANE — [offerDirective] answering the full typed [NomosOfferOutcome]
995
+ /// (head + law-minted `created` NomosRefs + births), for EVERY generated method (create or mutate). A pure
996
+ /// mutation returns `created: []`; a `.creates(...)` plan returns the minted aggregate id(s), each already
997
+ /// carrying the session [workspace] so `outcome.created.first.ref` is a complete followable NomosRef with no
998
+ /// query-after round-trip. [offerCreates] is the historical alias (identical behavior).
999
+ Future<NomosOfferOutcome> offerOutcome({
1000
+ required String domain,
1001
+ required String directiveId,
1002
+ required Object? payload,
1003
+ String? actor,
1004
+ String? domainHash,
1005
+ List<Map<String, Object?>>? attestations,
1006
+ bool? force,
1007
+ String? session,
968
1008
  }) async {
969
1009
  final r = _asMap(await _call('offerDirective', {
970
1010
  'domain': domain,
@@ -992,13 +1032,17 @@ class NomosBridge {
992
1032
  .map((m) => (m['workspace'] ?? '').toString())
993
1033
  .where((s) => s.isNotEmpty),
994
1034
  ]..removeWhere((s) => s.isEmpty);
1035
+ // The offer ran on this workspace (NomosRef) — stamp every minted ref with it so it is a complete locator.
1036
+ final ws = (r['workspace'] ?? '').toString();
995
1037
  return NomosOfferOutcome(
996
1038
  head: r['head'].toString(),
1039
+ workspace: ws,
997
1040
  created: ((r['created'] as List?) ?? const [])
998
1041
  .whereType<Map>()
999
1042
  .map((m) => NomosCreated(
1000
1043
  type: (m['type'] ?? '').toString(),
1001
- id: (m['id'] ?? '').toString()))
1044
+ id: (m['id'] ?? '').toString(),
1045
+ workspace: ws))
1002
1046
  .toList(),
1003
1047
  born: bornNames,
1004
1048
  birthOutcomes: births,
@@ -1168,6 +1212,26 @@ class NomosBridge {
1168
1212
  .toList();
1169
1213
  }
1170
1214
 
1215
+ /// RUNTIME activity feed — per-committed-intent rows (newest-first) from the local ledger, each carrying
1216
+ /// `{intentId, domain, directiveId, actorSubject, occurredAt, payload}` (payload = the DECODED directive
1217
+ /// payload). `base` = a commit-oid cursor (only intents newer than it); omitted = from the tip bounded by
1218
+ /// `limit` (default 200). Generic raw rows — the typed shaping is the codegen `renderActivity`.
1219
+ Future<List<Map<String, dynamic>>> activityLog(
1220
+ {String? base, int? limit}) async {
1221
+ final r = _asMap(await _call('activityLog', {
1222
+ if (base != null) 'base': base,
1223
+ if (limit != null) 'limit': limit,
1224
+ }));
1225
+ return ((r['rows'] as List?) ?? const [])
1226
+ .map((e) => (e as Map).cast<String, dynamic>())
1227
+ .toList();
1228
+ }
1229
+
1230
+ /// Watch the RUNTIME activity feed: a stream that re-emits the newest-first activity rows on every local
1231
+ /// change (doorbell/sync tick). `base` = a commit-oid cursor. Cancelling drops the watch on the runner.
1232
+ Stream<List<dynamic>> watchActivity({String? base, String? session}) =>
1233
+ _watchStream(kind: 'activity', base: base, session: session);
1234
+
1171
1235
  /// Mint an ed25519 DEVICE KEY in-kernel → `{secret, public}` (base64). The SECRET stays on this device
1172
1236
  /// (persist it in secure storage); pass it to [connect] as `authorSecret` (or per-offer `signWith`) so the
1173
1237
  /// holon SIGNS each intent. The PUBLIC half is what gets enrolled so the gate re-verifies the signature on
@@ -1594,6 +1658,7 @@ class NomosBridge {
1594
1658
  String? id,
1595
1659
  String? spatialId,
1596
1660
  NomosBbox? bbox,
1661
+ String? base,
1597
1662
  String? session}) {
1598
1663
  final subId = 'w${++_seq}';
1599
1664
  late final StreamController<List<dynamic>> ctrl;
@@ -1606,6 +1671,7 @@ class NomosBridge {
1606
1671
  if (id != null) 'id': id,
1607
1672
  if (spatialId != null) 'spatialId': spatialId,
1608
1673
  if (bbox != null) 'bbox': bbox.toJson(),
1674
+ if (base != null) 'base': base,
1609
1675
  if (session != null) 'session': session,
1610
1676
  }),
1611
1677
  onCancel: () async {
@@ -1709,6 +1775,9 @@ class NomosSession extends NomosBridge {
1709
1775
  [String? session]) =>
1710
1776
  parent.watchSpatial(spatialId, bbox, session ?? workspace);
1711
1777
  @override
1778
+ Stream<List<dynamic>> watchActivity({String? base, String? session}) =>
1779
+ parent.watchActivity(base: base, session: session ?? workspace);
1780
+ @override
1712
1781
  Stream<Map<String, Object?>> watchCompatibility(
1713
1782
  Map<String, Object?> requirement,
1714
1783
  [String? session]) =>
package/dart/pubspec.lock CHANGED
@@ -191,7 +191,7 @@ packages:
191
191
  path: "../dart_types"
192
192
  relative: true
193
193
  source: path
194
- version: "0.1.0"
194
+ version: "0.1.2"
195
195
  package_config:
196
196
  dependency: transitive
197
197
  description:
package/dart/pubspec.yaml CHANGED
@@ -11,7 +11,7 @@ description: >-
11
11
  Nomos 2 Dart frontend types — the hand-written kernel wire types plus the
12
12
  code-generated per-domain aggregate + directive-payload types. (De)serializes
13
13
  the EXACT serde JSON the Rust kernel + projection produce/consume.
14
- version: 0.43.0
14
+ version: 0.45.0
15
15
 
16
16
  environment:
17
17
  sdk: ^3.5.0
@@ -20,7 +20,7 @@ dependencies:
20
20
  # The pure-data core (wire types, offer codec, NomosReads, schema validation, error
21
21
  # info). nomos_client depends on and re-exports it, so existing imports are unchanged.
22
22
  # For local monorepo dev, pubspec_overrides.yaml points this at ../dart_types.
23
- nomos_types: ^0.1.1
23
+ nomos_types: ^0.1.3
24
24
  json_schema: ^5.2.2
25
25
  crypto: ^3.0.0
26
26
 
@@ -1,3 +1,17 @@
1
+ ## 0.1.3
2
+
3
+ - `NomosRef` — THE one typed reference `{workspace, type, id}`: value semantics, the canonical
4
+ `nomos://<workspace>/<type>/<id>` uri (`uri`/`parse`, encode round-trip), `fromJson` (object or uri),
5
+ `resolve()` over the multi-workspace reader. `ActivityRef` gains `workspace` + a `.ref` view; `ForeignRef`
6
+ gains `.ref`. Every reference shape now converges on the one triple. Purely additive.
7
+
8
+ ## 0.1.2
9
+
10
+ - Activity-feed runtime types: `ActivityEvent` (the shared activity row — kind/actor/occurredAt, rendered
11
+ title+message, stable `titleKey`/`messageKey` + params for localization, typed `refs`, category/icon/
12
+ severity, domain/directiveId provenance), `ActivityRef`, `ActivitySeverity`, `renderActivityTemplate`.
13
+ Consumed by the generated `renderActivity`/`describe`/`describeHistory`. Purely additive.
14
+
1
15
  ## 0.1.1
2
16
 
3
17
  - Add `t.foreignRef` runtime types: `ForeignRef<T>` (a typed cross-workspace locator), `NomosForeignReader` /
@@ -31,3 +31,5 @@ export 'src/errors.dart';
31
31
  // `NomosForeignReader`/`NomosForeignWorkspaceReader` read surfaces + the named resolve outcomes. Pure data +
32
32
  // abstract interfaces (no bridge) — so both the layered TYPES package and nomos_client resolve them.
33
33
  export 'src/foreign_ref.dart';
34
+ export 'src/activity.dart';
35
+ export 'src/nomos_ref.dart';
@@ -0,0 +1,173 @@
1
+ // NOMOS — the ACTIVITY-FEED runtime types (directive `.activity(...)` descriptors). The shared, tenant-
2
+ // agnostic shape a client renders from the intent log: a directive DECLARES its activity metadata (kind,
3
+ // message template, refs, params) and the generated `renderActivity` turns each committed intent into an
4
+ // [ActivityEvent] — no string-enricher guessing meaning beside the truth. The kernel/ledger stays the audit
5
+ // truth; this is a pure client-side human projection.
6
+ //
7
+ // These live in the pure `nomos_types` core (no bridge/lifecycle) so BOTH the layered TYPES package (where
8
+ // the generated pure `renderActivity` lives) AND the runtime `nomos_client` package resolve them.
9
+ library;
10
+
11
+ import 'nomos_ref.dart';
12
+
13
+ /// A declared navigation target on an activity row: the referenced aggregate/contract TYPE + the resolved id
14
+ /// (read from a payload field the directive named). Replaces the old enricher's blind id-probing — the app
15
+ /// knows exactly what `id` points at and can deep-link/resolve it.
16
+ class ActivityRef {
17
+ final String type;
18
+ final String id;
19
+
20
+ /// The source workspace (additive — empty on rows rendered before refs carried it).
21
+ final String workspace;
22
+
23
+ const ActivityRef({required this.type, required this.id, this.workspace = ''});
24
+
25
+ /// The canonical reference view (`nomos://<workspace>/<type>/<id>`).
26
+ NomosRef get ref => NomosRef(workspace: workspace, type: type, id: id);
27
+
28
+ factory ActivityRef.fromJson(Map<String, dynamic> j) => ActivityRef(
29
+ type: (j['type'] ?? '') as String,
30
+ id: (j['id'] ?? '') as String,
31
+ workspace: (j['workspace'] ?? '') as String);
32
+ Map<String, dynamic> toJson() =>
33
+ {'type': type, 'id': id, if (workspace.isNotEmpty) 'workspace': workspace};
34
+
35
+ @override
36
+ bool operator ==(Object other) =>
37
+ other is ActivityRef && other.type == type && other.id == id && other.workspace == workspace;
38
+ @override
39
+ int get hashCode => Object.hash(type, id, workspace);
40
+ }
41
+
42
+ /// Row prominence — a declared default the app may style or threshold on.
43
+ enum ActivitySeverity {
44
+ info,
45
+ success,
46
+ warning,
47
+ critical;
48
+
49
+ static ActivitySeverity fromWire(String? s) {
50
+ switch (s) {
51
+ case 'success':
52
+ return ActivitySeverity.success;
53
+ case 'warning':
54
+ return ActivitySeverity.warning;
55
+ case 'critical':
56
+ return ActivitySeverity.critical;
57
+ default:
58
+ return ActivitySeverity.info;
59
+ }
60
+ }
61
+
62
+ String get wire => name;
63
+ }
64
+
65
+ /// A rendered activity row — the tenant-agnostic "tiny shared activity contract". Produced by the generated
66
+ /// `renderActivity(intentMeta, payload)` from a directive's declared `.activity(...)` descriptor. The UI
67
+ /// consumes this directly (title/message already interpolated; `refs` for navigation; `titleKey`/`messageKey`
68
+ /// + `params` for later localization).
69
+ class ActivityEvent {
70
+ /// The intent id — a stable per-event identity (dedupe/order key).
71
+ final String eventId;
72
+
73
+ /// The declared STABLE event kind (e.g. `"site.created"`).
74
+ final String kind;
75
+
76
+ /// The intent's author (principal) — the "who".
77
+ final String actorSubject;
78
+
79
+ /// When it happened (the intent's physical HLC timestamp, ISO-8601 when available).
80
+ final String occurredAt;
81
+
82
+ /// The rendered title (template interpolated); [titleKey] + [params] localize it later.
83
+ final String title;
84
+
85
+ /// The rendered message (template interpolated); [messageKey] + [params] localize it later.
86
+ final String message;
87
+
88
+ /// Stable i18n key for the title (`activity.<kind>.title`).
89
+ final String titleKey;
90
+
91
+ /// Stable i18n key for the message (`activity.<kind>.message`).
92
+ final String messageKey;
93
+
94
+ /// The interpolation params (name → display value, read from the payload) — for localized re-rendering.
95
+ final Map<String, String> params;
96
+
97
+ /// Declared navigation targets (name → typed ref).
98
+ final Map<String, ActivityRef> refs;
99
+
100
+ /// Optional grouping category (e.g. `"estate"`).
101
+ final String? category;
102
+
103
+ /// Optional default icon token (app-interpreted).
104
+ final String? icon;
105
+
106
+ /// Row prominence (default [ActivitySeverity.info]).
107
+ final ActivitySeverity severity;
108
+
109
+ /// Provenance — the domain + directive that produced this event.
110
+ final String domain;
111
+ final String directiveId;
112
+
113
+ const ActivityEvent({
114
+ required this.eventId,
115
+ required this.kind,
116
+ required this.actorSubject,
117
+ required this.occurredAt,
118
+ required this.title,
119
+ required this.message,
120
+ required this.titleKey,
121
+ required this.messageKey,
122
+ required this.params,
123
+ required this.refs,
124
+ required this.severity,
125
+ required this.domain,
126
+ required this.directiveId,
127
+ this.category,
128
+ this.icon,
129
+ });
130
+
131
+ factory ActivityEvent.fromJson(Map<String, dynamic> j) => ActivityEvent(
132
+ eventId: (j['eventId'] ?? '') as String,
133
+ kind: (j['kind'] ?? '') as String,
134
+ actorSubject: (j['actorSubject'] ?? '') as String,
135
+ occurredAt: (j['occurredAt'] ?? '') as String,
136
+ title: (j['title'] ?? '') as String,
137
+ message: (j['message'] ?? '') as String,
138
+ titleKey: (j['titleKey'] ?? '') as String,
139
+ messageKey: (j['messageKey'] ?? '') as String,
140
+ params: ((j['params'] as Map?)?.cast<String, dynamic>() ?? const {})
141
+ .map((k, v) => MapEntry(k, '$v')),
142
+ refs: ((j['refs'] as Map?)?.cast<String, dynamic>() ?? const {})
143
+ .map((k, v) => MapEntry(k, ActivityRef.fromJson((v as Map).cast<String, dynamic>()))),
144
+ category: j['category'] as String?,
145
+ icon: j['icon'] as String?,
146
+ severity: ActivitySeverity.fromWire(j['severity'] as String?),
147
+ domain: (j['domain'] ?? '') as String,
148
+ directiveId: (j['directiveId'] ?? '') as String,
149
+ );
150
+
151
+ Map<String, dynamic> toJson() => {
152
+ 'eventId': eventId,
153
+ 'kind': kind,
154
+ 'actorSubject': actorSubject,
155
+ 'occurredAt': occurredAt,
156
+ 'title': title,
157
+ 'message': message,
158
+ 'titleKey': titleKey,
159
+ 'messageKey': messageKey,
160
+ 'params': params,
161
+ 'refs': refs.map((k, v) => MapEntry(k, v.toJson())),
162
+ if (category != null) 'category': category,
163
+ if (icon != null) 'icon': icon,
164
+ 'severity': severity.wire,
165
+ 'domain': domain,
166
+ 'directiveId': directiveId,
167
+ };
168
+ }
169
+
170
+ /// Interpolate `{name}` placeholders in [template] from [vars] — the render helper the generated
171
+ /// `renderActivity` uses. A missing var renders empty (the compiler already validated every placeholder).
172
+ String renderActivityTemplate(String template, Map<String, String> vars) =>
173
+ template.replaceAllMapped(RegExp(r'\{([a-zA-Z0-9_]+)\}'), (m) => vars[m.group(1)] ?? '');
@@ -14,6 +14,8 @@
14
14
  // this barrel, and its `NomosBridge` implements [NomosForeignReader] over the device's multi-workspace plane.
15
15
  library;
16
16
 
17
+ import 'nomos_ref.dart';
18
+
17
19
  /// Reads a FOREIGN workspace on demand — the surface a [ForeignRef] resolves against. It is STRUCTURAL: any
18
20
  /// object with this shape works. `nomos_client`'s `NomosBridge` implements it over the device's local
19
21
  /// multi-workspace plane (`bridge.session(ws).queryById(id)`, mounting the workspace lazily); the TS twin is
@@ -111,6 +113,10 @@ class ForeignRef<T> {
111
113
  /// The foreign aggregate type this locator points at.
112
114
  final String type;
113
115
 
116
+ /// The canonical reference view (`nomos://<workspace>/<type>/<id>`) — a [ForeignRef] IS a typed view over
117
+ /// the one reference triple.
118
+ NomosRef get ref => NomosRef(workspace: workspace, type: type, id: id);
119
+
114
120
  /// The target's decoder (the aggregate `fromJson` factory), applied to a resolved row's flat `data` map.
115
121
  final T Function(Map<String, dynamic> data, [String id]) _decode;
116
122
 
@@ -0,0 +1,75 @@
1
+ // NOMOS — THE ONE REFERENCE (architecture/nomos_ref.md). A [NomosRef] is the canonical, globally-unique,
2
+ // workspace-qualified identity of an aggregate instance: `{ workspace, type, id }`, with the stable string
3
+ // form `nomos://<workspace>/<type>/<id>`. It travels WITH the data by default — every generated read row,
4
+ // write outcome, and activity ref carries (or views as) one — so a dev holding a thing can always point at
5
+ // it: no client-side UUID pre-minting, no loose {workspaceId, id} string pairs, no re-query-and-diff.
6
+ //
7
+ // A NomosRef is a LOCATOR (like ForeignRef, which remains the TYPED per-field view): `resolve` is an
8
+ // informational read over the device's multi-workspace plane; law-grade attestation stays on the declared
9
+ // attested-read lane. Pure nomos_types — no bridge/lifecycle imports.
10
+ library;
11
+
12
+ import 'foreign_ref.dart';
13
+
14
+ /// The canonical typed reference to an aggregate instance: workspace + aggregate type + instance id.
15
+ /// Value semantics; `uri` is the stable interop string (`nomos://<workspace>/<type>/<id>`).
16
+ class NomosRef {
17
+ /// The workspace holding the instance.
18
+ final String workspace;
19
+
20
+ /// The aggregate TYPE (the read-projection type tag, e.g. `estate.EstateSite` or `EstateSite`).
21
+ final String type;
22
+
23
+ /// The instance id (law-minted or law-defined).
24
+ final String id;
25
+
26
+ const NomosRef({required this.workspace, required this.type, required this.id});
27
+
28
+ /// The stable string form — survives URLs, nav params, JSON, logs. Segments are URI-encoded so a
29
+ /// workspace/type/id containing `/` or spaces round-trips.
30
+ String get uri =>
31
+ 'nomos://${Uri.encodeComponent(workspace)}/${Uri.encodeComponent(type)}/${Uri.encodeComponent(id)}';
32
+
33
+ /// Parse a `nomos://<workspace>/<type>/<id>` string (the inverse of [uri]). Throws [FormatException]
34
+ /// on anything else.
35
+ factory NomosRef.parse(String uri) {
36
+ final u = Uri.tryParse(uri);
37
+ if (u == null || u.scheme != 'nomos') {
38
+ throw FormatException('NomosRef.parse: not a nomos:// uri', uri);
39
+ }
40
+ // nomos://<ws>/<type>/<id> — the workspace lands as the authority (host), type/id as path segments.
41
+ final ws = Uri.decodeComponent(u.host);
42
+ final segs = u.pathSegments.map(Uri.decodeComponent).toList();
43
+ if (ws.isEmpty || segs.length != 2 || segs[0].isEmpty || segs[1].isEmpty) {
44
+ throw FormatException('NomosRef.parse: expected nomos://<workspace>/<type>/<id>', uri);
45
+ }
46
+ return NomosRef(workspace: ws, type: segs[0], id: segs[1]);
47
+ }
48
+
49
+ /// Accepts the `{workspace,type,id}` object OR the `nomos://` uri string.
50
+ factory NomosRef.fromJson(Object? j) {
51
+ if (j is String) return NomosRef.parse(j);
52
+ final m = (j as Map).cast<String, dynamic>();
53
+ return NomosRef(
54
+ workspace: (m['workspace'] ?? '') as String,
55
+ type: (m['type'] ?? '') as String,
56
+ id: (m['id'] ?? '') as String,
57
+ );
58
+ }
59
+
60
+ Map<String, dynamic> toJson() => {'workspace': workspace, 'type': type, 'id': id};
61
+
62
+ /// Informational lookup of the referenced instance over the device's multi-workspace plane (the same
63
+ /// reader `ForeignRef.resolve` uses — `bridge.foreignReader()` in nomos_client). Returns the raw
64
+ /// `{type,id,data}` rows for the id in the ref's workspace (empty ⇒ not found / not visible).
65
+ Future<List<Map<String, dynamic>>> resolve(NomosForeignReader nomos) =>
66
+ nomos.foreignWorkspace(workspace).queryById(id);
67
+
68
+ @override
69
+ bool operator ==(Object other) =>
70
+ other is NomosRef && other.workspace == workspace && other.type == type && other.id == id;
71
+ @override
72
+ int get hashCode => Object.hash(workspace, type, id);
73
+ @override
74
+ String toString() => uri;
75
+ }
@@ -11,7 +11,7 @@ description: >-
11
11
  Pure kernel wire/data types for Nomos Dart frontends — no transport, no bridge,
12
12
  no runtime. The hand-written serde-JSON-compatible types plus the offer codec,
13
13
  reactive read engine, schema validation, and data-only error/trace types.
14
- version: 0.1.1
14
+ version: 0.1.3
15
15
 
16
16
  environment:
17
17
  sdk: ^3.5.0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@githolon/dsl",
3
- "version": "0.66.0",
3
+ "version": "0.68.0",
4
4
  "type": "module",
5
5
  "description": "Nomos 2 domain-authoring DSL: aggregates + directives in TS, executed and encoded to the Rust kernel's wire shapes.",
6
6
  "license": "SEE LICENSE IN LICENSE.md",