@githolon/dsl 0.72.0 → 0.72.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dart/CHANGELOG.md CHANGED
@@ -1,3 +1,31 @@
1
+ ## 0.48.1
2
+
3
+ - **Fix: `NomosSession.watchPendingConflicts()` never emitted.** The session overrode every other
4
+ reactive read to register on the parent plane (which owns the message loop) but omitted this one —
5
+ a session-bound generated client's conflict stream registered on the session's own dead controller
6
+ registry and never delivered an event. Now delegates like `watch`/`watchById`/`watchActivity`.
7
+ Regression test: a session-level subscription must emit its first snapshot. (Reported by co2 with
8
+ the exact fix — thank you.)
9
+
10
+ ## 0.48.0
11
+
12
+ - **Session-bound clients (architecture/session_bound_clients.md)** — generated clients now bind to
13
+ exactly ONE `NomosSession`: `XClient.bind(session)` async preflight factory (structural interface
14
+ compat, typed `DomainClientSessionMismatch` at construction), all dispatch through the session,
15
+ births infer the parent from the session (no loose parent strings), `engine.follow(NomosRef)`
16
+ mounts by ref, `NomosOfferOutcome.bornRefs`. The kernel's generic "no active installed law declares
17
+ domain 'x'" is wrapped into the context-rich `DomainNotInstalledForSession` (session identity, both
18
+ workspaces, active domain keys/hashes, the four possible causes).
19
+ - Root-bridge generic writes (`offer`/`offerDirective`/`offerIntent`/`offerCreates`/`createWorkspace`)
20
+ are `@Deprecated` in app code — kept for CLI/admin tooling; the session-bound generated surface is
21
+ the path.
22
+ - `NomosSession.pendingConflicts()` / `watchPendingConflicts()` — the maintained Surfaced-conflict
23
+ "decisions needed" read (derived, not drained).
24
+ - Test harness: `resetWorkspaceCustody`, `seedWorkspaceFromDeployJson`, `assertDomainInstalled`,
25
+ `session.assertCompatible(XClient.interface)`.
26
+ - Requires Nomos Cloud ≥ the 2026-07-11 deploy (wasm 72604ff7 — the Surfaced/captured-basis kernel)
27
+ and pairs with `@githolon/dsl` 0.72.0 codegen.
28
+
1
29
  ## 0.47.0
2
30
 
3
31
  - **Fix: `NomosBridge.createWorkspace` hardcoded `domain: "workspaces"`** in the underlying signed offer —
@@ -1986,6 +1986,9 @@ class NomosSession extends NomosBridge {
1986
1986
  Map<String, Object?> requirement,
1987
1987
  [String? session]) =>
1988
1988
  parent.watchCompatibility(requirement, session ?? workspace);
1989
+ @override
1990
+ Stream<List<dynamic>> watchPendingConflicts([String? session]) =>
1991
+ parent.watchPendingConflicts(session ?? workspace);
1989
1992
 
1990
1993
  // Live snapshots / streams reflect the shared plane — read them off the parent's controllers.
1991
1994
  // compat/onLawChanged are LAW-scoped, so a session answers for ITS workspace (falling back to the
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.2"
194
+ version: "0.3.0"
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.47.0
14
+ version: 0.48.1
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.4
23
+ nomos_types: ^0.3.0
24
24
  json_schema: ^5.2.2
25
25
  crypto: ^3.0.0
26
26
 
@@ -120,6 +120,40 @@ void main() {
120
120
  }
121
121
  }, timeout: const Timeout(Duration(minutes: 4)));
122
122
 
