@githolon/dsl 0.100.6 → 0.101.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 (82) hide show
  1. package/dart/CHANGELOG.md +6 -0
  2. package/dart/lib/src/dev_cloud.dart +46 -15
  3. package/dart/lib/src/test_harness.dart +78 -16
  4. package/dart/lib/src/webview_bridge.dart +640 -126
  5. package/dart/pubspec.lock +1 -1
  6. package/dart/pubspec.yaml +2 -2
  7. package/dart/test/bundle_version_pairing_test.dart +11 -22
  8. package/dart/test/co2_product_gauntlet_test.dart +228 -0
  9. package/dart/test/errors_test.dart +63 -12
  10. package/dart/test/first_app_gauntlet_test.dart +29 -3
  11. package/dart/test/webview_bridge_test.dart +274 -0
  12. package/dart_types/CHANGELOG.md +6 -0
  13. package/dart_types/lib/src/errors.dart +136 -30
  14. package/dart_types/lib/src/surfaced.dart +48 -2
  15. package/dart_types/lib/src/wire.dart +3 -1
  16. package/dart_types/pubspec.yaml +1 -1
  17. package/dart_types/test/surfaced_test.dart +19 -0
  18. package/package.json +1 -1
  19. package/src/activity.ts +43 -4
  20. package/src/aggregate.ts +132 -22
  21. package/src/attested_core.ts +1 -1
  22. package/src/authoring.ts +119 -6
  23. package/src/birth_meter.ts +4 -4
  24. package/src/birth_meter_ensure.ts +9 -1
  25. package/src/births.ts +53 -22
  26. package/src/build_package.ts +55 -14
  27. package/src/business_birth.ts +48 -7
  28. package/src/codegen_dart.ts +267 -37
  29. package/src/codegen_dart_client.ts +921 -82
  30. package/src/codegen_openapi.ts +28 -5
  31. package/src/codegen_proof.ts +107 -11
  32. package/src/codegen_ts.ts +961 -135
  33. package/src/compile_package_main.ts +155 -45
  34. package/src/conflicts.ts +252 -0
  35. package/src/describe_model.ts +448 -0
  36. package/src/directive.ts +5 -38
  37. package/src/drivers.ts +12 -4
  38. package/src/engine_entry.ts +4 -0
  39. package/src/evolve_preview.ts +72 -11
  40. package/src/fields.ts +201 -55
  41. package/src/framework/application_home.ts +103 -0
  42. package/src/framework/application_home_domain.ts +2 -0
  43. package/src/framework/attested_receipts.ts +2 -2
  44. package/src/framework/auth_provider_law.ts +51 -24
  45. package/src/framework/business_corrections.ts +170 -0
  46. package/src/framework/disclosure.ts +1 -1
  47. package/src/framework/domain_lifecycle.ts +250 -16
  48. package/src/framework/encryption_identity.ts +1 -1
  49. package/src/framework/encryption_scope.ts +21 -13
  50. package/src/framework/era_certification.ts +1 -1
  51. package/src/framework/framework_aggregates.ts +2 -0
  52. package/src/framework/genesis.ts +1 -1
  53. package/src/framework/home.ts +22 -9
  54. package/src/framework/identity.ts +5 -5
  55. package/src/framework/impure_capability.ts +2 -2
  56. package/src/framework/owned_custody.ts +561 -0
  57. package/src/framework/platform_admin.ts +1 -1
  58. package/src/framework/relations.ts +9 -1
  59. package/src/framework/repair.ts +1 -1
  60. package/src/framework/signing_identity.ts +2 -2
  61. package/src/framework/source_roster.ts +1 -1
  62. package/src/framework/workspaces.ts +17 -10
  63. package/src/generated_client_names.ts +39 -0
  64. package/src/index.ts +20 -15
  65. package/src/kernel_capabilities.ts +25 -1
  66. package/src/law_check.ts +4 -1
  67. package/src/manifest.ts +356 -63
  68. package/src/read_projection_manifest.ts +8 -0
  69. package/src/read_projection_namespace.ts +4 -0
  70. package/src/relation.ts +1 -1
  71. package/src/shape_compat.ts +47 -2
  72. package/src/stable_ids.ts +38 -6
  73. package/src/stable_ids_types.ts +30 -0
  74. package/src/surfaced_lint.ts +0 -0
  75. package/src/usd.ts +62 -11
  76. package/src/usd_layers.ts +54 -3
  77. package/src/value_object.ts +23 -19
  78. package/src/wire.ts +1 -0
  79. package/src/wire_encode.ts +48 -4
  80. package/src/workspace_routing.ts +57 -0
  81. package/src/workspace_sharding.ts +9 -9
  82. package/src/certified_read.ts +0 -313
