@githolon/dsl 0.114.0 → 0.115.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 (67) hide show
  1. package/assets/operation-contract.wasm +0 -0
  2. package/dart/CHANGELOG.md +40 -0
  3. package/dart/lib/src/application_framework_calls.dart +7 -1
  4. package/dart/lib/src/console_enrolment.dart +7 -0
  5. package/dart/lib/src/console_http_io.dart +22 -15
  6. package/dart/lib/src/dev_cloud.dart +62 -0
  7. package/dart/lib/src/operation_receipts.dart +74 -7
  8. package/dart/lib/src/reception/dart_reception.dart +26 -6
  9. package/dart/lib/src/runner/node-entry.mjs +7129 -4424
  10. package/dart/lib/src/runtime_v2_transport.dart +3 -0
  11. package/dart/pubspec.lock +1 -1
  12. package/dart/pubspec.yaml +2 -2
  13. package/dart/test/console_enrolment_test.dart +47 -0
  14. package/dart/test/model_adoption_test.dart +49 -0
  15. package/dart/test/runtime_projections_test.dart +41 -0
  16. package/dart_types/CHANGELOG.md +24 -0
  17. package/dart_types/lib/src/approved_model.dart +78 -1
  18. package/dart_types/lib/src/proto/nomos/kernel/v1/kernel.pb.dart +528 -2
  19. package/dart_types/lib/src/proto/nomos/kernel/v1/kernel.pbenum.dart +24 -0
  20. package/dart_types/lib/src/proto/nomos/runtime/v2/correspondence_desk.pb.dart +1897 -112
  21. package/dart_types/lib/src/proto/nomos/runtime/v2/model_adoption_desk.pb.dart +98 -0
  22. package/dart_types/lib/src/proto/nomos/runtime/v2/records_desk.pb.dart +16 -0
  23. package/dart_types/lib/src/proto/nomos/runtime/v2/runtime.pb.dart +43 -2
  24. package/dart_types/pubspec.yaml +1 -1
  25. package/package.json +4 -2
  26. package/src/aggregate.ts +93 -0
  27. package/src/anonymous_value_interning.ts +205 -0
  28. package/src/baseline.ts +27 -0
  29. package/src/baseline_export.ts +432 -0
  30. package/src/baseline_import.ts +312 -0
  31. package/src/baseline_usda.ts +186 -0
  32. package/src/birth_key_rule.ts +472 -0
  33. package/src/births.ts +207 -24
  34. package/src/build_provenance.ts +10 -0
  35. package/src/business_birth.ts +50 -4
  36. package/src/check_package_main.ts +50 -6
  37. package/src/codegen_call_proto.ts +5 -18
  38. package/src/codegen_dart.ts +95 -3
  39. package/src/codegen_dart_client.ts +52 -6
  40. package/src/codegen_dart_facade.ts +57 -35
  41. package/src/codegen_dart_framework_calls.ts +20 -1
  42. package/src/codegen_proof.ts +5 -2
  43. package/src/codegen_result_proto.ts +8 -6
  44. package/src/codegen_result_usda.ts +4 -0
  45. package/src/codegen_ts.ts +109 -10
  46. package/src/compatibility_graph.ts +41 -4
  47. package/src/compatibility_usda.ts +11 -1
  48. package/src/compile_package_main.ts +214 -51
  49. package/src/composed_wire_identity.ts +24 -0
  50. package/src/directive.ts +6 -0
  51. package/src/domain_requirements.ts +75 -0
  52. package/src/engine_javascript.ts +12 -6
  53. package/src/fields.ts +109 -0
  54. package/src/identity_usda.ts +77 -51
  55. package/src/index.ts +25 -1
  56. package/src/intent.ts +5 -0
  57. package/src/law_graph.ts +142 -1
  58. package/src/law_graph_usda.ts +25 -141
  59. package/src/law_layer_prims.ts +199 -0
  60. package/src/law_unit_selection.ts +45 -0
  61. package/src/law_version.ts +107 -0
  62. package/src/package_config.ts +44 -0
  63. package/src/package_dependencies.ts +8 -0
  64. package/src/value_object.ts +6 -3
  65. package/src/wire.ts +2 -0
  66. package/src/wire_paths.ts +17 -0
  67. package/src/workspace_routing.ts +1 -1
