@githolon/dsl 0.119.13 → 0.119.28
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/assets/operation-contract.wasm +0 -0
- package/compile_package.mjs +80 -74
- package/compile_proof.d.mts +1 -0
- package/compile_proof.mjs +29 -3
- package/dart/CHANGELOG.md +85 -0
- package/dart/lib/src/runner/node-entry.mjs +531 -197
- package/dart/lib/src/testing/test_peer.dart +36 -0
- package/dart/pubspec.lock +1 -1
- package/dart/pubspec.yaml +2 -2
- package/dart_types/CHANGELOG.md +4 -0
- package/dart_types/lib/src/proto/nomos/kernel/v1/kernel.pb.dart +2673 -1194
- package/dart_types/pubspec.yaml +1 -1
- package/package.json +7 -7
- package/src/anonymous_value_interning.ts +14 -7
- package/src/baseline_export.ts +64 -6
- package/src/baseline_import.ts +17 -0
- package/src/baseline_usda.ts +2 -2
- package/src/codegen_result_usda.ts +3 -1
- package/src/compile_package_main.ts +10 -7
- package/src/compiler_toolchain.ts +35 -0
- package/src/dart_analysis_roots.ts +71 -0
- package/src/intent.ts +3 -1
- package/src/law_graph.ts +11 -74
- package/src/law_graph_usda.ts +4 -4
- package/src/law_identity.ts +5 -3
- package/src/openusd_compiled_layer.ts +7 -2
- package/src/value_wire_continuity.ts +150 -0
package/src/law_identity.ts
CHANGED
|
@@ -19,6 +19,7 @@ export const LAW_ENTITY_KINDS = [
|
|
|
19
19
|
"workspace-type",
|
|
20
20
|
"contract",
|
|
21
21
|
"operation-field",
|
|
22
|
+
"value-field",
|
|
22
23
|
"type",
|
|
23
24
|
"object-type",
|
|
24
25
|
] as const;
|
|
@@ -48,7 +49,7 @@ export interface LawIdentityEntity {
|
|
|
48
49
|
readonly priorLabels?: readonly string[];
|
|
49
50
|
readonly generation: number;
|
|
50
51
|
readonly status: LawIdentityStatus;
|
|
51
|
-
/** Present
|
|
52
|
+
/** Present on operation-field and value-field wire custody rows. The row's label + lineage carry meaning. */
|
|
52
53
|
readonly operationFieldWire?: LawOperationFieldWire;
|
|
53
54
|
}
|
|
54
55
|
|
|
@@ -114,6 +115,7 @@ const KIND_PREFIX: Readonly<Record<LawEntityKind, string>> = {
|
|
|
114
115
|
"workspace-type": "x",
|
|
115
116
|
contract: "c",
|
|
116
117
|
"operation-field": "u",
|
|
118
|
+
"value-field": "v",
|
|
117
119
|
type: "t",
|
|
118
120
|
"object-type": "o",
|
|
119
121
|
};
|
|
@@ -348,8 +350,8 @@ export function validateLawIdentityRegistry(registry: LawIdentityRegistry): void
|
|
|
348
350
|
throw new Error(`NMS-ID-001 ${key} has invalid status`);
|
|
349
351
|
}
|
|
350
352
|
if (entity.operationFieldWire !== undefined) {
|
|
351
|
-
if (entity.kind !== "operation-field") {
|
|
352
|
-
throw new Error(`NMS-ID-001 ${key} carries
|
|
353
|
+
if (entity.kind !== "operation-field" && entity.kind !== "value-field") {
|
|
354
|
+
throw new Error(`NMS-ID-001 ${key} carries wire custody but is not a wire field`);
|
|
353
355
|
}
|
|
354
356
|
const keys = [
|
|
355
357
|
entity.operationFieldWire.protobuf.canonical,
|
|
@@ -58,10 +58,15 @@ export async function flattenOpenUsdToUsda(
|
|
|
58
58
|
}
|
|
59
59
|
args.push(request.sourcePath);
|
|
60
60
|
try {
|
|
61
|
-
const { stdout: usda } = await execFileAsync(request.usdcat, args, {
|
|
61
|
+
const { stdout: usda, stderr: diagnostics } = await execFileAsync(request.usdcat, args, {
|
|
62
62
|
encoding: "utf8",
|
|
63
63
|
maxBuffer: 256 * 1024 * 1024,
|
|
64
64
|
});
|
|
65
|
+
// OpenUSD can exit successfully after skipping an invalid sublayer. Its
|
|
66
|
+
// partial stage is not the complete authenticated law we asked to compile.
|
|
67
|
+
if (diagnostics.trim().length > 0) {
|
|
68
|
+
throw new Error(diagnostics.trim());
|
|
69
|
+
}
|
|
65
70
|
if (!usda.startsWith("#usda 1.0")) {
|
|
66
71
|
throw new Error(
|
|
67
72
|
`stock OpenUSD returned a non-USDA ${request.description}`
|
|
@@ -78,7 +83,7 @@ export async function flattenOpenUsdToUsda(
|
|
|
78
83
|
"$1$2"
|
|
79
84
|
);
|
|
80
85
|
} catch (error) {
|
|
81
|
-
const stderr = stderrOf(error);
|
|
86
|
+
const stderr = stderrOf(error) || (error instanceof Error ? error.message : String(error));
|
|
82
87
|
const maskDetail =
|
|
83
88
|
populationMask === undefined
|
|
84
89
|
? ""
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
// CAP-983: public wire allocations outlive the compiler's structural representatives.
|
|
2
|
+
// See architecture/value_wire_identity.md. This is compiler custody, not a second
|
|
3
|
+
// compatibility judge. The kernel still judges the emitted contract.
|
|
4
|
+
import type {
|
|
5
|
+
LawAnonymousValueFieldNode, LawAnonymousValueTypeNode, LawAnonymousValueVariantNode,
|
|
6
|
+
LawFieldNode, LawTypeNode, LawReadContractNode, LawValueTypeRef,
|
|
7
|
+
} from "./law_graph.js";
|
|
8
|
+
import type { LawIdentityReconciler, LawIdentityRegistry, LawOperationFieldWire } from "./law_identity.js";
|
|
9
|
+
import { anonymousTypeOwnsPrim, internAnonymousValues } from "./anonymous_value_interning.js";
|
|
10
|
+
import { listElementPath, mapValuePath, nestedMemberPath, unionVariantPath } from "./wire_paths.js";
|
|
11
|
+
|
|
12
|
+
type ValueNode = LawAnonymousValueFieldNode | LawAnonymousValueTypeNode | LawAnonymousValueVariantNode;
|
|
13
|
+
type Wire = LawOperationFieldWire["protobuf"];
|
|
14
|
+
interface Scope { kind: "operation-field" | "value-field"; owner: string; paths: Map<string, string> }
|
|
15
|
+
|
|
16
|
+
export function retainValueWireAllocations(input: {
|
|
17
|
+
nodes: readonly ValueNode[];
|
|
18
|
+
fields: readonly LawFieldNode[];
|
|
19
|
+
types: readonly LawTypeNode[];
|
|
20
|
+
reads: readonly LawReadContractNode[];
|
|
21
|
+
operations: ReadonlyMap<string, Map<string, string>>;
|
|
22
|
+
identities: LawIdentityReconciler;
|
|
23
|
+
registry: LawIdentityRegistry;
|
|
24
|
+
}): { nodes: ValueNode[]; registry: LawIdentityRegistry } {
|
|
25
|
+
const byId = new Map<string, ValueNode>(input.nodes.map(n => [n.entity.id, n]));
|
|
26
|
+
const scopes: Scope[] = [...input.operations].map(([owner, paths]) => ({ kind: "operation-field", owner, paths }));
|
|
27
|
+
const walk = (ref: LawValueTypeRef, path: string, paths: Map<string, string>, visiting: ReadonlySet<string>): void => {
|
|
28
|
+
if (visiting.has(ref.id)) return;
|
|
29
|
+
const node = byId.get(ref.id);
|
|
30
|
+
// A named type owns its own continuity; do not duplicate it under every caller.
|
|
31
|
+
if (node?.structuralKind !== "value-type") return;
|
|
32
|
+
const next = new Set(visiting).add(ref.id);
|
|
33
|
+
const e = node.expression;
|
|
34
|
+
switch (e.kind) {
|
|
35
|
+
case "record":
|
|
36
|
+
for (const ref of e.fields) {
|
|
37
|
+
const field = byId.get(ref.id);
|
|
38
|
+
if (field?.structuralKind !== "value-field") continue;
|
|
39
|
+
const member = nestedMemberPath(path, field.name);
|
|
40
|
+
paths.set(member, field.entity.id);
|
|
41
|
+
walk(field.value, member, paths, next);
|
|
42
|
+
}
|
|
43
|
+
break;
|
|
44
|
+
case "list": walk(e.element, listElementPath(path), paths, next); break;
|
|
45
|
+
case "map": walk(e.value, mapValuePath(path), paths, next); break;
|
|
46
|
+
case "sum":
|
|
47
|
+
for (const ref of e.variants) {
|
|
48
|
+
const variant = byId.get(ref.id);
|
|
49
|
+
if (variant?.structuralKind === "value-variant") {
|
|
50
|
+
const arm = unionVariantPath(path, variant.label ?? variant.entity.label);
|
|
51
|
+
paths.set(arm, variant.entity.id);
|
|
52
|
+
walk(variant.value, arm, paths, next);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
break;
|
|
56
|
+
case "nullable": case "default": case "recursive": walk(e.value, path, paths, next); break;
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
for (const field of input.fields) {
|
|
60
|
+
if (input.registry.entities[field.entity.id]?.kind !== "field") continue;
|
|
61
|
+
const paths = new Map<string, string>();
|
|
62
|
+
walk(field.value, "$", paths, new Set());
|
|
63
|
+
scopes.push({ kind: "value-field", owner: field.entity.id, paths });
|
|
64
|
+
}
|
|
65
|
+
for (const type of input.types) {
|
|
66
|
+
const paths = new Map<string, string>();
|
|
67
|
+
for (const ref of type.variants) {
|
|
68
|
+
const variant = byId.get(ref.id);
|
|
69
|
+
if (variant?.structuralKind === "value-variant") {
|
|
70
|
+
const arm = unionVariantPath("$", variant.label ?? variant.entity.label);
|
|
71
|
+
paths.set(arm, variant.entity.id);
|
|
72
|
+
walk(variant.value, arm, paths, new Set());
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
scopes.push({ kind: "value-field", owner: type.entity.id, paths });
|
|
76
|
+
}
|
|
77
|
+
for (const read of input.reads) {
|
|
78
|
+
const paths = new Map<string, string>();
|
|
79
|
+
if (read.returns.kind === "scalar") walk(read.returns.value, "$returns", paths, new Set());
|
|
80
|
+
for (const parameter of read.parameters) if (parameter.value !== undefined) {
|
|
81
|
+
walk(parameter.value, nestedMemberPath("$parameters", parameter.name), paths, new Set());
|
|
82
|
+
}
|
|
83
|
+
scopes.push({ kind: "value-field", owner: read.owner.id, paths });
|
|
84
|
+
}
|
|
85
|
+
const fields = input.nodes.filter((n): n is LawAnonymousValueFieldNode => n.structuralKind === "value-field");
|
|
86
|
+
const intern = internAnonymousValues({
|
|
87
|
+
types: input.nodes.filter((n): n is LawAnonymousValueTypeNode => n.structuralKind === "value-type"), fields,
|
|
88
|
+
variants: input.nodes.filter((n): n is LawAnonymousValueVariantNode => n.structuralKind === "value-variant"),
|
|
89
|
+
ownsPrim: anonymousTypeOwnsPrim, ignoreWireAllocations: true,
|
|
90
|
+
});
|
|
91
|
+
const members = input.nodes.filter((n): n is LawAnonymousValueFieldNode | LawAnonymousValueVariantNode => n.structuralKind !== "value-type");
|
|
92
|
+
const canonical = (id: string): string => intern.canonicalFieldIdById.get(id) ?? intern.canonicalVariantIdById.get(id) ?? id;
|
|
93
|
+
const held = new Map<string, Wire>();
|
|
94
|
+
const classes = new Map<string, Map<string, Wire>>();
|
|
95
|
+
const remember = (id: string, wire: Wire): void => {
|
|
96
|
+
if (byId.get(id)?.structuralKind === "value-variant" && wire.aliases?.length) {
|
|
97
|
+
throw new Error(`NMS-WIRE-002 ${id}: this runtime has no union-arm alias protocol; retain the published arm key`);
|
|
98
|
+
}
|
|
99
|
+
const prior = held.get(id);
|
|
100
|
+
if (prior && prior.canonical !== wire.canonical) throw new Error(`NMS-WIRE-001 ${id} has conflicting retained wire allocations; one source member cannot serve two contracts`);
|
|
101
|
+
const merged = { canonical: wire.canonical, aliases: [...new Set([...(prior?.aliases ?? []), ...(wire.aliases ?? [])])].sort() };
|
|
102
|
+
held.set(id, merged);
|
|
103
|
+
const key = canonical(id);
|
|
104
|
+
const group = classes.get(key) ?? new Map<string, Wire>();
|
|
105
|
+
const existing = group.get(merged.canonical);
|
|
106
|
+
group.set(merged.canonical, { canonical: merged.canonical, aliases: [...new Set([...(existing?.aliases ?? []), ...merged.aliases])].sort() });
|
|
107
|
+
classes.set(key, group);
|
|
108
|
+
};
|
|
109
|
+
for (const field of members) if (field.entity.wireKey) remember(field.entity.id, { canonical: field.entity.wireKey, ...(field.entity.wireAliases === undefined ? {} : { aliases: field.entity.wireAliases }) });
|
|
110
|
+
const coordinates = new Map(Object.values(input.registry.entities).filter(e => e.status === "active")
|
|
111
|
+
.map(e => [`${e.kind}\0${e.parent}\0${e.label}`, e]));
|
|
112
|
+
// All retained allocations are collected before allocating any new use: traversal order cannot win.
|
|
113
|
+
for (const scope of scopes) for (const [path, id] of scope.paths) {
|
|
114
|
+
const wire = coordinates.get(`${scope.kind}\0${scope.owner}\0${path}`)?.operationFieldWire?.protobuf;
|
|
115
|
+
if (wire) remember(id, wire);
|
|
116
|
+
}
|
|
117
|
+
const preferred = (id: string): Wire => {
|
|
118
|
+
const own = held.get(id);
|
|
119
|
+
if (own) return own;
|
|
120
|
+
const group = classes.get(canonical(id));
|
|
121
|
+
if (group?.size === 1) return [...group.values()][0]!;
|
|
122
|
+
const node = byId.get(canonical(id))!;
|
|
123
|
+
// No unique inherited allocation: a new use gets the historical first-allocation rule.
|
|
124
|
+
return { canonical: node.entity.sid };
|
|
125
|
+
};
|
|
126
|
+
// Freeze preferences before reconciliation so new uses cannot influence one another.
|
|
127
|
+
const preferences = new Map(members.map(field => [field.entity.id as string, preferred(field.entity.id)]));
|
|
128
|
+
const existingScopes = new Set(Object.values(input.registry.entities)
|
|
129
|
+
.filter(e => e.kind === "value-field" && e.status === "active").map(e => e.parent));
|
|
130
|
+
let registry = input.registry;
|
|
131
|
+
for (const scope of scopes) {
|
|
132
|
+
// Scalar/named references have no anonymous members. Avoid a full ledger scan for each;
|
|
133
|
+
// previously populated scopes still reconcile empty so removals get tombstones.
|
|
134
|
+
if (scope.paths.size === 0 && !existingScopes.has(scope.owner)) continue;
|
|
135
|
+
const result = input.identities.reconcile({
|
|
136
|
+
kind: scope.kind, parent: scope.owner, labels: [...scope.paths.keys()],
|
|
137
|
+
preferredOperationFieldWire: Object.fromEntries([...scope.paths].map(([path, id]) => [path, { protobuf: preferences.get(id)! }])),
|
|
138
|
+
// Operation retirement already uses accepts/publicAccepts together. A value owner is complete here.
|
|
139
|
+
retireAbsent: scope.kind === "value-field",
|
|
140
|
+
});
|
|
141
|
+
registry = result.registry;
|
|
142
|
+
for (const [path, id] of scope.paths) remember(id, registry.entities[result.resolved[path]!]!.operationFieldWire!.protobuf);
|
|
143
|
+
}
|
|
144
|
+
return { registry, nodes: input.nodes.map(node => {
|
|
145
|
+
if (node.structuralKind === "value-type") return node;
|
|
146
|
+
const wire = held.get(node.entity.id) ?? preferences.get(node.entity.id)!;
|
|
147
|
+
if (node.structuralKind === "value-variant") return { ...node, entity: { ...node.entity, wireKey: wire.canonical } };
|
|
148
|
+
return { ...node, entity: { ...node.entity, wireKey: wire.canonical, ...(wire.aliases?.length ? { wireAliases: wire.aliases } : {}) } };
|
|
149
|
+
}) };
|
|
150
|
+
}
|