@@ -68,7 +68,7 @@ export const KeyScope = aggregate("KeyScope", {
68
68
  scope: t.string().merge(Lww),
69
69
  currentEpoch: t.int().merge(Lww),
70
70
  openedAt: t.string().merge(Lww),
71
- });
71
+ }).public();
72
72
  export type KeyScopeHandle = typeof KeyScope;
73
73
 
74
74
  /**
@@ -84,7 +84,7 @@ export const WrappedKey = aggregate("WrappedKey", {
84
84
  recipientPubKey: t.string().merge(Lww), // base64 X25519 the wrap was sealed to
85
85
  hpkeEpk: t.string().merge(Lww), // base64 HPKE ephemeral public key
86
86
  ct: t.string().merge(Lww), // base64 sealed epoch secret
87
- });
87
+ }).public();
88
88
  export type WrappedKeyHandle = typeof WrappedKey;
89
89
 
90
90
  /** One wrap entry in an `advanceKeyEpoch` payload (computed client-side). */
@@ -97,7 +97,7 @@ const wrapEntrySchema = z.object({
97
97
  export type WrapEntry = z.infer<typeof wrapEntrySchema>;
98
98
 
99
99
  /** Build the plan ops for one wrap — a deterministic-keyed WrappedKey record. */
100
- function writeWrap(scope: string, epoch: number, w: WrapEntry): PlannedOp[] {
100
+ export function writeWrap(scope: string, epoch: number, w: WrapEntry): PlannedOp[] {
101
101
  const wk = instance(WrappedKey, wrappedKeyInstanceId(scope, epoch, w.recipientPrincipal));
102
102
  // The first op MATERIALIZES this new sibling bucket (`ensures` — a re-offer is idempotent);
103
103
  // the rest mutate it. Without the marker the referential gate rejects a set on an absent id.
@@ -111,6 +111,23 @@ function writeWrap(scope: string, epoch: number, w: WrapEntry): PlannedOp[] {
111
111
  ];
112
112
  }
113
113
 
114
+ /** Framework composition primitive: advance one scope head and materialize the supplied wraps. */
115
+ export function writeKeyEpoch(
116
+ scope: string,
117
+ epoch: number,
118
+ openedAt: string,
119
+ wraps: readonly WrapEntry[],
120
+ ): PlannedOp[] {
121
+ const ks = instance(KeyScope, keyScopeInstanceId(scope));
122
+ const ops: PlannedOp[] = [
123
+ withMarker(set(ks, "scope", scope), "ensures"),
124
+ set(ks, "currentEpoch", epoch),
125
+ set(ks, "openedAt", openedAt),
126
+ ];
127
+ for (const wrap of wraps) ops.push(...writeWrap(scope, epoch, wrap));
128
+ return ops;
129
+ }
130
+
114
131
  /**
115
132
  * `advanceKeyEpoch` — open a new epoch for `scope` and FAN OUT the wraps to every
116
133
  * member, in ONE intent. `epoch` is the new epoch number; `wraps` are the
@@ -129,16 +146,7 @@ export const advanceKeyEpoch = directive("advanceKeyEpoch")
129
146
  wraps: z.array(wrapEntrySchema),
130
147
  }),
131
148
  )
132
- .plan((p) => {
133
- const ks = instance(KeyScope, keyScopeInstanceId(p.scope));
134
- const ops: PlannedOp[] = [
135
- withMarker(set(ks, "scope", p.scope), "ensures"), // upsert the scope head (first advance creates it)
136
- set(ks, "currentEpoch", p.epoch),
137
- set(ks, "openedAt", p.openedAt),
138
- ];
139
- for (const w of p.wraps) ops.push(...writeWrap(p.scope, p.epoch, w));
140
- return ops;
141
- });
149
+ .plan((p) => writeKeyEpoch(p.scope, p.epoch, p.openedAt, p.wraps));
142
150
 
143
151
  /**
144
152
  * `wrapKey` — write ONE wrap (the single-member handoff). Beyond its use as a primitive,
@@ -33,7 +33,7 @@ export const EraCertification = aggregate("EraCertification", {
33
33
  reason: t.string().merge(Lww),
34
34
  /** The custodian's HLC at issue (audit). */
35
35
  certifiedAt: t.string().merge(Lww),
36
- });
36
+ }).public();
37
37
 