123
+ test(
124
+ 'session.watchPendingConflicts() EMITS (the 0.48.0 regression: the session-level stream '
125
+ 'registered on an object with no message loop and never emitted)', () async {
126
+ final skip = _missingPrereq();
127
+ if (skip != null) {
128
+ markTestSkipped(skip);
129
+ return;
130
+ }
131
+ final harness = await _harness();
132
+ try {
133
+ final session = harness.session(harness.workspace);
134
+ // Subscribe FIRST on the SESSION (the co2 shape: a session-bound generated client's
135
+ // conflict stream), then author any write so a watch tick fires. The broken delegation
136
+ // registered the sub on the session's own dead controller registry — the stream NEVER
137
+ // emitted, regardless of ticks. The fix delegates to the parent plane like every other
138
+ // reactive read; the first tick must deliver a snapshot (empty — no Surfaced law here).
139
+ final first = session.watchPendingConflicts().first;
140
+ final client = await HomeClient.bind(session, actor: _owner);
141
+ await client.birthEstateWorkspace(
142
+ payload: BirthEstateWorkspacePayload(
143
+ owner: _owner,
144
+ frameworkHash: harness.frameworkHash!,
145
+ lawHash: harness.lawHashes(harness.workspace).first,
146
+ bornAt: DateTime.now().toUtc().toIso8601String(),
147
+ ),
148
+ );
149
+ final rows = await first.timeout(const Duration(seconds: 30));
150
+ expect(rows, isEmpty,
151
+ reason: 'no Surfaced law in this fixture — the point is the stream EMITS at all');
152
+ } finally {
153
+ await harness.dispose();
154
+ }
155
+ }, timeout: const Timeout(Duration(minutes: 4)));
156
+
123
157
  test('bind on a deliberately WRONG session throws DomainClientSessionMismatch with every field',
124
158
  () async {
125
159
  final skip = _missingPrereq();
@@ -1,3 +1,12 @@
1
+ ## 0.3.0
2
+
3
+ - `SurfacedValue<T>` — the typed read surface for `Surfaced(inner)` merge-driver fields: sealed
4
+ `SurfacedResolved<T>` / `SurfacedPending<T>` with `fromJson` envelope detection, `isPending`,
5
+ `valueOrNull`, and `SurfacedObservation<T> {value, occurredAt, author?}` (nullable author — the
6
+ writer principal captured at the apply lane). `surfacedEnvelopeKey`/`surfacedAuthorKey` constants.
7
+ - `PendingConflictRow` — the workspace-wide "decisions needed" row served by the maintained
8
+ `pendingConflicts` read: `{aggregateType, aggregateId, field, observations}`.
9
+
1
10
  ## 0.2.0
2
11
 
3
12
  - `NomosPrincipal` / `NomosDeviceSecret` — branded identity types for the generated cross-workspace birth
@@ -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.2.0
14
+ version: 0.3.0
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.72.0",
3
+ "version": "0.72.1",
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",
@@ -898,12 +898,16 @@ const DART_TYPES_IMPORT = `import 'package:nomos_types/nomos_types.dart';`;
898
898
  /** Version constraints the scaffolded pubspecs pin — move together with the Dart packages' releases.
899
899
  * Caret on 0.x is EXACT-MINOR (`^0.45.0` = `<0.46.0`), so these must track the CURRENT release, not
900
900
  * just the floor generated code needs — a lagging pin forces tenants into dependency_overrides. */
901
- // 0.1.4: custody-lifecycle types (CustodyBreakPolicy et al).
902
- // 0.2.0: branded birth identities (NomosPrincipal/NomosDeviceSecret) — the generated cross-workspace
903
- // `.births()` methods type actor/authorSecret as these, so a layered package needs nomos_types 0.2.0.
904
- const NOMOS_TYPES_DEP = "^0.2.0";
905
- // 0.46.0: custody lifecycle on NomosBridge/NomosSession (onCustodyBreak/custodyStatus/salvage lanes).
906
- const NOMOS_CLIENT_DEP = "^0.46.0";
901
+ // 0.3.0: SurfacedValue<T>/SurfacedObservation/PendingConflictRow — generated Surfaced-field typing +
902
+ // the pendingConflicts read rows.
903
+ const NOMOS_TYPES_DEP = "^0.3.0";
904
+ // 0.48.x: session-bound clients (XClient.bind/NomosClientInterface/DomainClientSessionMismatch/
905
+ // DomainNotInstalledForSession, engine.follow, pendingConflicts lanes) — the generated client
906
+ // REQUIRES this surface. 0.48.1 fixes NomosSession.watchPendingConflicts delegation.
907
+ const NOMOS_CLIENT_DEP = "^0.48.1";
908
+ // DRIFT TRIPWIRE: pubspec_pins.test.ts asserts these equal the CURRENT versions in dsl/dart/pubspec.yaml
909
+ // and dsl/dart_types/pubspec.yaml — a Dart release without this bump fails the suite, so tenants never
910
+ // land back in dependency_overrides (the exact co2 report this closes, third occurrence).
907
911
 
908
912
  const isPubPackageName = (s: string): boolean => /^[a-z][a-z0-9_]*$/.test(s);
909
913