@@ -0,0 +1,107 @@
1
+ // THE CLAIMED VERSION OF A LAW (CAP-811).
2
+ //
3
+ // A law's identity is its package name (unique per provider, enforced by nomos.cafe). A version's identity is its
4
+ // content hash (the unit set identity). The claimed version orders the versions of one identity: an author declares
5
+ // it in `nomos.project.ts` (`version: "1.4.0"`), the compiler writes it into the package contract
6
+ // (`/Nomos/Package` `nomos:version` in `package.usda`), and so it travels inside the composition unit and is covered
7
+ // by that unit's hash, the unit set identity and the closure identity. Nobody can restate a version without minting
8
+ // a different law.
9
+ //
10
+ // The claim is a claim, not an authority: the provider's release lane (qualify -> publish -> rollout) refuses to
11
+ // publish a claim that does not move its series forward, and a kernel WARNS when an install serves an equal or lower
12
+ // claim for an identity it already serves. Absent claim = no ordering = no warning; a package that declares no
13
+ // version is byte-identical to one compiled before this key.
14
+ //
15
+ // Grammar: semver 2.0 MAJOR.MINOR.PATCH with an optional pre-release, no build metadata (build metadata does not
16
+ // order versions, so it could only make two different laws claim the same place). Dependency-free so the compiler,
17
+ // CLI, console and Peer Office share one comparison; the kernel's twin is `law_version` (kernel/src/law_version.rs).
18
+
19
+ /** A validated claim, as authored: typed, never a bare string. Only `lawVersionClaim` and the readers here mint one. */
20
+ export type LawVersionClaim = string & { readonly __nomosLawVersionClaim: unique symbol };
21
+
22
+ export interface LawVersion {
23
+ readonly major: number;
24
+ readonly minor: number;
25
+ readonly patch: number;
26
+ /** Dot-separated pre-release identifiers, empty for a release. */
27
+ readonly prerelease: readonly string[];
28
+ }
29
+
30
+ const NUMERIC = "0|[1-9]\\d*";
31
+ const IDENT = "(?:0|[1-9]\\d*|\\d*[A-Za-z-][0-9A-Za-z-]*)";
32
+ const LAW_VERSION = new RegExp(`^(${NUMERIC})\\.(${NUMERIC})\\.(${NUMERIC})(?:-(${IDENT}(?:\\.${IDENT})*))?$`);
33
+
34
+ /** Parse a claimed version, or explain why it is not one. */
35
+ export function parseLawVersion(text: string): LawVersion {
36
+ if (typeof text !== "string") throw new Error(`a law version must be a string; got ${JSON.stringify(text)}`);
37
+ if (text.includes("+")) {
38
+ throw new Error(`law version '${text}' carries build metadata; a claim must order law, so drop the '+…' suffix`);
39
+ }
40
+ const match = LAW_VERSION.exec(text);
41
+ if (match === null) {
42
+ throw new Error(`law version '${text}' is not semver MAJOR.MINOR.PATCH[-prerelease] (e.g. "1.4.0", "2.0.0-rc.1")`);
43
+ }
44
+ const part = (value: string): number => {
45
+ const number = Number(value);
46
+ if (!Number.isSafeInteger(number)) throw new Error(`law version '${text}' has a component too large to order`);
47
+ return number;
48
+ };
49
+ return {
50
+ major: part(match[1]!),
51
+ minor: part(match[2]!),
52
+ patch: part(match[3]!),
53
+ prerelease: match[4] === undefined ? [] : match[4].split("."),
54
+ };
55
+ }
56
+
57
+ /** Validate authored text as a claim, or throw why it is not one. */
58
+ export function lawVersionClaim(text: string): LawVersionClaim {
59
+ parseLawVersion(text);
60
+ return text as LawVersionClaim;
61
+ }
62
+
63
+ export function isLawVersion(text: unknown): text is LawVersionClaim {
64
+ if (typeof text !== "string") return false;
65
+ try {
66
+ parseLawVersion(text);
67
+ return true;
68
+ } catch {
69
+ return false;
70
+ }
71
+ }
72
+
73
+ const compareIdentifier = (left: string, right: string): number => {
74
+ const leftNumeric = /^\d+$/.test(left);
75
+ const rightNumeric = /^\d+$/.test(right);
76
+ if (leftNumeric && rightNumeric) return Math.sign(Number(left) - Number(right));
77
+ if (leftNumeric) return -1;
78
+ if (rightNumeric) return 1;
79
+ return left < right ? -1 : left > right ? 1 : 0;
80
+ };
81
+
82
+ /** Semver precedence: negative when `left` orders before `right`, zero when they claim the same place. */
83
+ export function compareLawVersions(left: LawVersionClaim, right: LawVersionClaim): number {
84
+ const a = parseLawVersion(left);
85
+ const b = parseLawVersion(right);
86
+ for (const key of ["major", "minor", "patch"] as const) {
87
+ if (a[key] !== b[key]) return Math.sign(a[key] - b[key]);
88
+ }
89
+ if (a.prerelease.length === 0 || b.prerelease.length === 0) {
90
+ return a.prerelease.length === b.prerelease.length ? 0 : a.prerelease.length === 0 ? 1 : -1;
91
+ }
92
+ for (let index = 0; index < Math.min(a.prerelease.length, b.prerelease.length); index += 1) {
93
+ const order = compareIdentifier(a.prerelease[index]!, b.prerelease[index]!);
94
+ if (order !== 0) return order;
95
+ }
96
+ return Math.sign(a.prerelease.length - b.prerelease.length);
97
+ }
98
+
99
+ /**
100
+ * Read the claimed version from a compiled package contract (`package.usda`, the composition unit's asset), or
101
+ * `undefined` when the law claims none. Throws when the contract carries a claim that is not a law version.
102
+ */
103
+ export function claimedVersionOfPackageContract(packageUsda: string): LawVersionClaim | undefined {
104
+ const match = /^\s*custom uniform string nomos:version = ("(?:[^"\\]|\\.)*")\s*$/mu.exec(packageUsda);
105
+ if (match === null) return undefined;
106
+ return lawVersionClaim(JSON.parse(match[1]!) as string);
107
+ }
@@ -1,5 +1,6 @@
1
1
  // NOMOS — one package contract for authoring, checking, compilation and editor diagnostics.
