@githolon/dsl 0.108.4 → 0.108.7

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 (44) hide show
  1. package/dart/CHANGELOG.md +5 -0
  2. package/dart/lib/src/application_framework_calls.dart +21 -0
  3. package/dart/lib/src/dev_cloud.dart +67 -0
  4. package/dart/lib/src/nms_test_environment.dart +1 -1
  5. package/dart/lib/src/runner/node-entry.mjs +354 -104
  6. package/dart/lib/src/runner/offline-install.mjs +64 -8
  7. package/dart/lib/src/session_bound.dart +58 -30
  8. package/dart/lib/src/test_harness.dart +60 -98
  9. package/dart/lib/src/webview_bridge.dart +212 -32
  10. package/dart/pubspec.lock +1 -1
  11. package/dart/pubspec.yaml +2 -2
  12. package/dart/test/node_runner_transport_test.dart +5 -5
  13. package/dart/test/webview_bridge_test.dart +6 -0
  14. package/dart_types/CHANGELOG.md +4 -0
  15. package/dart_types/lib/src/proto/nomos/runtime/v2/runtime.pb.dart +428 -2
  16. package/dart_types/pubspec.yaml +1 -1
  17. package/package.json +1 -1
  18. package/runtime/generated-application-host.js +293 -79
  19. package/src/application_topology.ts +120 -28
  20. package/src/births.ts +27 -0
  21. package/src/codegen_call_usda.ts +9 -4
  22. package/src/codegen_dart_application.ts +146 -37
  23. package/src/codegen_dart_client.ts +225 -160
  24. package/src/codegen_dart_framework_calls.ts +89 -4
  25. package/src/codegen_ts.ts +135 -60
  26. package/src/compile_package_main.ts +3598 -1484
  27. package/src/directive.ts +320 -118
  28. package/src/fields.ts +2 -3
  29. package/src/framework/application_home.ts +3 -0
  30. package/src/framework/auth_provider_law.ts +20 -28
  31. package/src/framework/genesis.ts +32 -1
  32. package/src/framework/home.ts +45 -8
  33. package/src/framework/signing_identity.ts +78 -0
  34. package/src/framework/workspaces.ts +9 -1
  35. package/src/framework_call_dart_enums.ts +33 -0
  36. package/src/framework_call_definitions.ts +11 -2
  37. package/src/index.ts +12 -0
  38. package/src/intent.ts +525 -194
  39. package/src/law_graph.ts +32 -4
  40. package/src/law_graph_usda.ts +3 -0
  41. package/src/package_config.ts +16 -1
  42. package/src/read.ts +33 -11
  43. package/src/wire.ts +1 -0
  44. package/src/wire_encode.ts +3 -3
@@ -27,6 +27,7 @@ import 'package:nomos_types/nomos_kernel_protocol.dart' as nomos_protocol;
27
27
  import 'package:nomos_types/nomos_types.dart'
28
28
  show
29
29
  nomosErrorFromInfo,
30
+ NomosBridgeError,
30
31
  NomosTraceContext,
31
32
  NomosErrorInfo,
32
33
  NomosRef,
@@ -1420,6 +1421,21 @@ final class NomosKernelCallFailure implements Exception {
1420
1421
  String toString() => 'NomosKernelCallFailure($code: $message)';
1421
1422
  }
1422
1423
 
1424
+ /// A generated model candidate was not staged by the bound workspace.
1425
+ ///
1426
+ /// This remains distinct from an ordinary domain-offer refusal: generated
1427
+ /// clients may use a typed authentication-posture query to decide whether a
1428
+ /// law-declared provider-epoch recovery action is applicable, without parsing
1429
+ /// this diagnostic prose or catching an unrelated [StateError].
1430
+ final class NomosModelStageFailure implements Exception {
1431
+ const NomosModelStageFailure(this.message);
1432
+
1433
+ final String message;
1434
+
1435
+ @override
1436
+ String toString() => 'NomosModelStageFailure($message)';
1437
+ }
1438
+
1423
1439
  /// Product-facing progress for one accepted write. Transport topology and custody identifiers remain private.
