@githolon/dsl 0.103.8 → 0.103.10

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.
@@ -3338,7 +3338,14 @@ function generateSealedApplicationProof(
3338
3338
  ` if (!response.ok || !body.token) fail("the generated application could not attest its private device: " + (body.error || response.status));`,
3339
3339
  ` return body.token;`,
3340
3340
  `};`,
3341
- `const application = await ${opener}({ cloud, application: applicationName, signIn });`,
3341
+ `const performanceEnabled = process.env.NOMOS_PROOF_PERFORMANCE === "1";`,
3342
+ `const reportPerformance = performanceEnabled`,
3343
+ ` ? (sample: { readonly operation: string; readonly name: string; readonly durationMs: number; readonly domain?: string; readonly directive?: string }) =>`,
3344
+ ` console.error("[nomos-application-performance] " + JSON.stringify(sample))`,
3345
+ ` : undefined;`,
3346
+ `const coldOpenStarted = performance.now();`,
3347
+ `const application = await ${opener}({ cloud, application: applicationName, signIn, onPerformance: reportPerformance });`,
3348
+ `if (reportPerformance) reportPerformance({ operation: "open", name: "generated application ready (cold)", durationMs: performance.now() - coldOpenStarted });`,
3342
3349
  `ok("opened the generated ${applicationName}; identity, custody, recovery and sync stay inside Nomos");`,
3343
3350
  `const waitUntilSaved = async (): Promise<void> => {`,
3344
3351
  ` const current = await application.currentStatus();`,
@@ -3467,6 +3474,15 @@ function generateSealedApplicationProof(
3467
3474
  `const _proofDisposable = application as unknown as { [Symbol.asyncDispose]?: () => Promise<void> };`,
3468
3475
  `const _proofDispose = _proofDisposable[Symbol.asyncDispose];`,
3469
3476
  `if (_proofDispose) await Promise.race([_proofDispose(), new Promise<void>((resolve) => setTimeout(resolve, 1_000))]);`,
3477
+ `if (performanceEnabled) {`,
3478
+ ` const warmOpenStarted = performance.now();`,
3479
+ ` const warmApplication = await ${opener}({ cloud, application: applicationName, signIn, onPerformance: reportPerformance });`,
3480
+ ` reportPerformance?.({ operation: "open", name: "generated application ready (warm)", durationMs: performance.now() - warmOpenStarted });`,
3481
+ ` const warmStatus = await warmApplication.currentStatus();`,
3482
+ ` if (warmStatus.phase === "attention") fail(warmStatus.message ?? "the warm application needs attention");`,
3483
+ ` const warmDisposable = warmApplication as unknown as { [Symbol.asyncDispose]?: () => Promise<void> };`,
3484
+ ` if (warmDisposable[Symbol.asyncDispose]) await Promise.race([warmDisposable[Symbol.asyncDispose]!(), new Promise<void>((resolve) => setTimeout(resolve, 1_000))]);`,
3485
+ `}`,
3470
3486
  `process.exit(0);`,
3471
3487
  ``,
3472
3488
  );
package/src/codegen_ts.ts CHANGED
@@ -3920,6 +3920,10 @@ export function generateTsClient(modules: readonly DomainModule[], opts: TsClien
3920
3920
  ),
3921
3921
  `type _${applicationName}Business = ${applicationType};`,
3922
3922
  `export type ${applicationName}Status = _NomosApplicationStatus;`,
3923
+ `export interface ${applicationName}PerformanceSample {`,
3924
+ ` readonly operation: "open" | "offer" | "birth" | "read" | "sync" | "maintenance";`,
3925
+ ` readonly name: string; readonly durationMs: number; readonly domain?: string; readonly directive?: string;`,
3926
+ `}`,
3923
3927
  `export type ${applicationName} = _${applicationName}Business & _NomosApplicationParticipant & _NomosApplicationLifecycle & _NomosApplicationModelLifecycle${hasInvitations ? " & _NomosApplicationInvitations" : ""};`,
3924
3928
  `export interface ${applicationName}OpenOptions {`,
3925
3929
  ` /** Nomos Cloud serving this deployed application. Configure it once at the app boundary. */`,
@@ -3928,6 +3932,8 @@ export function generateTsClient(modules: readonly DomainModule[], opts: TsClien
3928
3932
  ` readonly application: string;`,
3929
3933
  ` /** Return the signed-in authority credential; when supplied, bind its opaque device challenge. */`,
3930
3934
  ` readonly signIn: (request?: { readonly deviceChallenge?: string }) => Promise<string>;`,
3935
+ ` /** Typed timings for developer tooling; Nomos routing, credentials and Git custody remain private. */`,
3936
+ ` readonly onPerformance?: (sample: ${applicationName}PerformanceSample) => void;`,
3931
3937
  `}`,
3932
3938
  `function _nomosPublicDomain<T extends Record<string, unknown>>(domain: T): _NomosPublicDomain<T> {`,
3933
3939
  ` const application: Record<string, unknown> = {};`,
@@ -4055,7 +4061,7 @@ export function generateTsClient(modules: readonly DomainModule[], opts: TsClien
4055
4061
  ` * or parallel cache around it. Nomos owns offline custody and synchronization. */`,
4056
4062
  `export function ${applicationOpener}(options: ${applicationName}OpenOptions): Promise<${applicationName}> {`,
4057
4063
  ` return nomosInternalOpenGeneratedApplication(`,
4058
- ` { cloud: options.cloud, application: options.application, signIn: options.signIn, lawHash: ${hashConst} },`,
4064
+ ` { cloud: options.cloud, application: options.application, signIn: options.signIn, onPerformance: options.onPerformance, lawHash: ${hashConst} },`,
4059
4065
  ` (holon, user) => _nomosBind${applicationName}(holon as NomosHolon, user),`,
4060
4066
  ` );`,
4061
4067
  `}`,
@@ -197,6 +197,10 @@ const DSL_DIR = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..")
197
197
  * here so a generated offer can never silently fall back to initializing the whole tenant domain.
198
198
  */
199
199
  const BUSINESS_BIRTH_FRAMEWORK_PLAN_SOURCES: Readonly<Record<string, PlanSourceSliceTarget>> = {
200
+ seedBirthPolicy: {
201
+ modulePath: path.join(DSL_DIR, "src", "framework", "birth_meter.ts"),
202
+ exportName: "seedBirthPolicy",
203
+ },
200
204
  enrollSigner: {
201
205
  modulePath: path.join(DSL_DIR, "src", "framework", "signing_identity.ts"),
202
206
  exportName: "enrollSigner",
@@ -1646,8 +1650,8 @@ const NOMOS_TYPES_DEP = "^0.8.4";
1646
1650
  // 0.48.x: session-bound clients (XClient.bind/NomosClientInterface/DomainClientSessionMismatch/
1647
1651
  // DomainNotInstalledForSession, engine.follow, pendingConflicts lanes) — the generated client
1648
1652
  // REQUIRES this surface. 0.48.1 fixes NomosSession.watchPendingConflicts delegation.
1649
- const NOMOS_CLIENT_DEP = "^0.64.7";
1650
- const NOMOS_FLUTTER_DEP = "^0.63.10";
1653
+ const NOMOS_CLIENT_DEP = "^0.64.10";
1654
+ const NOMOS_FLUTTER_DEP = "^0.63.13";
1651
1655
  // DRIFT TRIPWIRE: pubspec_pins.test.ts asserts these equal the CURRENT versions in dsl/dart/pubspec.yaml
1652
1656
  // and dsl/dart_types/pubspec.yaml — a Dart release without this bump fails the suite, so tenants never
1653
1657
  // land back in dependency_overrides (the exact co2 report this closes, third occurrence).
@@ -5173,7 +5177,7 @@ async function main(): Promise<void> {
5173
5177
  const temporaryDeclarationPath = temporaryClientPath.replace(/\.ts$/, ".d.ts");
5174
5178
  const runtimeTypesSource = [
5175
5179
  `export declare function nomosInternalOpenGeneratedApplication<T extends object>(`,
5176
- ` options: { cloud: string; application: string; signIn: (request?: { readonly deviceChallenge?: string }) => Promise<string>; lawHash: string },`,
5180
+ ` options: { cloud: string; application: string; signIn: (request?: { readonly deviceChallenge?: string }) => Promise<string>; onPerformance?: (sample: { readonly operation: "open" | "offer" | "birth" | "read" | "sync" | "maintenance"; readonly name: string; readonly durationMs: number; readonly domain?: string; readonly directive?: string }) => void; lawHash: string },`,
5177
5181
  ` bind: (holon: unknown, user: { readonly identityId: string; readonly identityAddress: string }) => T,`,
5178
5182
  `): Promise<T & {`,
5179
5183
  ` currentStatus(): Promise<any>;`,
@@ -294,10 +294,12 @@ export const stageDomain = directive(DOMAIN_LIFECYCLE_DIRECTIVES.Stage)
294
294
  })
295
295
  .requires(MODEL_LIFECYCLE_AUTHORITY);
296
296
 
297
- /** Make a staged package current. The package bytes are already committed; the kernel
298
- * re-loads them from prefix state and runs the evolve gate on this phase transition.
299
- * The prior version stays Active by default so gradual-rollout clients can still have
300
- * their declared era checked; the newer activation stamp alone makes this law current. */
297
+ /** Make a staged or retained Active package current. The package bytes are already
298
+ * committed; the kernel re-loads them from prefix state and runs the evolve gate on
299
+ * this governed transition. Prior versions stay Active by default so gradual-rollout
300
+ * clients can still have their declared era checked; the newer activation stamp alone
301
+ * makes this law current. Re-promoting a shadowed Active package is therefore the lawful,
302
+ * history-proved inverse of a later package taking its domain keys. */
301
303
  export const promoteDomain = directive(DOMAIN_LIFECYCLE_DIRECTIVES.Promote)
302
304
  .mutates(DomainInstallation)
303
305
  .payload(z.object({