2
2
 
3
+ import { parseLawVersion } from "./law_version.js";
3
4
  import {
4
5
  normalizeRuntimePackageDependencies,
5
6
  type RuntimePackageDependency,
@@ -72,6 +73,15 @@ export interface NormalizedNomosPackageConfig extends Omit<NomosPackageConfig, "
72
73
  */
73
74
  export interface NomosPackageConfig {
74
75
  readonly name: string;
76
+ /**
77
+ * THE CLAIMED VERSION of this law (CAP-811): semver `MAJOR.MINOR.PATCH[-prerelease]`, e.g. `"1.4.0"`. The
78
+ * package name is the law's identity, the content hash is the version's identity, and this claim orders the
79
+ * versions of one identity. It is compiled into the package contract, so it is covered by the law's hash. The
80
+ * release lane refuses to publish a claim that does not move its series forward; a kernel warns when an install
81
+ * serves an equal or lower claim. Era rule: a package that declares none is byte-identical to one compiled
82
+ * before this key.
83
+ */
84
+ readonly version?: string;
75
85
  readonly domains: readonly NomosPackageDomainConfig[];
76
86
  /** Application-root policy compiled into the private receiving-group law.
77
87
  * Required for a published application: Nomos never invents a child-workspace allowance. */
@@ -91,6 +101,17 @@ export interface NomosPackageConfig {
91
101
  };
92
102
  /** Separately installed law required at runtime; USDA composition arcs do not belong here. */
93
103
  readonly dependencies?: readonly RuntimePackageDependency[];
104
+ /**
105
+ * THE RELEASED BASELINE this package's compiles extend (architecture/domain_release_lifecycle.md,
106
+ * step 1): a `nomos.baseline.usda` exported from released custody by `githolon baseline export`,
107
+ * pinned by content address. A publishable compile (`githolon compile --publishable`) refuses
108
+ * without one; every compile that names one verifies the ledger against it and imports the
109
+ * released identities and wire allocations it lacks. `artifact` is relative to this file.
110
+ */
111
+ readonly baseline?: {
112
+ readonly artifact: string;
113
+ readonly sha256: string;
114
+ };
94
115
  }
95
116
 
96
117
  type PackageDomainKey<Config extends NomosPackageConfig> =
@@ -143,6 +164,13 @@ export function validateNomosPackageConfig(value: unknown): {
143
164
  if (!Array.isArray(config.domains) || config.domains.length === 0) {
144
165
  throw new Error("config needs domains: [{ key, features }, ...]");
145
166
  }
167
+ if (config.version !== undefined) {
168
+ try {
169
+ parseLawVersion(config.version);
170
+ } catch (error) {
171
+ throw new Error(`package '${config.name}' version: ${(error as Error).message}`);
172
+ }
173
+ }
146
174
  const domainKeys = new Set<string>();
147
175
  const normalizedDomains: NormalizedNomosPackageDomainConfig[] = [];
148
176
  for (const candidate of config.domains) {
@@ -219,6 +247,22 @@ export function validateNomosPackageConfig(value: unknown): {
219
247
  if (config.dependencies !== undefined && !Array.isArray(config.dependencies)) {
220
248
  throw new Error("package dependencies must be an array");
221
249
  }
250
+ if (config.baseline !== undefined) {
251
+ const baseline = config.baseline as Partial<NonNullable<NomosPackageConfig["baseline"]>> | null;
252
+ if (
253
+ baseline === null
254
+ || typeof baseline !== "object"
255
+ || typeof baseline.artifact !== "string"
256
+ || baseline.artifact.length === 0
257
+ || typeof baseline.sha256 !== "string"
258
+ || !/^[0-9a-f]{64}$/u.test(baseline.sha256)
259
+ ) {
260
+ throw new Error(
261
+ "baseline must be { artifact: '<path to nomos.baseline.usda>', sha256: '<its 64-hex content address>' }; " +
262
+ "export it with githolon baseline export and pin the sha256 it prints",
263
+ );
264
+ }
265
+ }
222
266
  if (config.application !== undefined) {
223
267
  const max = config.application.maxChildWorkspacesPerUser;
224
268
  if (!Number.isInteger(max) || max < 0) {
@@ -1,5 +1,6 @@
1
1
  // NOMOS — runtime package requirements are canonical typed USDA law, not ambient host setup.
2
2
 
3
+ import { parseLawVersion, type LawVersionClaim } from "./law_version.js";
3
4
  import { usdaString, usdaStringArray } from "./usda_text.js";
4
5
 
5
6
  /**
@@ -59,9 +60,13 @@ export function normalizeRuntimePackageDependencies(
59
60
  /** Emit the package contract into the same composed stage the kernel executes. */
60
61
  export function packageContractUsda(input: {
61
62
  readonly packageName: string;
63
+ /** The law's claimed version (CAP-811, law_version.ts). Absent: no claim, and the contract is byte-identical
64
+ * to one compiled before claims existed. Present: carried in the composition unit, so covered by its hash. */
65
+ readonly claimedVersion?: LawVersionClaim;
62
66
  readonly exportedDomains: readonly string[];
63
67
  readonly runtimeDependencies: readonly RuntimePackageDependency[];
64
68
  }): string {
69
+ if (input.claimedVersion !== undefined) parseLawVersion(input.claimedVersion);
65
70
  const dependencies = [...input.runtimeDependencies];
66
71
  const dependencyPrimName = (index: number): string => `d_${String(index).padStart(6, "0")}`;
67
72
  const targets = dependencies.map(
@@ -81,6 +86,9 @@ export function packageContractUsda(input: {
81
86
  ' def NomosPackage "Package"',
82
87
  " {",
83
88
  ` custom uniform string nomos:name = ${usdaString(input.packageName)}`,
89
+ ...(input.claimedVersion === undefined
90
+ ? []
91
+ : [` custom uniform string nomos:version = ${usdaString(input.claimedVersion)}`]),
84
92
  ' custom uniform token nomos:operationContract = "nomos.protobuf.v1"',
85
93
  ` custom uniform string[] nomos:domains = ${usdaStringArray([...input.exportedDomains].sort())}`,
86
94
  ...(targets.length > 0
@@ -66,6 +66,7 @@ import {
66
66
  type ValueObjectDescriptor,
67
67
  type ValueObjectFieldDescriptor,
68
68
  type ValueObjectFieldMeta,
69
+ type TypedId,
69
70
  } from "./fields.js";
70
71
  // LOCAL zod introspection (the same `_def ?? def` convention as codegen_ts.ts) —
71
72
  // deliberately NOT imported from codegen_ts.js: this module rides the RUNTIME barrel
@@ -434,14 +435,16 @@ export const NOMOS_BRANDED_ID_BRAND: unique symbol = Symbol.for("nomos.brandedId
434
435
 
435
436
  const BRAND_NAME_RE = /^[A-Z][A-Za-z0-9_]*$/;
436
437
 
437
- /** Declare a NOMINAL string id: `siteId: brandedId("SiteId")`. */
438
- export function brandedId(name: string): z.ZodType<string> {
438
+ /** Declare a NOMINAL string id: `siteId: brandedId("SiteId")`. The parsed value is typed
439
+ * {@link TypedId}`<"SiteId">` in law code too (the same type a `t.brandedId("SiteId")` field holds), so a
440
+ * plain string is a compile error on both sides of the wire. */
441
+ export function brandedId<const Name extends string>(name: Name): z.ZodType<TypedId<Name>> {
439
442
  if (!BRAND_NAME_RE.test(name)) {
440
443
  throw new Error(`brandedId: '${name}' must be a capitalized identifier — it becomes the generated branded type's name.`);
441
444
  }
442
445
  const schema = z.string();
443
446
  Object.defineProperty(schema, NOMOS_BRANDED_ID_BRAND, { value: name, enumerable: false });
444
- return schema;
447
+ return schema as unknown as z.ZodType<TypedId<Name>>;
445
448
  }
446
449
 
447
450
  /** Resolve the `brandedId(...)` brand name of a schema (through optional/default/nullable). */
package/src/wire.ts CHANGED
@@ -211,6 +211,8 @@ export interface WireIntent {
211
211
  workspace: string;
212
212
  genesisChain: unknown;
213
213
  parentWorkspaceRoles?: readonly import("./births.js").WorkspaceRole[];
214
+ /** The typed key the workspace name hashes (business births under typed-key law → `nomos:birthKey`). */
215
+ birthKey?: string;
214
216
  }[];
215
217
  /** Exact target calls authored by source law. The OpenUSD bytes come from a compiler-generated
216
218
  * encoder for the target Directive object; no public operation string or generic payload crosses. */
@@ -0,0 +1,17 @@
1
+ // NOMOS — The one spelling of a nested operation field's ledger label.
2
+ //
3
+ // A top-level payload field is ledgered under its own name. A field INSIDE a structural value
4
+ // (a record member, a map value, a list element, a union variant) is ledgered under a path built
5
+ // from these segments, so its transport allocation survives a change elsewhere in the structure
6
+ // (the 1 October 2026 `canvasRequirements` incident: nested `isRequired` keys moved because their
7
+ // structural sids moved). law_graph.ts allocates by these paths; baseline_export.ts recovers the
8
+ // same paths from released law so the two agree without a sidecar.
9
+
10
+ /** A record member beneath `parent`. */
11
+ export const nestedMemberPath = (parent: string, name: string): string => `${parent}.${name}`;
12
+ /** The element of a list beneath `parent`. */
13
+ export const listElementPath = (parent: string): string => `${parent}[]`;
14
+ /** The value of a map beneath `parent`. */
15
+ export const mapValuePath = (parent: string): string => `${parent}{}`;
16
+ /** One variant of a union beneath `parent`, by its discriminator label or ordinal. */
17
+ export const unionVariantPath = (parent: string, variant: string): string => `${parent}|${variant}|`;
@@ -164,7 +164,7 @@ export function routeTagHexOfMintedId(id: string): string | undefined {
164
164
  // ── the plan trace (the mint-front-door family, aimed at HOMES) ──────────────────────
165
165
 
166
166
  /** Build a schema-valid probe payload: every top-level string field gets its sentinel. */
167
- function buildProbePayload(
167
+ export function buildProbePayload(
168
168
  schema: z.ZodTypeAny,
169
169
  sentinelOf: Map<string, string>,
170
170
  jsonSafe = false,