1424
1440
  final class NomosOperationStatus {
1425
1441
  const NomosOperationStatus(this.phase, {this.updatedAt});
@@ -2797,6 +2813,11 @@ class NomosBridge {
2797
2813
  NomosOfferAuthenticationProof.sessionCredentials => sessionToken,
2798
2814
  NomosOfferAuthenticationProof.enrolledDevice => null,
2799
2815
  };
2816
+ // Intentionally visible in device logs: this is the OBD port for a failed
2817
+ // lawful dispatch. It names no token, device secret or tenant payload.
2818
+ // ignore: avoid_print
2819
+ print('[nomos-offer] dispatch ${call.domain}/${call.directive} in '
2820
+ '$workspace using ${authenticationProof.name}');
2800
2821
  final response = await kernelTransport.callKernel(
2801
2822
  session: runtimeSession,
2802
2823
  request: nomos_protocol.CallRequest(
@@ -2834,6 +2855,9 @@ class NomosBridge {
2834
2855
  ),
2835
2856
  );
2836
2857
  if (response.hasFailure()) {
2858
+ // ignore: avoid_print
2859
+ print('[nomos-offer] refused ${call.domain}/${call.directive} in '
2860
+ '$workspace: ${response.failure.code}: ${response.failure.message}');
2837
2861
  throw NomosKernelCallFailure(
2838
2862
  code: response.failure.code,
2839
2863
  message: response.failure.message,
@@ -2847,6 +2871,9 @@ class NomosBridge {
2847
2871
  final offer = response.offer;
2848
2872
  if (!offer.hasAdmitted()) throw NomosTypedOfferFailure(offer);
2849
2873
  final admitted = offer.admitted;
2874
+ // ignore: avoid_print
2875
+ print('[nomos-offer] admitted ${call.domain}/${call.directive} in '
2876
+ '$workspace as ${admitted.intentId} at ${admitted.head}');
2850
2877
  final birthOutcomes = List<NomosBirthOutcome>.unmodifiable(
2851
2878
  admitted.birthOutcomes,
2852
2879
  );
@@ -3677,20 +3704,35 @@ class NomosBridge {
3677
3704
  required String candidateHash,
3678
3705
  required List<int> lawUsdz,
3679
3706
  }) async {
3680
- final response = await _invokeRuntimeV2(
3681
- nomos_protocol.RuntimeRequest(
3682
- modelLifecycle: nomos_protocol.ModelLifecycleRequest(
3683
- session: _runtimeSession(),
3684
- stage: nomos_protocol.StageGeneratedModelRequest(
3685
- domain: domain,
3686
- candidateHash: candidateHash,
3687
- lawUsdz: lawUsdz,
3707
+ print(
3708
+ '[nomos-model-stage] local domain=$domain session=${_runtimeSession()}',
3709
+ );
3710
+ late final nomos_protocol.RuntimeResponse response;
3711
+ try {
3712
+ response = await _invokeRuntimeV2(
3713
+ nomos_protocol.RuntimeRequest(
3714
+ modelLifecycle: nomos_protocol.ModelLifecycleRequest(
3715
+ session: _runtimeSession(),
3716
+ stage: nomos_protocol.StageGeneratedModelRequest(
3717
+ domain: domain,
3718
+ candidateHash: candidateHash,
3719
+ lawUsdz: lawUsdz,
3720
+ ),
3688
3721
  ),
3689
3722
  ),
3690
- ),
3691
- );
3723
+ );
3724
+ } on NomosBridgeError catch (error) {
3725
+ print(
3726
+ '[nomos-model-stage] local refused domain=$domain as ${error.runtimeType}',
3727
+ );
3728
+ // Runtime v2 translates its generated failure arm before returning the
3729
+ // response. Preserve the operation boundary so generated clients can
3730
+ // query typed authentication posture and select a law-declared recovery
3731
+ // action without scraping diagnostics or catching unrelated failures.
3732
+ throw NomosModelStageFailure(error.message);
3733
+ }
3692
3734
  if (!response.hasModelLifecycle() || !response.modelLifecycle.accepted) {
3693
- throw StateError(
3735
+ throw NomosModelStageFailure(
3694
3736
  response.hasModelLifecycle() && response.modelLifecycle.hasMessage()
3695
3737
  ? response.modelLifecycle.message
3696
3738
  : 'Runtime v2 refused generated model staging',
@@ -4016,6 +4058,42 @@ class NomosBridge {
4016
4058
  return response.applicationCustodyEstablished;
4017
4059
  }
4018
4060
 
4061
+ /// Offer one compiler-generated call to a remote workspace without cloning
4062
+ /// that workspace onto this device. The resident source session signs the
4063
+ /// target-kernel-prepared USDA; Runtime v2 carries the nominal call and the
4064
+ /// admitted target head without a command string or tenant map.
4065
+ Future<nomos_protocol.RemoteGeneratedOfferAccepted>
4066
+ nomosInternalOfferRemoteGeneratedCall({
4067
+ required String targetWorkspace,
4068
+ required String actor,
4069
+ required String authorSecret,
4070
+ String? authToken,
4071
+ required NmsGeneratedCall call,
4072
+ }) async {
4073
+ final response = await _invokeRuntimeV2(
4074
+ nomos_protocol.RuntimeRequest(
4075
+ remoteGeneratedOffer: nomos_protocol.RemoteGeneratedOfferRequest(
4076
+ sourceSession: _runtimeSession(),
4077
+ targetWorkspace: targetWorkspace,
4078
+ actor: actor,
4079
+ authorSecret: base64Decode(authorSecret),
4080
+ authToken: utf8.encode(authToken ?? ''),
4081
+ call: nomos_protocol.DirectiveCall(
4082
+ domain: call.domain,
4083
+ directive: call.directive,
4084
+ callUsda: call.canonicalUsda,
4085
+ ),
4086
+ ),
4087
+ ),
4088
+ );
4089
+ if (!response.hasRemoteGeneratedOffer()) {
4090
+ throw StateError(
4091
+ 'Runtime v2 returned ${response.whichOutcome().name} for a remote generated offer',
4092
+ );
4093
+ }
4094
+ return response.remoteGeneratedOffer;
4095
+ }
4096
+
4019
4097
  /// Sign a cross-custody SHARE attestation `{secret, asserterWorkspace, object, relation, subject,
4020
4098
  /// attestedAt}` → `{publicKey, signature}`. This is what drives `recordShare` into an invitee's home
4021
4099
  /// (the free global invitation system): the granting workspace signs that it shares `object#relation`
@@ -4057,8 +4135,9 @@ class NomosBridge {
4057
4135
  nomos_protocol.QueryAuthority _nmsQueryAuthority(
4058
4136
  List<NomosScopeKey>? keys,
4059
4137
  String? principal,
4060
- String? session,
4061
- ) {
4138
+ String? session, {
4139
+ String? authorSecret,
4140
+ }) {
4062
4141
  final runtimeSession = session ?? _sessionName;
4063
4142
  if (runtimeSession == null || runtimeSession.isEmpty) {
4064
4143
  throw StateError(
@@ -4066,7 +4145,7 @@ class NomosBridge {
4066
4145
  }
4067
4146
  final plane = _eventPlane;
4068
4147
  final token = plane._sessionAuthTokens[runtimeSession];
4069
- final secret = plane._sessionAuthorSecrets[runtimeSession];
4148
+ final secret = authorSecret ?? plane._sessionAuthorSecrets[runtimeSession];
4070
4149
  return nomos_protocol.QueryAuthority(
4071
4150
  principalClaim:
4072
4151
  principal ?? plane._sessionPrincipals[runtimeSession] ?? '',
@@ -4206,10 +4285,16 @@ class NomosBridge {
4206
4285
  Future<NomosAuthenticationPosture> nmsAuthenticationPosture({
4207
4286
  String? session,
4208
4287
  String? principal,
4288
+ String? authorSecret,
4209
4289
  }) async {
4210
4290
  final response = await _nmsKernelQuery(
4211
4291
  session: session,
4212
- authority: _nmsQueryAuthority(null, principal, session),
4292
+ authority: _nmsQueryAuthority(
4293
+ null,
4294
+ principal,
4295
+ session,
4296
+ authorSecret: authorSecret,
4297
+ ),
4213
4298
  query: nomos_protocol.QueryRequest(
4214
4299
  authenticationPosture: nomos_protocol.AuthenticationPostureQuery(),
4215
4300
  ),
@@ -4220,11 +4305,16 @@ class NomosBridge {
4220
4305
  );
4221
4306
  }
4222
4307
  final posture = response.authenticationPosture;
4223
- return NomosAuthenticationPosture(
4308
+ final result = NomosAuthenticationPosture(
4224
4309
  providerToken: _providerTokenVerification(posture.providerToken),
4225
4310
  enrolledDevice: posture.enrolledDevice,
4226
4311
  resolvedPrincipal: posture.resolvedPrincipal,
4227
4312
  );
4313
+ print(
4314
+ '[nomos-auth-posture] workspace=${_eventPlane._workspaceBySession[session ?? _sessionName] ?? session ?? _sessionName ?? ''} '
4315
+ 'token=${result.providerToken.name} enrolled=${result.enrolledDevice} '
4316
+ 'principal=${result.resolvedPrincipal.isEmpty ? 'unresolved' : 'resolved'}');
4317
+ return result;
4228
4318
  }
4229
4319
 
4230
4320
  /// Drive actual custody synchronization until the kernel proves that the
@@ -4235,6 +4325,7 @@ class NomosBridge {
4235
4325
  Future<NomosAuthenticationPosture> nmsAwaitAuthenticationReady({
4236
4326
  String? session,
4237
4327
  String? principal,
4328
+ String? authorSecret,
4238
4329
  int maximumSyncRounds = 4,
4239
4330
  }) async {
4240
4331
  final runtimeSession = session ?? _sessionName;
@@ -4247,11 +4338,20 @@ class NomosBridge {
4247
4338
  var posture = await nmsAuthenticationPosture(
4248
4339
  session: session,
4249
4340
  principal: expectedPrincipal,
4341
+ authorSecret: authorSecret,
4250
4342
  );
4251
4343
  if (posture.isReadyFor(expectedPrincipal)) return posture;
4252
4344
 
4253
4345
  for (var round = 0; round < maximumSyncRounds; round++) {
4254
4346
  final result = await sync(admit: true, session: session);
4347
+ print(
4348
+ '[nomos-auth-recovery] workspace=${_eventPlane._workspaceBySession[runtimeSession] ?? runtimeSession ?? ''} '
4349
+ 'round=${round + 1}/$maximumSyncRounds pulled=${result.pulled} '
4350
+ 'previous=${result.hasPreviousHead() ? (result.previousHead.length > 12 ? result.previousHead.substring(0, 12) : result.previousHead) : 'none'} '
4351
+ 'current=${result.hasCurrentHead() ? (result.currentHead.length > 12 ? result.currentHead.substring(0, 12) : result.currentHead) : 'none'} '
4352
+ 'ahead=${result.stillAhead} diverged=${result.diverged} reconnect=${result.reconnectRequired} '
4353
+ 'deferred=${result.deferred} refused=${result.refused} offline=${result.offline} pushFailed=${result.pushFailed}',
4354
+ );
4255
4355
  if (result.offline || result.pushFailed) {
4256
4356
  throw StateError(
4257
4357
  'Authentication recovery could not converge custody: '
@@ -4261,15 +4361,68 @@ class NomosBridge {
4261
4361
  posture = await nmsAuthenticationPosture(
4262
4362
  session: session,
4263
4363
  principal: expectedPrincipal,
4364
+ authorSecret: authorSecret,
4264
4365
  );
4265
4366
  if (posture.isReadyFor(expectedPrincipal)) return posture;
4266
4367
  }
4267
- throw StateError(
4368
+ final failure = StateError(
4268
4369
  'Authentication recovery did not establish a valid provider token and enrolled device '
4269
4370
  'for $expectedPrincipal after $maximumSyncRounds custody rounds '
4270
4371
  '(token: ${posture.providerToken.name}, enrolled: ${posture.enrolledDevice}, '
4271
4372
  'resolved: ${posture.resolvedPrincipal})',
4272
4373
  );
4374
+ print(
4375
+ '[nomos-auth-recovery-exhausted] '
4376
+ 'workspace=${_eventPlane._workspaceBySession[runtimeSession] ?? runtimeSession ?? ''} '
4377
+ 'caller=${StackTrace.current}',
4378
+ );
4379
+ throw failure;
4380
+ }
4381
+
4382
+ /// Synchronize until the workspace can verify the signed-in provider token.
4383
+ /// This is deliberately weaker than [nmsAwaitAuthenticationReady]: historical
4384
+ /// child law may need the refreshed verifier before it can lawfully enrol the
4385
+ /// current device and adopt its successor law.
4386
+ @internal
4387
+ Future<NomosAuthenticationPosture> nmsAwaitProviderTokenReady({
4388
+ String? session,
4389
+ String? principal,
4390
+ int maximumSyncRounds = 4,
4391
+ }) async {
4392
+ final runtimeSession = session ?? _sessionName;
4393
+ final expectedPrincipal = principal ??
4394
+ this.principal ??
4395
+ (runtimeSession == null
4396
+ ? null
4397
+ : _eventPlane._sessionPrincipals[runtimeSession]) ??
4398
+ '';
4399
+ bool ready(NomosAuthenticationPosture posture) =>
4400
+ posture.providerToken == NomosProviderTokenVerification.valid &&
4401
+ posture.resolvedPrincipal == expectedPrincipal;
4402
+ var posture = await nmsAuthenticationPosture(
4403
+ session: session,
4404
+ principal: expectedPrincipal,
4405
+ );
4406
+ if (ready(posture)) return posture;
4407
+ for (var round = 0; round < maximumSyncRounds; round++) {
4408
+ final result = await sync(admit: true, session: session);
4409
+ if (result.offline || result.pushFailed) {
4410
+ throw StateError(
4411
+ 'Provider recovery could not converge custody: '
4412
+ '${result.hasPushError() ? result.pushError.message : 'workspace is offline'}',
4413
+ );
4414
+ }
4415
+ posture = await nmsAuthenticationPosture(
4416
+ session: session,
4417
+ principal: expectedPrincipal,
4418
+ );
4419
+ if (ready(posture)) return posture;
4420
+ }
4421
+ throw StateError(
4422
+ 'Provider recovery did not establish a valid token for '
4423
+ '$expectedPrincipal after $maximumSyncRounds custody rounds '
4424
+ '(token: ${posture.providerToken.name}, resolved: ${posture.resolvedPrincipal})',
4425
+ );
4273
4426
  }
4274
4427
 
4275
4428
  Future<nomos_protocol.QueryResponse> _nmsKernelHistoricQuery({
@@ -5295,9 +5448,25 @@ class NomosBridge {
5295
5448
  (_asMap(await _call('export'))['snapshot'] ?? '').toString();
5296
5449
 
5297
5450
  /// The local ledger tip (an O(1) ref read). Cheap change signal — persistence skips re-exporting an
5298
- /// unchanged snapshot when [head] matches the last saved tip.
5299
- Future<String> head() async =>
5300
- (_asMap(await _call('head'))['head'] ?? '').toString();
5451
+ /// unchanged snapshot when [head] matches the last saved tip. Runtime v2 carries this as an optional
5452
+ /// protobuf field so an unborn workspace is distinct from a malformed bridge result.
5453
+ Future<String> head() async {
5454
+ final response = await _invokeRuntimeV2(
5455
+ nomos_protocol.RuntimeRequest(
5456
+ workspaceStatus: nomos_protocol.WorkspaceStatusRequest(
5457
+ session: _runtimeSession(),
5458
+ ),
5459
+ ),
5460
+ );
5461
+ if (!response.hasWorkspaceStatus()) {
5462
+ throw StateError(
5463
+ 'Runtime v2 returned ${response.whichOutcome().name}, expected workspaceStatus',
5464
+ );
5465
+ }
5466
+ return response.workspaceStatus.hasHead()
5467
+ ? response.workspaceStatus.head
5468
+ : '';
5469
+ }
5301
5470
 
5302
5471
  /// AUTO-SYNC — event-driven background sync. The edge DOORBELL converges peers' writes in real time and a
5303
5472
  /// local write flushes the up leg at once; `fallbackMs` is only a just-in-case safety pull (default 60s).
@@ -6119,21 +6288,32 @@ class NomosSession extends NomosBridge {
6119
6288
  'Generated child model inheritance needs a bound parent session.',
6120
6289
  );
6121
6290
  }
6122
- final response = await _invokeRuntimeV2(
6123
- nomos_protocol.RuntimeRequest(
6124
- modelLifecycle: nomos_protocol.ModelLifecycleRequest(
6125
- session: childWorkspace,
6126
- stage: nomos_protocol.StageGeneratedModelRequest(
6127
- domain: domain,
6128
- candidateHash: candidateHash,
6129
- lawUsdz: lawUsdz,
6130
- sourceSession: source,
6291
+ print(
6292
+ '[nomos-model-stage] child domain=$domain source=$source target=$childWorkspace',
6293
+ );
6294
+ late final nomos_protocol.RuntimeResponse response;
6295
+ try {
6296
+ response = await _invokeRuntimeV2(
6297
+ nomos_protocol.RuntimeRequest(
6298
+ modelLifecycle: nomos_protocol.ModelLifecycleRequest(
6299
+ session: childWorkspace,
6300
+ stage: nomos_protocol.StageGeneratedModelRequest(
6301
+ domain: domain,
6302
+ candidateHash: candidateHash,
6303
+ lawUsdz: lawUsdz,
6304
+ sourceSession: source,
6305
+ ),
6131
6306
  ),
6132
6307
  ),
6133
- ),
6134
- );
6308
+ );
6309
+ } on NomosBridgeError catch (error) {
6310
+ print(
6311
+ '[nomos-model-stage] child refused domain=$domain as ${error.runtimeType}',
6312
+ );
6313
+ throw NomosModelStageFailure(error.message);
6314
+ }
6135
6315
  if (!response.hasModelLifecycle() || !response.modelLifecycle.accepted) {
6136
- throw StateError(
6316
+ throw NomosModelStageFailure(
6137
6317
  response.hasModelLifecycle() && response.modelLifecycle.hasMessage()
6138
6318
  ? response.modelLifecycle.message
6139
6319
  : 'Runtime v2 refused generated child model staging',
package/dart/pubspec.lock CHANGED
@@ -199,7 +199,7 @@ packages:
199
199
  path: "../dart_types"
200
200
  relative: true
201
201
  source: path
202
- version: "0.9.0"
202
+ version: "0.10.0"
203
203
  package_config:
204
204
  dependency: "direct main"
205
205
  description:
package/dart/pubspec.yaml CHANGED
@@ -7,7 +7,7 @@ repository: https://github.com/Captain-App/nomos2
7
7
  description: >-
8
8
  Nomos 2 Dart client — generated domain values, intent payloads and application
9
9
  lifecycle types over the typed Nomos kernel protocol and USDA custody model.
10
- version: 0.65.2
10
+ version: 0.65.3
11
11
 
12
12
  environment:
13
13
  sdk: ^3.5.0
@@ -16,7 +16,7 @@ dependencies:
16
16
  # The pure-data core (wire types, offer codec, NomosReads, schema validation, error
17
17
  # info). nomos_client depends on and re-exports it, so existing imports are unchanged.
18
18
  # For local monorepo dev, pubspec_overrides.yaml points this at ../dart_types.
19
- nomos_types: ^0.10.0
19
+ nomos_types: ^0.10.1
20
20
  fixnum: ^1.1.1
21
21
  json_schema: ^5.2.2
22
22
  crypto: ^3.0.0
@@ -41,12 +41,13 @@ void main() {
41
41
  await bridge.ready.timeout(const Duration(seconds: 15));
42
42
  });
43
43
 
44
- test('a pre-connect op answers a typed bridge error', () async {
44
+ test('a pre-connect position read fails before crossing the runtime boundary',
45
+ () async {
45
46
  await bridge.ready.timeout(const Duration(seconds: 15));
46
47
  await expectLater(
47
48
  bridge.head(),
48
- throwsA(isA<NomosBridgeError>()
49
- .having((e) => e.message, 'message', contains('not connected'))),
49
+ throwsA(isA<StateError>().having((e) => e.message, 'message',
50
+ contains('No Nomos workspace is connected'))),
50
51
  );
51
52
  });
52
53
 
@@ -65,8 +66,7 @@ void main() {
65
66
  : null,
66
67
  () async {
67
68
  final ws = Platform.environment['NOMOS_HEADLESS_E2E']!;
68
- final cloud = Platform.environment['NOMOS_CLOUD'] ??
69
- 'https://nomos.cafe';
69
+ final cloud = Platform.environment['NOMOS_CLOUD'] ?? 'https://nomos.cafe';
70
70
  await bridge.ready.timeout(const Duration(seconds: 15));
71
71
  await bridge.connect(
72
72
  cloud: cloud, workspace: ws, clientId: 'headless-test');
@@ -24,6 +24,12 @@ protocol.RuntimeResponse _runtimeLifecycleResponse(
24
24
  case protocol.RuntimeRequest_Command.listWorkspaces:
25
25
  response.workspaceList = protocol.WorkspaceList();
26
26
  break;
27
+ case protocol.RuntimeRequest_Command.workspaceStatus:
28
+ response.workspaceStatus = protocol.WorkspaceStatus(
29
+ workspace: request.workspaceStatus.session,
30
+ head: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
31
+ );
32
+ break;
27
33
  case protocol.RuntimeRequest_Command.prepareDomain:
28
34
  response.domainPrepared = protocol.DomainPrepared(
29
35
  domain: request.prepareDomain.domain,
@@ -1,3 +1,7 @@
1
+ ## 0.10.1
2
+
3
+ - Carry the current typed Runtime v2 authentication, remote-offer, model-lifecycle, and custody frames from the shared Protobuf authority.
4
+
1
5
  ## 0.10.0
2
6
 
3
7
  - Replace the retired Runtime v1 command model with the generated Runtime v2 and custody snapshot