38
38
  const eraCertPayload = z.object({
39
39
  /** The content-addressed id for the folded fact (`sha256(canonical artifact)` — caller-computed). */
@@ -43,6 +43,7 @@ import * as encryptionScope from "./encryption_scope.js";
43
43
  import * as genesis from "./genesis.js";
44
44
  import * as home from "./home.js";
45
45
  import * as identity from "./identity.js";
46
+ import * as ownedCustody from "./owned_custody.js";
46
47
  import * as relations from "./relations.js";
47
48
  import * as repair from "./repair.js";
48
49
  import * as signingIdentity from "./signing_identity.js";
@@ -65,6 +66,7 @@ const FRAMEWORK_NAMESPACES: ReadonlyArray<Record<string, unknown>> = [
65
66
  genesis,
66
67
  home,
67
68
  identity,
69
+ ownedCustody,
68
70
  relations,
69
71
  repair,
70
72
  signingIdentity,
@@ -53,7 +53,7 @@ export const GenesisWarrant = aggregate("GenesisWarrant", {
53
53
  principal: t.string().merge(Lww), // the x-nomos-auth-verified owner, recorded at birth
54
54
  workspaceId: t.string().merge(Lww), // this workspace's unique self-id (the author-signature source binding)
55
55
  bornAt: t.string().merge(Lww), // ISO-8601, caller-stamped (determinism)
56
- });
56
+ }).public();
57
57
  export type GenesisWarrantHandle = typeof GenesisWarrant;
58
58
 
59
59
  /** The framework PRIMITIVE plan: record the founding warrant (singleton). */
@@ -36,7 +36,7 @@ import { set, type PlannedOp } from "../ops.js";
36
36
  import { query } from "../query.js";
37
37
  import { birth } from "../births.js";
38
38
  import { readFrameworkDeclared } from "../read.js";
39
- import { authProvider as authProviderQuery } from "./auth_provider_law.js";
39
+ import { authProvider as authProviderQuery, seedAuthProvider } from "./auth_provider_law.js";
40
40
  import { workspaceInvariant, refAs } from "./workspace_invariant.js";
41
41
  import { identityRelations } from "./signing_identity.js";
42
42
  import { writeTuple } from "./relations.js";
@@ -81,7 +81,7 @@ export const HomeOwner = aggregate("HomeOwner", {
81
81
  homeName: t.string().merge(Lww),
82
82
  /** ISO-8601, caller-stamped (determinism — no clock in the plan). */
83
83
  bornAt: t.string().merge(Lww),
84
- });
84
+ }).public();
85
85
 
86
86
  /**
87
87
  * THE HOME-OWNER RELATION (the ReBAC authority spine, co2 ask #1). The {@link HomeOwner} aggregate is the
@@ -185,7 +185,17 @@ export function homeNameOf(subject: string): string {
185
185
  * home).
186
186
  */
187
187
  export const HOME_LAW_DOMAIN = "home";
