@githolon/dsl 0.45.0 → 0.47.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 +5 -0
- package/dart/lib/src/errors.dart +250 -0
- package/dart/lib/src/test_harness.dart +182 -175
- package/dart/lib/src/webview_bridge.dart +38 -4
- package/dart/pubspec.yaml +1 -1
- package/dart/test/errors_test.dart +77 -0
- package/dart/test/test_harness_test.dart +85 -57
- package/package.json +1 -1
- package/src/codegen_dart.ts +25 -14
- package/src/codegen_dart_client.ts +33 -1
- package/src/codegen_proof.ts +255 -23
- package/src/codegen_ts.ts +33 -0
- package/src/compat_manifest.ts +20 -0
- package/src/compile_package_main.ts +174 -16
- package/src/framework/framework_aggregates.ts +18 -0
- package/src/read_projection_composition.ts +9 -9
- package/src/read_projection_namespace.ts +4 -5
- package/src/usd.ts +3 -3
- package/src/value_object.ts +10 -9
package/dart/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
## 0.32.0
|
|
2
|
+
|
|
3
|
+
- SPATIAL READS: `NomosBbox` + `NomosBridge.spatialWithin(spatialId, bbox)` + `watchSpatial(...)` — the R*Tree probe surfaces on the bridge; generated clients (tooling ≥0.46) emit typed `sitesByBounds({required NomosBbox bbox})` + watch accessors.
|
|
4
|
+
- Analyzer-clean under strict lints (curly-braces rule) — the two remaining unbraced ifs in the bridge are gone.
|
|
5
|
+
|
|
1
6
|
## 0.31.0
|
|
2
7
|
|
|
3
8
|
- `NomosFieldMeta.fromBirth` — the registry surfaces BIRTH-PRESENCE LAW (`.fromBirth()` fields, tooling ≥0.42): a gate invariant guarantees the field present on every row, and the generated read models type it non-nullable.
|
package/dart/lib/src/errors.dart
CHANGED
|
@@ -22,9 +22,259 @@ import 'webview_bridge.dart' show NomosBridgeError, NomosErrorInfo;
|
|
|
22
22
|
/// [NomosBridgeError]. Apps `switch` on the type / `code`, never scrape prose.
|
|
23
23
|
NomosBridgeError nomosErrorFromInfo(NomosErrorInfo info) {
|
|
24
24
|
if (info.code.startsWith('nomos.custody.')) return CustodyError.fromInfo(info);
|
|
25
|
+
if (info.code.startsWith('nomos.law.')) return LawMismatchError.fromInfo(info);
|
|
26
|
+
if (info.code.startsWith('nomos.auth.')) return AuthError.fromInfo(info);
|
|
27
|
+
if (info.code.startsWith('nomos.load.')) return LoadError.fromInfo(info);
|
|
25
28
|
return NomosBridgeError(info.message, info: info);
|
|
26
29
|
}
|
|
27
30
|
|
|
31
|
+
/// THE ONE recommendedAction vocabulary, shared across EVERY typed error (custody, law, auth, load). A repair
|
|
32
|
+
/// button branches on these stable strings, so there is exactly one lane per failure and no parallel spelling.
|
|
33
|
+
/// [CustodyError.recommendedAction] already uses these strings — this names them so the other families reuse
|
|
34
|
+
/// the SAME set rather than inventing their own.
|
|
35
|
+
class NomosRecommendedAction {
|
|
36
|
+
NomosRecommendedAction._();
|
|
37
|
+
|
|
38
|
+
/// Regenerate the typed client against the deployed law (`githolon compile` / `npx nomos-compile`).
|
|
39
|
+
static const recompileClient = 'recompileClient';
|
|
40
|
+
|
|
41
|
+
/// Redeploy the client's law package to the workspace (`POST /v2/workspaces/<ws>/domains`).
|
|
42
|
+
static const redeployLaw = 'redeployLaw';
|
|
43
|
+
|
|
44
|
+
/// Re-acquire a fresh auth-provider token and reconnect.
|
|
45
|
+
static const reauth = 'reauth';
|
|
46
|
+
|
|
47
|
+
/// Quarantine the local snapshot and re-clone fresh (evict local custody).
|
|
48
|
+
static const quarantineLocalSnapshotAndReclone = 'quarantineLocalSnapshotAndReclone';
|
|
49
|
+
|
|
50
|
+
/// Ask the cloud to serve the full chain and retry (escalate cloud custody).
|
|
51
|
+
static const refetchFullHistoryAndRetry = 'refetchFullHistoryAndRetry';
|
|
52
|
+
|
|
53
|
+
/// Transient — retry the operation.
|
|
54
|
+
static const retry = 'retry';
|
|
55
|
+
|
|
56
|
+
/// Re-open the holon / reconnect fresh (the loaded runtime is unusable).
|
|
57
|
+
static const reopen = 'reopen';
|
|
58
|
+
|
|
59
|
+
/// No automatic remedy — surface to a human.
|
|
60
|
+
static const none = 'none';
|
|
61
|
+
|
|
62
|
+
/// A one-line, human-first sentence for [action] — used in the typed messages so a log line reads as prose.
|
|
63
|
+
static String sentence(String action) {
|
|
64
|
+
switch (action) {
|
|
65
|
+
case recompileClient:
|
|
66
|
+
return 'recompile the client (githolon compile / npx nomos-compile) against the deployed law';
|
|
67
|
+
case redeployLaw:
|
|
68
|
+
return 'redeploy the package (POST /v2/workspaces/<ws>/domains) so the workspace runs the client\'s law';
|
|
69
|
+
case reauth:
|
|
70
|
+
return 're-authenticate (acquire a fresh auth-provider token) and reconnect';
|
|
71
|
+
case quarantineLocalSnapshotAndReclone:
|
|
72
|
+
return 'quarantine the local snapshot and re-clone fresh';
|
|
73
|
+
case refetchFullHistoryAndRetry:
|
|
74
|
+
return 'refetch the full history from the cloud and retry';
|
|
75
|
+
case retry:
|
|
76
|
+
return 'retry the operation';
|
|
77
|
+
case reopen:
|
|
78
|
+
return 'reopen the holon (reconnect fresh)';
|
|
79
|
+
case none:
|
|
80
|
+
return 'no automatic remedy — inspect the error';
|
|
81
|
+
default:
|
|
82
|
+
return action;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/// LAW DRIFT — the client was generated under one law and the workspace runs another (`nomos.law.*`): either a
|
|
88
|
+
/// §5 connect-time compat check, or a dispatch-time refusal when a payload's baked hash names law the workspace
|
|
89
|
+
/// no longer runs. When [structurallyCompatible] is true the operation can still proceed (structural subtyping);
|
|
90
|
+
/// when false it names the [incompatibleMember] that broke. REMEDY: `recompileClient` or `redeployLaw`.
|
|
91
|
+
class LawMismatchError extends NomosBridgeError {
|
|
92
|
+
/// The stable machine code, e.g. `nomos.law.mismatch`.
|
|
93
|
+
final String code;
|
|
94
|
+
|
|
95
|
+
/// The workspace whose installed law differs.
|
|
96
|
+
final String? workspace;
|
|
97
|
+
|
|
98
|
+
/// The law hash the CLIENT was generated for.
|
|
99
|
+
final String? generatedFor;
|
|
100
|
+
|
|
101
|
+
/// The law hash the WORKSPACE actually runs.
|
|
102
|
+
final String? workspaceRuns;
|
|
103
|
+
|
|
104
|
+
/// The failing lane: directive id / query id / `connect` / `sync`.
|
|
105
|
+
final String? operation;
|
|
106
|
+
|
|
107
|
+
/// True/false when a structural compat verdict is known; null when undecided (a bare hash mismatch).
|
|
108
|
+
final bool? structurallyCompatible;
|
|
109
|
+
|
|
110
|
+
/// The structural member that broke compat, when [structurallyCompatible] is false and one was named.
|
|
111
|
+
final String? incompatibleMember;
|
|
112
|
+
|
|
113
|
+
/// The named remedy from [NomosRecommendedAction] (`recompileClient` | `redeployLaw`).
|
|
114
|
+
final String recommendedAction;
|
|
115
|
+
|
|
116
|
+
LawMismatchError({
|
|
117
|
+
required this.code,
|
|
118
|
+
required String message,
|
|
119
|
+
this.workspace,
|
|
120
|
+
this.generatedFor,
|
|
121
|
+
this.workspaceRuns,
|
|
122
|
+
this.operation,
|
|
123
|
+
this.structurallyCompatible,
|
|
124
|
+
this.incompatibleMember,
|
|
125
|
+
this.recommendedAction = NomosRecommendedAction.recompileClient,
|
|
126
|
+
NomosErrorInfo? info,
|
|
127
|
+
}) : super(message, info: info);
|
|
128
|
+
|
|
129
|
+
factory LawMismatchError.fromInfo(NomosErrorInfo info) {
|
|
130
|
+
String? attr(String name) {
|
|
131
|
+
final v = info.attributes['nomos.law.$name'] ?? info.attributes[name];
|
|
132
|
+
return v?.toString();
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
bool? compat() {
|
|
136
|
+
final v = info.attributes['nomos.law.structurallyCompatible'] ??
|
|
137
|
+
info.attributes['structurallyCompatible'] ??
|
|
138
|
+
info.attributes['structurally_compatible'];
|
|
139
|
+
if (v is bool) return v;
|
|
140
|
+
if (v == null) return null;
|
|
141
|
+
final s = v.toString();
|
|
142
|
+
if (s == 'true') return true;
|
|
143
|
+
if (s == 'false') return false;
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return LawMismatchError(
|
|
148
|
+
code: info.code,
|
|
149
|
+
message: info.message,
|
|
150
|
+
workspace: info.workspace,
|
|
151
|
+
generatedFor: attr('generatedFor') ?? attr('generated_for') ?? attr('clientHash'),
|
|
152
|
+
workspaceRuns: attr('workspaceRuns') ?? attr('workspace_runs') ?? attr('installed'),
|
|
153
|
+
operation: info.operation ?? attr('operation'),
|
|
154
|
+
structurallyCompatible: compat(),
|
|
155
|
+
incompatibleMember: attr('incompatibleMember') ?? attr('incompatible_member') ?? attr('member'),
|
|
156
|
+
recommendedAction: attr('recommendedAction') ?? attr('recommended_action') ?? NomosRecommendedAction.recompileClient,
|
|
157
|
+
info: info,
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/// The exact asked-for mismatch sentence:
|
|
162
|
+
/// "client generated for law <X>, workspace runs law <Y>; <compat verdict> — <remedy sentence>".
|
|
163
|
+
String get mismatchMessage {
|
|
164
|
+
final x = generatedFor ?? 'unknown';
|
|
165
|
+
final y = workspaceRuns ?? 'unknown';
|
|
166
|
+
final verdict = structurallyCompatible == true
|
|
167
|
+
? 'structurally compatible — proceeding'
|
|
168
|
+
: (incompatibleMember != null
|
|
169
|
+
? 'structurally incompatible on $incompatibleMember'
|
|
170
|
+
: 'structurally incompatible');
|
|
171
|
+
return 'client generated for law $x, workspace runs law $y; $verdict — ${NomosRecommendedAction.sentence(recommendedAction)}';
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
@override
|
|
175
|
+
String toString() => 'LawMismatchError($code): $mismatchMessage';
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/// AUTH — the auth-provider token was missing/malformed/expired/rejected, or its issuer does not match the
|
|
179
|
+
/// workspace's law-declared key (`nomos.auth.*`, e.g. `nomos.auth.issuer_mismatch`, `nomos.auth.token_invalid`,
|
|
180
|
+
/// `nomos.auth.token_expired`). REMEDY is always `reauth`: acquire a fresh token and reconnect.
|
|
181
|
+
class AuthError extends NomosBridgeError {
|
|
182
|
+
/// The stable machine code, e.g. `nomos.auth.issuer_mismatch`.
|
|
183
|
+
final String code;
|
|
184
|
+
|
|
185
|
+
/// The workspace the auth was for.
|
|
186
|
+
final String? workspace;
|
|
187
|
+
|
|
188
|
+
/// The token issuer, when one was decodable (present on an issuer mismatch).
|
|
189
|
+
final String? issuer;
|
|
190
|
+
|
|
191
|
+
/// The failing lane (e.g. `connect` / a birth directive id).
|
|
192
|
+
final String? operation;
|
|
193
|
+
|
|
194
|
+
/// The named remedy — always `reauth`.
|
|
195
|
+
final String recommendedAction;
|
|
196
|
+
|
|
197
|
+
AuthError({
|
|
198
|
+
required this.code,
|
|
199
|
+
required String message,
|
|
200
|
+
this.workspace,
|
|
201
|
+
this.issuer,
|
|
202
|
+
this.operation,
|
|
203
|
+
this.recommendedAction = NomosRecommendedAction.reauth,
|
|
204
|
+
NomosErrorInfo? info,
|
|
205
|
+
}) : super(message, info: info);
|
|
206
|
+
|
|
207
|
+
factory AuthError.fromInfo(NomosErrorInfo info) {
|
|
208
|
+
String? attr(String name) {
|
|
209
|
+
final v = info.attributes['nomos.auth.$name'] ?? info.attributes[name];
|
|
210
|
+
return v?.toString();
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return AuthError(
|
|
214
|
+
code: info.code,
|
|
215
|
+
message: info.message,
|
|
216
|
+
workspace: info.workspace,
|
|
217
|
+
issuer: attr('issuer'),
|
|
218
|
+
operation: info.operation ?? attr('operation'),
|
|
219
|
+
recommendedAction: attr('recommendedAction') ?? attr('recommended_action') ?? NomosRecommendedAction.reauth,
|
|
220
|
+
info: info,
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
@override
|
|
225
|
+
String toString() =>
|
|
226
|
+
'AuthError($code${workspace != null ? ', workspace: $workspace' : ''}'
|
|
227
|
+
'${issuer != null ? ', issuer: $issuer' : ''}, recommendedAction: $recommendedAction): $message';
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/// LOAD — a runtime artifact (the holon wasm, a manifest, the runner) could not be fetched or instantiated
|
|
231
|
+
/// (`nomos.load.*`, e.g. `nomos.load.wasm_fetch_failed`, `nomos.load.instantiate_failed`,
|
|
232
|
+
/// `nomos.load.manifest_failed`). This is a transport/runtime fault, never a law refusal. REMEDY: `retry` for a
|
|
233
|
+
/// transient fetch, `reopen` when the loaded runtime is unusable.
|
|
234
|
+
class LoadError extends NomosBridgeError {
|
|
235
|
+
/// The stable machine code, e.g. `nomos.load.wasm_fetch_failed`.
|
|
236
|
+
final String code;
|
|
237
|
+
|
|
238
|
+
/// WHICH artifact failed to load (e.g. `holon.wasm`, `manifests`, the runner).
|
|
239
|
+
final String? artifact;
|
|
240
|
+
|
|
241
|
+
/// The URL the artifact was fetched from, when known.
|
|
242
|
+
final String? sourceUrl;
|
|
243
|
+
|
|
244
|
+
/// The named remedy from [NomosRecommendedAction] (`retry` | `reopen`).
|
|
245
|
+
final String recommendedAction;
|
|
246
|
+
|
|
247
|
+
LoadError({
|
|
248
|
+
required this.code,
|
|
249
|
+
required String message,
|
|
250
|
+
this.artifact,
|
|
251
|
+
this.sourceUrl,
|
|
252
|
+
this.recommendedAction = NomosRecommendedAction.retry,
|
|
253
|
+
NomosErrorInfo? info,
|
|
254
|
+
}) : super(message, info: info);
|
|
255
|
+
|
|
256
|
+
factory LoadError.fromInfo(NomosErrorInfo info) {
|
|
257
|
+
String? attr(String name) {
|
|
258
|
+
final v = info.attributes['nomos.load.$name'] ?? info.attributes[name];
|
|
259
|
+
return v?.toString();
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
return LoadError(
|
|
263
|
+
code: info.code,
|
|
264
|
+
message: info.message,
|
|
265
|
+
artifact: attr('artifact'),
|
|
266
|
+
sourceUrl: attr('sourceUrl') ?? attr('source_url') ?? attr('url'),
|
|
267
|
+
recommendedAction: attr('recommendedAction') ?? attr('recommended_action') ?? NomosRecommendedAction.retry,
|
|
268
|
+
info: info,
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
@override
|
|
273
|
+
String toString() =>
|
|
274
|
+
'LoadError($code${artifact != null ? ', artifact: $artifact' : ''}'
|
|
275
|
+
'${sourceUrl != null ? ', sourceUrl: $sourceUrl' : ''}, recommendedAction: $recommendedAction): $message';
|
|
276
|
+
}
|
|
277
|
+
|
|
28
278
|
/// The custody phase a [CustodyError] was raised in.
|
|
29
279
|
enum CustodyPhase { fold, author, fetch, unknown }
|
|
30
280
|
|