188
- export const birthHome = directive("birthHome")
188
+ /**
189
+ * Build the private home-birth primitive for the domain key that carries the home law.
190
+ *
191
+ * Most framework-authored laws still use the historic public `home` key through
192
+ * {@link birthHome}. Business packages use an obscure compiler-owned key instead, so a
193
+ * tenant remains free to model a business concept called "home". The key is closed over
194
+ * here and written into every child-genesis step; it is never a tenant payload field.
195
+ */
196
+ export function birthHomeForDomain(homeLawDomain: string) {
197
+ if (homeLawDomain.length === 0) throw new Error("birthHomeForDomain requires a non-empty home-law domain");
198
+ return directive("birthHome")
189
199
  .creates(HomeOwner) // the birth's law-declared touched type — the child's HomeOwner is what this offer seeds
190
200
  .payload(
191
201
  z.object({
@@ -262,7 +272,7 @@ export const birthHome = directive("birthHome")
262
272
  { domain: "nomos", directiveId: "installDomain", actor: founder, payload: { domainHash: p.lawHash }, domainHash: p.lawHash, domainPackageB64: "" },
263
273
  // SEED THE OWNER — the home is born OWNED; the homeNameBindsOwner invariant in the child's law proves
264
274
  // homeName == home-<sha256(owner)> at the child's own gate, so the slot can ONLY be its rightful owner's.
265
- { domain: HOME_LAW_DOMAIN, directiveId: "seedHomeOwner", actor: founder, payload: { principal: p.owner, homeName, bornAt: p.bornAt } },
275
+ { domain: homeLawDomain, directiveId: "seedHomeOwner", actor: founder, payload: { principal: p.owner, homeName, bornAt: p.bornAt } },
266
276
  // ENROL THE OWNER'S DEVICE on the warrant-free prefix (when supplied) — enrollSigner self-binds to
267
277
  // ctx.principal() (the owner), so this binds `ownerKeyHash` as the owner's signer BEFORE the warrant
268
278
  // closes bootstrap. This is what makes the born home SIGNER-READY (able to sign + self-serve-birth its own
@@ -272,7 +282,7 @@ export const birthHome = directive("birthHome")
272
282
  // ladder: every seed runs UNSIGNED on the still-warrant-free prefix; the warrant closes it). ERA-SAFE: a
273
283
  // home born earlier (pre-feature law, no such step in its recipe) replays byte-identical — the era rule
274
284
  // rides the LAW hash, not this branch.
275
- { domain: HOME_LAW_DOMAIN, directiveId: "enrollSigner", actor: founder, payload: { keyHash: p.ownerKeyHash, grantedBy: p.owner, grantedAt: 1, ...(verifiedVia !== undefined ? { verifiedVia } : {}) } },
285
+ { domain: homeLawDomain, directiveId: "enrollSigner", actor: founder, payload: { keyHash: p.ownerKeyHash, grantedBy: p.owner, grantedAt: 1, ...(verifiedVia !== undefined ? { verifiedVia } : {}) } },
276
286
  ];
277
287
  // AUTHPROVIDER INHERITANCE (default ON — see the payload doc): copy the parent's declared provider
278
288
  // (the up-front captured read above) AS DATA into the child genesis. The child owns the copy as its
@@ -282,8 +292,8 @@ export const birthHome = directive("birthHome")
282
292
  const issuer = str("issuer");
283
293
  if (issuer !== undefined) {
284
294
  genesisChain.push({
285
- domain: HOME_LAW_DOMAIN,
286
- directiveId: "setAuthProvider",
295
+ domain: homeLawDomain,
296
+ directiveId: "seedAuthProvider",
287
297
  actor: founder,
288
298
  payload: {
289
299
  issuer,
@@ -309,6 +319,9 @@ export const birthHome = directive("birthHome")
309
319
  })
310
320
  .reads(authProviderQuery) // the parent-side AuthProvider capture the inheritance copies (the #58 lane)
311
321
  .births(); // BIRTH IS A DECLARED KERNEL PRIMITIVE — emits the `nomosBirthGate` era key; the kernel folds the recipe
322
+ }
323
+
324
+ export const birthHome = birthHomeForDomain(HOME_LAW_DOMAIN);
312
325
 
313
326
  /**
314
327
  * THE SHARED-WITH-ME INDEX (§5) — one record per cross-custody attestation delivered to this home holon:
@@ -330,7 +343,7 @@ export const SharedWithMe = aggregate("SharedWithMe", {
330
343
  /** PRUNED (forward-check fail-safe): set when the live `Check` on the asserter denies — the hint is
331
344
  * dropped from the list but the audit row stays. `""` = live. */
332
345
  prunedAt: t.string().merge(Lww),
333
- });
346
+ }).public();
334
347
 
335
348
  /**
336
349
  * `recordShare` — index a cross-custody share into the home holon's access list. AUTHORED on the home
@@ -418,7 +431,7 @@ export const BirthAttestation = aggregate("BirthAttestation", {
418
431
  * home (`child`==self-id, `founder`==HomeOwner.principal, `verified`). It travels because it folds into
419
432
  * the home's own genesis (seeded by the parent's offer-effect), so a peer holding only the home has it. */
420
433
  certChain: t.string().merge(Lww),
421
- });
434
+ }).public();
422
435
 
423
436
  /** Audit read: this home's birth attestation (who attested it + the verified verdict). */
424
437
  export const birthAttestation = query("birthAttestation").key("child").returns(BirthAttestation);
@@ -117,7 +117,7 @@ export const Actor = aggregate("Actor", {
117
117
  revokedDeviceKeyIds: t.set(t.string()).merge(AddWins),
118
118
  createdAt: t.string().merge(Lww), // ISO-8601; immutable-after-create (NOTE 1a)
119
119
  updatedAt: t.string().merge(Lww),
120
- });
120
+ }).public();
121
121
 
122
122
  /**
123
123
  * The User aggregate — an actor's human-facing profile. Field shapes mirror the
@@ -138,7 +138,7 @@ export const User = aggregate("User", {
138
138
  profile: t.map(t.string()).merge(MapOf(Lww)),
139
139
  registeredAt: t.string().merge(Lww), // immutable-after-create (NOTE 1a)
140
140
  updatedAt: t.string().merge(Lww),
141
- });
141
+ }).public();
142
142
 
143
143
  /**
144
144
  * The DeviceKey aggregate — a device-scoped key bound to an actor. "Each device
@@ -164,7 +164,7 @@ export const DeviceKey = aggregate("DeviceKey", {
164
164
  // Optional hint of last authorship by this key; NOT provenance (NOTE 1c). Not
165
165
  // folded at create — OPTIONAL.
166
166
  lastAuthoredAt: t.string().merge(Lww).optional(),
167
- });
167
+ }).public();
168
168
 
169
169
  /**
170
170
  * The Organization aggregate — mirrors the Dart `CreateOrganization` shape. Org
@@ -195,7 +195,7 @@ export const Organization = aggregate("Organization", {
195
195
  createdBy: t.string().merge(Lww),
196
196
  createdAt: t.string().merge(Lww),
197
197
  updatedAt: t.string().merge(Lww),
198
- });
198
+ }).public();
199
199
 
200
200
  /**
201
201
  * The PublicUser aggregate — the lightweight public-facing profile index (display
@@ -209,7 +209,7 @@ export const PublicUser = aggregate("PublicUser", {
209
209
  // `createPublicUser` folds photoUrl only when supplied — OPTIONAL (read-decode gap).
210
210
  photoUrl: t.string().merge(Lww).optional(),
211
211
  updatedAt: t.string().merge(Lww),
212
- });
212
+ }).public();
213
213
 
214
214
  // ───────────────────────────── Directives ──────────────────────────────────
215
215
 
@@ -168,7 +168,7 @@ export function impureCapabilityAggregate<
168
168
  // GLOBAL (read-projection namespacing opt-out): the capability lane addresses the envelope
169
169
  // by its BARE declared id (`nomosCapabilities.aggregateId` → the obligation rows the holon
170
170
  // surfaces), so the envelope's type name must not be domain-qualified.
171
- return aggregate(id, { ...IMPURE_CAPABILITY_ENVELOPE, ...params }, { global: true });
171
+ return aggregate(id, { ...IMPURE_CAPABILITY_ENVELOPE, ...params }, { global: true }).public();
172
172
  }
173
173
 
174
174
  /**
@@ -238,7 +238,7 @@ const deadLetterSchema = z.object({
238
238
  * handle; the envelope handle just types the envelope subset for `set()`).
239
239
  */
240
240
  function envelopeInstance(aggregateId: string, requestId: string) {
241
- const envelopeHandle = aggregate(aggregateId, IMPURE_CAPABILITY_ENVELOPE, { global: true });
241
+ const envelopeHandle = aggregate(aggregateId, IMPURE_CAPABILITY_ENVELOPE, { global: true }).public();
242
242
  return instance(envelopeHandle, impureCapabilityInstanceId(requestId));
243
243
  }
244
244