halfcode-compiler.xnl 0.2.8 → 0.3.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 (59) hide show
  1. package/README.md +5 -3
  2. package/dist/application-assembly.d.ts +1 -1
  3. package/dist/application-assembly.js +1 -1
  4. package/dist/authoring-runtime.d.ts +167 -1
  5. package/dist/authoring-runtime.js +2 -2
  6. package/dist/effective-content-identities-CV6XFBZy.js +118 -0
  7. package/dist/effective-content-identities-drMRhYE2.d.ts +14 -0
  8. package/dist/{index-B515mMkO.d.ts → index-CR7wJSSX.d.ts} +10 -6
  9. package/dist/{index-Cqh9pEBa.d.ts → index-DEikbOFh.d.ts} +2 -1
  10. package/dist/{index-CF4nEkOi.d.ts → index-DI3WtuXq.d.ts} +1 -1
  11. package/dist/index-DboIOEr8.d.ts +474 -0
  12. package/dist/index.d.ts +7 -5
  13. package/dist/index.js +7 -5
  14. package/dist/kind-definition.d.ts +118 -10
  15. package/dist/kind-definition.js +826 -15
  16. package/dist/resource-core-Brj8naBr.d.ts +47 -0
  17. package/dist/resource-core.d.ts +4 -3
  18. package/dist/resource-core.js +40 -141
  19. package/dist/resource-projection.d.ts +1 -1
  20. package/dist/skill-capsule.d.ts +2 -2
  21. package/dist/skill-capsule.js +1 -1
  22. package/dist/{src-3pnDAjBD.js → src-B0Hja_dk.js} +5 -7
  23. package/dist/{src-CaQ25rMj.js → src-DLJUCH0M.js} +11 -7
  24. package/dist/src-hrUy4DJ9.js +640 -0
  25. package/dist/{src-D3qSzGFn.js → src-jggOQtq3.js} +511 -113
  26. package/dist/system-skills/resource-dsl/KindDefinitions/SkillCapsule/manifest.xnl +15 -3
  27. package/dist/system-skills/resource-dsl/KindDefinitions/WikiPage/manifest.xnl +15 -3
  28. package/dist/system-skills/resource-dsl/SkillCapsules/System/SKILL.metadata.yaml +1 -0
  29. package/dist/system-skills/resource-dsl/SkillCapsules/System/manifest.xnl +1 -1
  30. package/dist/system-skills/resource-dsl/SkillCapsules/System/resource-mappings.xnl +1 -1
  31. package/dist/system-skills/resource-dsl/WikiPages/documents/manifest.xnl +1 -1
  32. package/dist/system-skills/resource-dsl/WikiPages/files/manifest.xnl +1 -1
  33. package/dist/system-skills/resource-dsl/WikiPages/index/manifest.xnl +1 -1
  34. package/dist/system-skills/resource-dsl/WikiPages/language/manifest.xnl +1 -1
  35. package/dist/system-skills/resource-dsl/WikiPages/migration/manifest.xnl +1 -1
  36. package/dist/system-skills/resource-dsl/WikiPages/projections/manifest.xnl +1 -1
  37. package/dist/system-skills/resource-dsl/WikiPages/skill-capsules/manifest.xnl +1 -1
  38. package/dist/system-skills/resource-dsl/documents.md +33 -17
  39. package/dist/system-skills/resource-dsl/examples/function.xnl +1 -1
  40. package/dist/system-skills/resource-dsl/examples/kind-definition.xnl +15 -3
  41. package/dist/system-skills/resource-dsl/examples/resource-mappings.xnl +1 -1
  42. package/dist/system-skills/resource-dsl/examples/resource-package.xnl +1 -1
  43. package/dist/system-skills/resource-dsl/examples/skill-capsule-authoring.xnl +1 -1
  44. package/dist/system-skills/resource-dsl/examples/skill-capsule-devops.xnl +1 -1
  45. package/dist/system-skills/resource-dsl/examples/skill-capsule-kind-definition.xnl +14 -3
  46. package/dist/system-skills/resource-dsl/examples/skill-capsule-resource-dsl.xnl +1 -1
  47. package/dist/system-skills/resource-dsl/examples/skill-capsule-run.xnl +1 -1
  48. package/dist/system-skills/resource-dsl/index.md +5 -5
  49. package/dist/system-skills/resource-dsl/language.md +10 -8
  50. package/dist/system-skills/resource-dsl/manifest.xnl +1 -1
  51. package/dist/system-skills/resource-dsl/migration.md +6 -3
  52. package/dist/system-skills/resource-dsl/projections.md +7 -6
  53. package/dist/system-skills/resource-dsl/skill-capsules.md +8 -7
  54. package/dist/system-skills/sys-halfcode-resource-dsl.plan.js +84 -59
  55. package/dist/testing.js +1 -1
  56. package/package.json +6 -2
  57. package/dist/index-CDIT65pI.d.ts +0 -192
  58. package/dist/resource-core-C8IonwKw.d.ts +0 -41
  59. package/dist/src-B87eJQat.js +0 -39
@@ -0,0 +1,47 @@
1
+ import { et as ResourceMetadata, i as AuthoredResourceTree, p as ResourceDiagnostic, st as ResourcePackageReadPort, yt as ResourceDigestContribution } from "./index-DboIOEr8.js";
2
+ //#region ../resource-core/src/composition-error.d.ts
3
+ declare class ResourceCompositionError extends Error {
4
+ readonly diagnostics: readonly ResourceDiagnostic[];
5
+ constructor(diagnostics: readonly ResourceDiagnostic[]);
6
+ }
7
+ //#endregion
8
+ //#region ../resource-core/src/resource-material.d.ts
9
+ interface ReadResourceMaterialInput {
10
+ readonly tree: AuthoredResourceTree;
11
+ readonly rootDir: string;
12
+ readonly resourceId: string;
13
+ readonly uri: string;
14
+ }
15
+ interface ResourceMaterial {
16
+ readonly resourceId: string;
17
+ readonly uri: string;
18
+ readonly sourceUri: string;
19
+ readonly digest: string;
20
+ readonly contribution: ResourceDigestContribution;
21
+ bytes(): Uint8Array;
22
+ }
23
+ declare class ResourceMaterialError extends Error {
24
+ readonly diagnostics: readonly ResourceDiagnostic[];
25
+ constructor(diagnostics: readonly ResourceDiagnostic[]);
26
+ }
27
+ declare function readResourceMaterial(input: ReadResourceMaterialInput): Promise<ResourceMaterial>;
28
+ //#endregion
29
+ //#region ../resource-core/src/directory-resource-package-read-port.d.ts
30
+ declare function createDirectoryResourcePackageReadPort(rootDir: string): Promise<ResourcePackageReadPort>;
31
+ //#endregion
32
+ //#region ../resource-core/src/resource-envelope.d.ts
33
+ interface ResourceMetadataDecodeInput {
34
+ readonly fields: Readonly<Record<string, unknown>>;
35
+ readonly removedFieldContainers?: readonly Readonly<Record<string, unknown>>[];
36
+ readonly lifecycle?: unknown;
37
+ readonly location: string;
38
+ readonly source: "XNL" | "Markdown";
39
+ }
40
+ type ResourceMetadataDecodeResult = Readonly<{
41
+ metadata: ResourceMetadata;
42
+ }> | Readonly<{
43
+ diagnostic: ResourceDiagnostic;
44
+ }>;
45
+ declare function decodeResourceMetadata(input: ResourceMetadataDecodeInput): ResourceMetadataDecodeResult;
46
+ //#endregion
47
+ export { ReadResourceMaterialInput as a, readResourceMaterial as c, createDirectoryResourcePackageReadPort as i, ResourceCompositionError as l, ResourceMetadataDecodeResult as n, ResourceMaterial as o, decodeResourceMetadata as r, ResourceMaterialError as s, ResourceMetadataDecodeInput as t };
@@ -1,3 +1,4 @@
1
- import { A as buildResourceDependencySnapshot, B as ResourceTombstone, C as BuildResourceDependencySnapshotInput, D as ResourceDependencySnapshot, E as ResourceDependencyEdge, F as EffectiveResourceEntry, H as composeLayeredResourceRegistry, I as EffectiveResourceRegistry, L as ResourceLayerDescriptor, M as sha256Digest, N as ComposeLayeredResourceRegistryInput, O as ResourceDigestContribution, P as EffectiveKindDefinition, R as ResourceLayerInput, S as validateResourceTree, T as ResourceContentIdentity, U as Sha256Digest, V as ResourceTombstoneOrigin, _ as ResourceValue, a as ResourceDescriptor, b as SourceShape, c as ResourceKindContract, d as ResourceRecord, f as ResourceRegistry, g as ResourceValidationError, h as ResourceTreeBuildResult, i as RegisteredKindDefinition, j as createResourceContentIdentity, k as SnapshotResource, l as ResourceMetadata, m as ResourceTree, n as LoadedResourceTree, o as ResourceDiagnostic, p as ResourceScalar, r as LoadedResourceTreeBuildResult, s as ResourceIdentity, t as LoadResourceTreeOptions, u as ResourceNode, v as ResourceValueList, w as CreateResourceContentIdentityInput, x as loadResourceTree, y as ResourceValueMap, z as ResourceOrigin } from "./index-CDIT65pI.js";
2
- import { a as ResolveEffectiveResourceContentIdentitiesInput, c as ResourceCompositionError, i as readResourceMaterial, n as ResourceMaterial, o as ResourceLayerContentIdentityInput, r as ResourceMaterialError, s as resolveEffectiveResourceContentIdentities, t as ReadResourceMaterialInput } from "./resource-core-C8IonwKw.js";
3
- export { BuildResourceDependencySnapshotInput, ComposeLayeredResourceRegistryInput, CreateResourceContentIdentityInput, EffectiveKindDefinition, EffectiveResourceEntry, EffectiveResourceRegistry, LoadResourceTreeOptions, LoadedResourceTree, LoadedResourceTreeBuildResult, ReadResourceMaterialInput, RegisteredKindDefinition, ResolveEffectiveResourceContentIdentitiesInput, ResourceCompositionError, ResourceContentIdentity, ResourceDependencyEdge, ResourceDependencySnapshot, ResourceDescriptor, ResourceDiagnostic, ResourceDigestContribution, ResourceIdentity, ResourceKindContract, ResourceLayerContentIdentityInput, ResourceLayerDescriptor, ResourceLayerInput, ResourceMaterial, ResourceMaterialError, ResourceMetadata, ResourceNode, ResourceOrigin, ResourceRecord, ResourceRegistry, ResourceScalar, ResourceTombstone, ResourceTombstoneOrigin, ResourceTree, ResourceTreeBuildResult, ResourceValidationError, ResourceValue, ResourceValueList, ResourceValueMap, type Sha256Digest, SnapshotResource, SourceShape, buildResourceDependencySnapshot, composeLayeredResourceRegistry, createResourceContentIdentity, loadResourceTree, readResourceMaterial, resolveEffectiveResourceContentIdentities, sha256Digest, validateResourceTree };
1
+ import { $ as RESOURCE_ENVELOPE_VERSION, A as validateResourceTreeFromReadPort, At as ResourceOrigin, B as KindSpecRevision, C as ResourceValue, Ct as sha256Digest, D as loadResourceTree, Dt as EffectiveResourceRegistry, E as SourceShape, Et as EffectiveResourceEntry, F as KindContractLockReader, Ft as canonicalJson, G as ReaderProfile, H as KindWriterRegistration, I as KindReaderRegistration, It as compareCodeUnits, J as ResourceResolutionReceipt, K as ReaderTarget, L as KindSemanticContract, Lt as digestCanonical, M as JsonSchema, Mt as ResourceTombstoneOrigin, N as JsonSchemaValidator, Nt as composeLayeredResourceRegistry, O as loadResourceTreeFromReadPort, Ot as ResourceLayerDescriptor, P as KindContractLock, Pt as Sha256Digest, Q as RESOURCE_ENVELOPE_FINGERPRINT, R as KindSourceContract, S as ResourceValidationError, St as createResourceContentIdentity, T as ResourceValueMap, Tt as EffectiveKindDefinition, U as PortableSpec, V as KindSubjectOwner, W as PortableValue, X as CORE_BOOTSTRAP_WRITER_SPEC_VERSIONS, Y as SpecResolutionDefinition, Z as RESOURCE_ENVELOPE_CONTRACT, _ as ResourceRecord, _t as ResourceDependencyEdge, a as AuthoredResourceTreeBuildResult, at as ResourcePackageEntry, b as ResourceTree, bt as SnapshotResource, c as RegisteredKindDefinition, ct as ResourcePackageReadPortOptions, d as ResolvedResourceTree, dt as dirnameResourcePackageSourcePath, et as ResourceMetadata, f as ResourceDescriptor, ft as joinResourcePackageSourcePath, g as ResourceNode, gt as ResourceContentIdentity, h as ResourceKindContract, ht as CreateResourceContentIdentityInput, i as AuthoredResourceTree, it as ResourcePackageDirectoryEntry, j as CompatibilityPolicy, jt as ResourceTombstone, k as validateResourceTree, kt as ResourceLayerInput, l as ResolvedResourceRecord, lt as ResourcePackageSourcePathError, m as ResourceIdentity, mt as BuildResourceDependencySnapshotInput, n as AuthoredResourceRegistry, nt as isSpecVersion, o as KindSpecRevisionDescriptor, ot as ResourcePackageEntryKind, p as ResourceDiagnostic, pt as relativeResourcePackageSourcePath, q as ResolvedSpec, r as AuthoredResourceSpec, rt as ResourcePackageAwaitable, s as LoadResourceTreeOptions, st as ResourcePackageReadPort, t as AuthoredResourceRecord, tt as SpecVersion, u as ResolvedResourceRegistry, ut as canonicalResourcePackageSourcePath, v as ResourceRegistry, vt as ResourceDependencySnapshot, w as ResourceValueList, wt as ComposeLayeredResourceRegistryInput, x as ResourceTreeBuildResult, xt as buildResourceDependencySnapshot, y as ResourceScalar, yt as ResourceDigestContribution, z as KindSourceShape } from "./index-DboIOEr8.js";
2
+ import { a as ReadResourceMaterialInput, c as readResourceMaterial, i as createDirectoryResourcePackageReadPort, l as ResourceCompositionError, n as ResourceMetadataDecodeResult, o as ResourceMaterial, r as decodeResourceMetadata, s as ResourceMaterialError, t as ResourceMetadataDecodeInput } from "./resource-core-Brj8naBr.js";
3
+ import { n as ResourceLayerContentIdentityInput, r as resolveEffectiveResourceContentIdentities, t as ResolveEffectiveResourceContentIdentitiesInput } from "./effective-content-identities-drMRhYE2.js";
4
+ export { AuthoredResourceRecord, AuthoredResourceRegistry, AuthoredResourceSpec, AuthoredResourceTree, AuthoredResourceTreeBuildResult, BuildResourceDependencySnapshotInput, CORE_BOOTSTRAP_WRITER_SPEC_VERSIONS, CompatibilityPolicy, ComposeLayeredResourceRegistryInput, CreateResourceContentIdentityInput, EffectiveKindDefinition, EffectiveResourceEntry, EffectiveResourceRegistry, JsonSchema, JsonSchemaValidator, KindContractLock, KindContractLockReader, KindReaderRegistration, KindSemanticContract, KindSourceContract, KindSourceShape, KindSpecRevision, KindSpecRevisionDescriptor, KindSubjectOwner, KindWriterRegistration, LoadResourceTreeOptions, PortableSpec, PortableValue, RESOURCE_ENVELOPE_CONTRACT, RESOURCE_ENVELOPE_FINGERPRINT, RESOURCE_ENVELOPE_VERSION, ReadResourceMaterialInput, ReaderProfile, ReaderTarget, RegisteredKindDefinition, ResolveEffectiveResourceContentIdentitiesInput, ResolvedResourceRecord, ResolvedResourceRegistry, ResolvedResourceTree, ResolvedSpec, ResourceCompositionError, ResourceContentIdentity, ResourceDependencyEdge, ResourceDependencySnapshot, ResourceDescriptor, ResourceDiagnostic, ResourceDigestContribution, ResourceIdentity, ResourceKindContract, ResourceLayerContentIdentityInput, ResourceLayerDescriptor, ResourceLayerInput, ResourceMaterial, ResourceMaterialError, ResourceMetadata, ResourceMetadataDecodeInput, ResourceMetadataDecodeResult, ResourceNode, ResourceOrigin, ResourcePackageAwaitable, ResourcePackageDirectoryEntry, ResourcePackageEntry, ResourcePackageEntryKind, ResourcePackageReadPort, ResourcePackageReadPortOptions, ResourcePackageSourcePathError, ResourceRecord, ResourceRegistry, ResourceResolutionReceipt, ResourceScalar, ResourceTombstone, ResourceTombstoneOrigin, ResourceTree, ResourceTreeBuildResult, ResourceValidationError, ResourceValue, ResourceValueList, ResourceValueMap, type Sha256Digest, SnapshotResource, SourceShape, SpecResolutionDefinition, SpecVersion, buildResourceDependencySnapshot, canonicalJson, canonicalResourcePackageSourcePath, compareCodeUnits, composeLayeredResourceRegistry, createDirectoryResourcePackageReadPort, createResourceContentIdentity, decodeResourceMetadata, digestCanonical, dirnameResourcePackageSourcePath, isSpecVersion, joinResourcePackageSourcePath, loadResourceTree, loadResourceTreeFromReadPort, readResourceMaterial, relativeResourcePackageSourcePath, resolveEffectiveResourceContentIdentities, sha256Digest, validateResourceTree, validateResourceTreeFromReadPort };
@@ -1,4 +1,5 @@
1
- import { a as isLoadedResourceTreeAuthentic, c as sha256Digest, d as markEffectiveRegistryAuthentic, f as ResourceCompositionError, i as readonlyMap, l as effectiveRegistryLayerBindings, m as digestCanonical, n as loadResourceTree, o as buildResourceDependencySnapshot, p as compareCodeUnits, r as validateResourceTree, s as createResourceContentIdentity, t as ResourceValidationError, u as isEffectiveRegistryAuthentic } from "./src-D3qSzGFn.js";
1
+ import { C as digestCanonical, D as dirnameResourcePackageSourcePath, E as canonicalResourcePackageSourcePath, O as joinResourcePackageSourcePath, S as compareCodeUnits, T as ResourcePackageSourcePathError, a as validateResourceTreeFromReadPort, b as ResourceCompositionError, c as RESOURCE_ENVELOPE_CONTRACT, d as isSpecVersion, f as readonlyMap, g as sha256Digest, h as createResourceContentIdentity, i as validateResourceTree, k as relativeResourcePackageSourcePath, l as RESOURCE_ENVELOPE_FINGERPRINT, m as buildResourceDependencySnapshot, n as loadResourceTree, o as decodeResourceMetadata, p as isAuthoredResourceTreeAuthentic, r as loadResourceTreeFromReadPort, s as CORE_BOOTSTRAP_WRITER_SPEC_VERSIONS, t as ResourceValidationError, u as RESOURCE_ENVELOPE_VERSION, w as createDirectoryResourcePackageReadPort, x as canonicalJson, y as markEffectiveRegistryAuthentic } from "./src-jggOQtq3.js";
2
+ import { t as resolveEffectiveResourceContentIdentities } from "./effective-content-identities-CV6XFBZy.js";
2
3
  import { lstat, readFile, realpath } from "node:fs/promises";
3
4
  import { dirname, isAbsolute, relative, resolve, sep } from "node:path";
4
5
  //#region ../resource-core/src/layered-registry.ts
@@ -12,11 +13,11 @@ function composeLayeredResourceRegistry(input) {
12
13
  const layerId = layer.id.trim();
13
14
  const packageId = layer.tree.manifest.resourceId;
14
15
  if (layerId.length === 0) {
15
- diagnostics.push(diagnostic$1("RESOURCE_LAYER_ID_EMPTY", layerLocation$1(layerIndex), "Resource layer id must be a non-empty explicit value."));
16
+ diagnostics.push(diagnostic("RESOURCE_LAYER_ID_EMPTY", layerLocation(layerIndex), "Resource layer id must be a non-empty explicit value."));
16
17
  return;
17
18
  }
18
19
  if (layerIds.has(layerId)) {
19
- diagnostics.push(diagnostic$1("RESOURCE_LAYER_ID_DUPLICATE", layerLocation$1(layerIndex, layerId), `Resource layer id '${layerId}' is declared more than once.`));
20
+ diagnostics.push(diagnostic("RESOURCE_LAYER_ID_DUPLICATE", layerLocation(layerIndex, layerId), `Resource layer id '${layerId}' is declared more than once.`));
20
21
  return;
21
22
  }
22
23
  layerIds.add(layerId);
@@ -29,7 +30,7 @@ function composeLayeredResourceRegistry(input) {
29
30
  mergeResources(layer.tree, layerId, layerIndex, packageId, entries, diagnostics);
30
31
  applyTombstones(layer, layerId, layerIndex, packageId, entries, diagnostics);
31
32
  });
32
- if (diagnostics.length > 0) throw new ResourceCompositionError(stableDiagnostics$1(diagnostics));
33
+ if (diagnostics.length > 0) throw new ResourceCompositionError(stableDiagnostics(diagnostics));
33
34
  const frozenEntries = [...entries.values()].sort((left, right) => compareCodeUnits(left.resourceId, right.resourceId)).map((entry) => freezeEntry(entry));
34
35
  const byId = readonlyMap(frozenEntries.map((entry) => [entry.resourceId, entry]));
35
36
  const byKindValues = /* @__PURE__ */ new Map();
@@ -75,7 +76,7 @@ function composeLayeredResourceRegistry(input) {
75
76
  function mergeKindDefinitions(tree, layerId, layerIndex, packageId, definitions, diagnostics) {
76
77
  for (const [kind, inputDefinition] of [...tree.registry.kindDefinitions.entries()].sort(([left], [right]) => compareCodeUnits(left, right))) {
77
78
  if (!isCanonicalVfsDocumentUri(inputDefinition.documentUri)) {
78
- diagnostics.push(diagnostic$1("RESOURCE_LAYER_PROVENANCE_INVALID", layerLocation$1(layerIndex, layerId, kind), `Resource kind '${kind}' must use canonical VFS document provenance.`));
79
+ diagnostics.push(diagnostic("RESOURCE_LAYER_PROVENANCE_INVALID", layerLocation(layerIndex, layerId, kind), `Resource kind '${kind}' must use canonical VFS document provenance.`));
79
80
  continue;
80
81
  }
81
82
  const definition = cloneRegisteredKindDefinition(inputDefinition);
@@ -89,7 +90,7 @@ function mergeKindDefinitions(tree, layerId, layerIndex, packageId, definitions,
89
90
  continue;
90
91
  }
91
92
  if (JSON.stringify(normalizedKindContract(current.definition)) !== JSON.stringify(normalizedKindContract(definition))) {
92
- diagnostics.push(diagnostic$1("RESOURCE_LAYER_KIND_DEFINITION_CONFLICT", layerLocation$1(layerIndex, layerId, kind), `Resource kind '${kind}' has incompatible KindDefinition contracts across layers.`));
93
+ diagnostics.push(diagnostic("RESOURCE_LAYER_KIND_DEFINITION_CONFLICT", layerLocation(layerIndex, layerId, kind), `Resource kind '${kind}' has incompatible KindDefinition contracts across layers.`));
93
94
  continue;
94
95
  }
95
96
  current.origins.push(origin);
@@ -100,12 +101,12 @@ function mergeResources(tree, layerId, layerIndex, packageId, entries, diagnosti
100
101
  const seenInLayer = /* @__PURE__ */ new Set();
101
102
  for (const resource of records) {
102
103
  if (seenInLayer.has(resource.resourceId)) {
103
- diagnostics.push(diagnostic$1("RESOURCE_LAYER_RESOURCE_DUPLICATE", layerLocation$1(layerIndex, layerId, resource.resourceId), `Resource '${resource.resourceId}' occurs more than once in layer '${layerId}'.`));
104
+ diagnostics.push(diagnostic("RESOURCE_LAYER_RESOURCE_DUPLICATE", layerLocation(layerIndex, layerId, resource.resourceId), `Resource '${resource.resourceId}' occurs more than once in layer '${layerId}'.`));
104
105
  continue;
105
106
  }
106
107
  seenInLayer.add(resource.resourceId);
107
108
  if (!isSafeLogicalPath(resource.logicalPath) || resource.documentUri !== `vfs://@/${resource.logicalPath}`) {
108
- diagnostics.push(diagnostic$1("RESOURCE_LAYER_PROVENANCE_INVALID", layerLocation$1(layerIndex, layerId, resource.resourceId), `Resource '${resource.resourceId}' must use matching canonical VFS documentUri and safe logicalPath provenance.`));
109
+ diagnostics.push(diagnostic("RESOURCE_LAYER_PROVENANCE_INVALID", layerLocation(layerIndex, layerId, resource.resourceId), `Resource '${resource.resourceId}' must use matching canonical VFS documentUri and safe logicalPath provenance.`));
109
110
  continue;
110
111
  }
111
112
  const immutableResource = cloneResourceRecord(resource);
@@ -124,7 +125,7 @@ function mergeResources(tree, layerId, layerIndex, packageId, entries, diagnosti
124
125
  continue;
125
126
  }
126
127
  if (current.kind !== resource.kind) {
127
- diagnostics.push(diagnostic$1("RESOURCE_LAYER_IDENTITY_KIND_CONFLICT", layerLocation$1(layerIndex, layerId, resource.resourceId), `Resource '${resource.resourceId}' changes kind from '${current.kind}' to '${resource.kind}' across layers.`));
128
+ diagnostics.push(diagnostic("RESOURCE_LAYER_IDENTITY_KIND_CONFLICT", layerLocation(layerIndex, layerId, resource.resourceId), `Resource '${resource.resourceId}' changes kind from '${current.kind}' to '${resource.kind}' across layers.`));
128
129
  continue;
129
130
  }
130
131
  if (current.effectiveOrigin) current.shadowed.push(current.effectiveOrigin);
@@ -140,25 +141,25 @@ function applyTombstones(layer, layerId, layerIndex, packageId, entries, diagnos
140
141
  for (const tombstone of tombstones) {
141
142
  const resourceId = tombstone.resourceId.trim();
142
143
  if (resourceId.length === 0) {
143
- diagnostics.push(diagnostic$1("RESOURCE_LAYER_TOMBSTONE_ID_EMPTY", layerLocation$1(layerIndex, layerId), "Resource tombstone target must be a non-empty resource id."));
144
+ diagnostics.push(diagnostic("RESOURCE_LAYER_TOMBSTONE_ID_EMPTY", layerLocation(layerIndex, layerId), "Resource tombstone target must be a non-empty resource id."));
144
145
  continue;
145
146
  }
146
147
  if (seen.has(resourceId)) {
147
- diagnostics.push(diagnostic$1("RESOURCE_LAYER_TOMBSTONE_DUPLICATE", layerLocation$1(layerIndex, layerId, resourceId), `Resource '${resourceId}' has more than one tombstone in layer '${layerId}'.`));
148
+ diagnostics.push(diagnostic("RESOURCE_LAYER_TOMBSTONE_DUPLICATE", layerLocation(layerIndex, layerId, resourceId), `Resource '${resourceId}' has more than one tombstone in layer '${layerId}'.`));
148
149
  continue;
149
150
  }
150
151
  seen.add(resourceId);
151
152
  const current = entries.get(resourceId);
152
153
  if (!current) {
153
- diagnostics.push(diagnostic$1("RESOURCE_LAYER_TOMBSTONE_TARGET_MISSING", layerLocation$1(layerIndex, layerId, resourceId), `Tombstone target '${resourceId}' does not exist in a lower or current layer.`));
154
+ diagnostics.push(diagnostic("RESOURCE_LAYER_TOMBSTONE_TARGET_MISSING", layerLocation(layerIndex, layerId, resourceId), `Tombstone target '${resourceId}' does not exist in a lower or current layer.`));
154
155
  continue;
155
156
  }
156
157
  if (current.effectiveLayerId === layerId) {
157
- diagnostics.push(diagnostic$1("RESOURCE_LAYER_TOMBSTONE_RESOURCE_CONFLICT", layerLocation$1(layerIndex, layerId, resourceId), `Resource '${resourceId}' cannot be both effective and tombstoned in layer '${layerId}'.`));
158
+ diagnostics.push(diagnostic("RESOURCE_LAYER_TOMBSTONE_RESOURCE_CONFLICT", layerLocation(layerIndex, layerId, resourceId), `Resource '${resourceId}' cannot be both effective and tombstoned in layer '${layerId}'.`));
158
159
  continue;
159
160
  }
160
161
  if (tombstone.expectedKind !== void 0 && tombstone.expectedKind !== current.kind) {
161
- diagnostics.push(diagnostic$1("RESOURCE_LAYER_TOMBSTONE_KIND_MISMATCH", layerLocation$1(layerIndex, layerId, resourceId), `Tombstone for '${resourceId}' expects kind '${tombstone.expectedKind}', but the target kind is '${current.kind}'.`));
162
+ diagnostics.push(diagnostic("RESOURCE_LAYER_TOMBSTONE_KIND_MISMATCH", layerLocation(layerIndex, layerId, resourceId), `Tombstone for '${resourceId}' expects kind '${tombstone.expectedKind}', but the target kind is '${current.kind}'.`));
162
163
  continue;
163
164
  }
164
165
  const origin = Object.freeze({
@@ -235,9 +236,9 @@ function cloneResourceRecord(resource) {
235
236
  }
236
237
  function cloneResourceMetadata(metadata) {
237
238
  return Object.freeze({
238
- apiVersion: metadata.apiVersion,
239
- ...metadata.lifecycle === void 0 ? {} : { lifecycle: metadata.lifecycle },
240
- ...metadata.version === void 0 ? {} : { version: metadata.version }
239
+ envelopeVersion: metadata.envelopeVersion,
240
+ specVersion: metadata.specVersion,
241
+ ...metadata.lifecycle === void 0 ? {} : { lifecycle: metadata.lifecycle }
241
242
  });
242
243
  }
243
244
  function cloneResourceValue(value) {
@@ -251,10 +252,17 @@ function cloneRegisteredKindDefinition(definition) {
251
252
  return Object.freeze({
252
253
  resourceId: definition.resourceId,
253
254
  resourceKind: definition.resourceKind,
255
+ subjectFqn: definition.subjectFqn,
254
256
  sourceShapes: Object.freeze([...definition.sourceShapes].sort(compareCodeUnits)),
255
257
  requiredFiles: Object.freeze([...definition.requiredFiles].sort(compareCodeUnits)),
256
- currentApiVersion: definition.currentApiVersion,
257
- supportedApiVersions: Object.freeze([...definition.supportedApiVersions].sort(compareCodeUnits)),
258
+ specRevisions: Object.freeze(definition.specRevisions.map((revision) => Object.freeze({
259
+ specVersion: revision.specVersion,
260
+ schemaRef: revision.schemaRef,
261
+ schemaFingerprint: revision.schemaFingerprint,
262
+ contractFingerprint: revision.contractFingerprint,
263
+ semanticContract: Object.freeze({ ...revision.semanticContract }),
264
+ stability: revision.stability
265
+ })).sort((left, right) => left.specVersion - right.specVersion)),
258
266
  documentCardinality: definition.documentCardinality,
259
267
  documentUri: definition.documentUri
260
268
  });
@@ -262,10 +270,17 @@ function cloneRegisteredKindDefinition(definition) {
262
270
  function normalizedKindContract(definition) {
263
271
  return {
264
272
  resourceKind: definition.resourceKind,
273
+ subjectFqn: definition.subjectFqn,
265
274
  sourceShapes: [...definition.sourceShapes].sort(compareCodeUnits),
266
275
  requiredFiles: [...definition.requiredFiles].sort(compareCodeUnits),
267
- currentApiVersion: definition.currentApiVersion,
268
- supportedApiVersions: [...definition.supportedApiVersions].sort(compareCodeUnits),
276
+ specRevisions: definition.specRevisions.map((revision) => ({
277
+ specVersion: revision.specVersion,
278
+ schemaRef: revision.schemaRef,
279
+ schemaFingerprint: revision.schemaFingerprint,
280
+ contractFingerprint: revision.contractFingerprint,
281
+ semanticContract: revision.semanticContract,
282
+ stability: revision.stability
283
+ })),
269
284
  documentCardinality: definition.documentCardinality
270
285
  };
271
286
  }
@@ -301,122 +316,9 @@ function compareOrigins(left, right) {
301
316
  function compareTombstones(left, right) {
302
317
  return left.layerIndex - right.layerIndex || compareCodeUnits(left.resourceId, right.resourceId);
303
318
  }
304
- function stableDiagnostics$1(diagnostics) {
305
- return Object.freeze([...diagnostics].sort((left, right) => compareCodeUnits(left.location, right.location) || compareCodeUnits(left.code, right.code)));
306
- }
307
- function diagnostic$1(code, location, message) {
308
- return Object.freeze({
309
- code,
310
- location,
311
- message
312
- });
313
- }
314
- function layerLocation$1(index, layerId, subject) {
315
- return `layer:${index}:${layerId ?? "unnamed"}${subject === void 0 ? "" : `:${subject}`}`;
316
- }
317
- //#endregion
318
- //#region ../resource-core/src/effective-content-identities.ts
319
- function resolveEffectiveResourceContentIdentities(input) {
320
- const diagnostics = [];
321
- if (!isEffectiveRegistryAuthentic(input.registry)) throw compositionError(diagnostic("RESOURCE_CONTENT_IDENTITY_REGISTRY_UNTRUSTED", "content-projector:registry", "Effective content identities require an authentic registry returned by composeLayeredResourceRegistry()."));
322
- const bindings = effectiveRegistryLayerBindings(input.registry) ?? [];
323
- if (input.layers.length !== input.registry.layers.length || bindings.length !== input.registry.layers.length) diagnostics.push(diagnostic("RESOURCE_CONTENT_IDENTITY_LAYER_COUNT_MISMATCH", "content-projector:layers", "Effective content identity layers must exactly match the composed registry layers."));
324
- const loadedById = /* @__PURE__ */ new Map();
325
- for (let index = 0; index < input.registry.layers.length; index += 1) {
326
- const descriptor = input.registry.layers[index];
327
- const layer = input.layers[index];
328
- const binding = bindings[index];
329
- if (!layer) continue;
330
- if (!isLoadedResourceTreeAuthentic(layer.tree)) {
331
- diagnostics.push(diagnostic("RESOURCE_CONTENT_IDENTITY_LAYER_UNTRUSTED", layerLocation(index, layer.id), `Layer '${layer.id}' must use an authentic LoadedResourceTree returned by loadResourceTree().`));
332
- continue;
333
- }
334
- if (layer.id !== descriptor.id || binding?.id !== descriptor.id) {
335
- diagnostics.push(diagnostic("RESOURCE_CONTENT_IDENTITY_LAYER_ID_MISMATCH", layerLocation(index, layer.id), `Layer at index ${index} must retain exact id '${descriptor.id}'.`));
336
- continue;
337
- }
338
- if (descriptor.index !== index) {
339
- diagnostics.push(diagnostic("RESOURCE_CONTENT_IDENTITY_LAYER_INDEX_MISMATCH", layerLocation(index, layer.id), `Layer '${layer.id}' has inconsistent registry index ${descriptor.index}.`));
340
- continue;
341
- }
342
- if (layer.tree.manifest.resourceId !== descriptor.packageId) {
343
- diagnostics.push(diagnostic("RESOURCE_CONTENT_IDENTITY_LAYER_PACKAGE_MISMATCH", layerLocation(index, layer.id), `Layer '${layer.id}' must retain package '${descriptor.packageId}'.`));
344
- continue;
345
- }
346
- if (binding?.tree !== layer.tree) {
347
- diagnostics.push(diagnostic("RESOURCE_CONTENT_IDENTITY_LAYER_BINDING_MISMATCH", layerLocation(index, layer.id), `Layer '${layer.id}' must use the exact loaded tree composed into the registry.`));
348
- continue;
349
- }
350
- validateLoadedIdentityCoverage(layer.tree, layer.id, diagnostics);
351
- loadedById.set(layer.id, layer.tree);
352
- }
353
- const effectiveEntries = [...input.registry.byId.values()].filter((entry) => entry.resource !== void 0).sort((left, right) => compareCodeUnits(left.resourceId, right.resourceId));
354
- const effectiveIds = new Set(effectiveEntries.map((entry) => entry.resourceId));
355
- for (const resourceId of input.contributions?.keys() ?? []) if (!effectiveIds.has(resourceId)) diagnostics.push(diagnostic("RESOURCE_DIGEST_CONTRIBUTION_OWNER_UNKNOWN", contentLocation(resourceId), `Digest contributions target unknown effective resource '${resourceId}'.`));
356
- const output = [];
357
- for (const entry of effectiveEntries) {
358
- const tree = entry.effectiveLayerId === void 0 ? void 0 : loadedById.get(entry.effectiveLayerId);
359
- if (!tree || !entry.effectiveOrigin) {
360
- diagnostics.push(diagnostic("RESOURCE_CONTENT_IDENTITY_EFFECTIVE_ORIGIN_MISSING", contentLocation(entry.resourceId), `Effective resource '${entry.resourceId}' has no exact loaded layer origin.`));
361
- continue;
362
- }
363
- validateEffectiveOrigin(entry, input.registry, tree, diagnostics);
364
- const authorityIdentity = tree.contentIdentities.get(entry.resourceId);
365
- if (!authorityIdentity) {
366
- diagnostics.push(diagnostic("RESOURCE_CONTENT_IDENTITY_MISSING", contentLocation(entry.resourceId), `Effective resource '${entry.resourceId}' is missing its loader authority identity.`));
367
- continue;
368
- }
369
- try {
370
- const identity = createResourceContentIdentity({
371
- resourceId: entry.resourceId,
372
- authorityDigest: authorityIdentity.authorityDigest,
373
- contributions: [...authorityIdentity.contributions, ...input.contributions?.get(entry.resourceId) ?? []]
374
- });
375
- output.push([entry.resourceId, identity]);
376
- } catch (error) {
377
- if (error instanceof ResourceCompositionError) diagnostics.push(...error.diagnostics);
378
- else throw error;
379
- }
380
- }
381
- if (diagnostics.length > 0) throw new ResourceCompositionError(stableDiagnostics(diagnostics));
382
- return readonlyMap(output.sort(([left], [right]) => compareCodeUnits(left, right)));
383
- }
384
- function validateLoadedIdentityCoverage(tree, layerId, diagnostics) {
385
- const resources = [...tree.registry.byKind.values()].flatMap((records) => [...records]).sort((left, right) => compareCodeUnits(left.resourceId, right.resourceId));
386
- const resourcesById = new Map(resources.map((resource) => [resource.resourceId, resource]));
387
- for (const resource of resources) {
388
- const identity = tree.contentIdentities.get(resource.resourceId);
389
- if (!identity) {
390
- diagnostics.push(diagnostic("RESOURCE_CONTENT_IDENTITY_MISSING", layerLocation(void 0, layerId, resource.resourceId), `Loaded resource '${resource.resourceId}' has no authority identity.`));
391
- continue;
392
- }
393
- const normalized = createResourceContentIdentity({
394
- resourceId: identity.resourceId,
395
- authorityDigest: identity.authorityDigest,
396
- contributions: identity.contributions
397
- });
398
- if (identity.resourceId !== resource.resourceId || identity.contentDigest !== normalized.contentDigest) diagnostics.push(diagnostic("RESOURCE_CONTENT_IDENTITY_INVALID", layerLocation(void 0, layerId, resource.resourceId), `Loaded resource '${resource.resourceId}' has an inconsistent authority identity.`));
399
- }
400
- for (const resourceId of tree.contentIdentities.keys()) if (!resourcesById.has(resourceId)) diagnostics.push(diagnostic("RESOURCE_CONTENT_IDENTITY_EXTRA", layerLocation(void 0, layerId, resourceId), `Loaded tree contains an extra authority identity '${resourceId}'.`));
401
- }
402
- function validateEffectiveOrigin(entry, registry, tree, diagnostics) {
403
- const origin = entry.effectiveOrigin;
404
- const descriptor = registry.layers[origin.layerIndex];
405
- const loadedRecord = findResource$1(tree, entry.resourceId);
406
- if (!descriptor || descriptor.id !== origin.layerId || descriptor.packageId !== origin.packageId || tree.manifest.resourceId !== origin.packageId || !loadedRecord || loadedRecord.documentUri !== origin.documentUri || loadedRecord.logicalPath !== origin.logicalPath) diagnostics.push(diagnostic("RESOURCE_CONTENT_IDENTITY_EFFECTIVE_ORIGIN_MISMATCH", contentLocation(entry.resourceId), `Effective resource '${entry.resourceId}' does not match its exact layer/package/origin facts.`));
407
- }
408
- function findResource$1(tree, resourceId) {
409
- for (const records of tree.registry.byKind.values()) {
410
- const resource = records.find((record) => record.resourceId === resourceId);
411
- if (resource) return resource;
412
- }
413
- }
414
319
  function stableDiagnostics(diagnostics) {
415
320
  return Object.freeze([...diagnostics].sort((left, right) => compareCodeUnits(left.location, right.location) || compareCodeUnits(left.code, right.code)));
416
321
  }
417
- function compositionError(diagnosticValue) {
418
- return new ResourceCompositionError(Object.freeze([diagnosticValue]));
419
- }
420
322
  function diagnostic(code, location, message) {
421
323
  return Object.freeze({
422
324
  code,
@@ -424,11 +326,8 @@ function diagnostic(code, location, message) {
424
326
  message
425
327
  });
426
328
  }
427
- function layerLocation(index, layerId, resourceId) {
428
- return `content-layer:${index ?? "unknown"}:${layerId}${resourceId === void 0 ? "" : `:${resourceId}`}`;
429
- }
430
- function contentLocation(resourceId) {
431
- return `content:${resourceId || "unnamed"}`;
329
+ function layerLocation(index, layerId, subject) {
330
+ return `layer:${index}:${layerId ?? "unnamed"}${subject === void 0 ? "" : `:${subject}`}`;
432
331
  }
433
332
  //#endregion
434
333
  //#region ../resource-core/src/resource-material.ts
@@ -441,7 +340,7 @@ var ResourceMaterialError = class extends Error {
441
340
  }
442
341
  };
443
342
  async function readResourceMaterial(input) {
444
- if (!isLoadedResourceTreeAuthentic(input.tree)) throw materialError("RESOURCE_MATERIAL_TREE_UNTRUSTED", input.resourceId, "Resource materials require an authentic LoadedResourceTree.");
343
+ if (!isAuthoredResourceTreeAuthentic(input.tree)) throw materialError("RESOURCE_MATERIAL_TREE_UNTRUSTED", input.resourceId, "Resource materials require an authentic AuthoredResourceTree.");
445
344
  const record = findResource(input.tree, input.resourceId);
446
345
  const identity = input.tree.contentIdentities.get(input.resourceId);
447
346
  if (!record || record.sourceShape !== "directory" || !identity) throw materialError("RESOURCE_MATERIAL_RESOURCE_INVALID", input.resourceId, `Resource '${input.resourceId}' is not an authentic directory resource.`);
@@ -515,4 +414,4 @@ function materialError(code, resourceId, message) {
515
414
  })]);
516
415
  }
517
416
  //#endregion
518
- export { ResourceCompositionError, ResourceMaterialError, ResourceValidationError, buildResourceDependencySnapshot, composeLayeredResourceRegistry, createResourceContentIdentity, loadResourceTree, readResourceMaterial, resolveEffectiveResourceContentIdentities, sha256Digest, validateResourceTree };
417
+ export { CORE_BOOTSTRAP_WRITER_SPEC_VERSIONS, RESOURCE_ENVELOPE_CONTRACT, RESOURCE_ENVELOPE_FINGERPRINT, RESOURCE_ENVELOPE_VERSION, ResourceCompositionError, ResourceMaterialError, ResourcePackageSourcePathError, ResourceValidationError, buildResourceDependencySnapshot, canonicalJson, canonicalResourcePackageSourcePath, compareCodeUnits, composeLayeredResourceRegistry, createDirectoryResourcePackageReadPort, createResourceContentIdentity, decodeResourceMetadata, digestCanonical, dirnameResourcePackageSourcePath, isSpecVersion, joinResourcePackageSourcePath, loadResourceTree, loadResourceTreeFromReadPort, readResourceMaterial, relativeResourcePackageSourcePath, resolveEffectiveResourceContentIdentities, sha256Digest, validateResourceTree, validateResourceTreeFromReadPort };
@@ -1,2 +1,2 @@
1
- import { n as resourceProjectionPackage, t as ResourceRegistry } from "./index-CF4nEkOi.js";
1
+ import { n as resourceProjectionPackage, t as ResourceRegistry } from "./index-DI3WtuXq.js";
2
2
  export { ResourceRegistry, resourceProjectionPackage };
@@ -1,3 +1,3 @@
1
- import { I as SkillCapsuleDependency } from "./index-Cqh9pEBa.js";
2
- import { S as skillCapsuleDistributionProjection, _ as applySkillCapsuleDistributionPlan, a as PlannedSkillCapsule, b as compilerSkillPackage, c as SkillCapsuleContentDigest, d as SkillCapsuleDistributionReceipt, f as SkillCapsuleIdentity, g as SkillReference, h as SkillDescriptor, i as PlanSkillCapsuleDistributionInput, l as SkillCapsuleDistributionError, m as SkillCapsuleProvenanceManifest, n as CompileResourceSkillCapsuleInput, o as PlannedSkillFile, p as SkillCapsulePlan, r as CompileSkillCapsuleInput, s as SkillCapsuleApplyStep, t as ApplySkillCapsuleDistributionOptions, u as SkillCapsuleDistributionPlan, v as compileResourceSkillCapsule, x as planSkillCapsuleDistribution, y as compileSkillCapsule } from "./index-B515mMkO.js";
1
+ import { I as SkillCapsuleDependency } from "./index-DEikbOFh.js";
2
+ import { S as skillCapsuleDistributionProjection, _ as applySkillCapsuleDistributionPlan, a as PlannedSkillCapsule, b as compilerSkillPackage, c as SkillCapsuleContentDigest, d as SkillCapsuleDistributionReceipt, f as SkillCapsuleIdentity, g as SkillReference, h as SkillDescriptor, i as PlanSkillCapsuleDistributionInput, l as SkillCapsuleDistributionError, m as SkillCapsuleProvenanceManifest, n as CompileResourceSkillCapsuleInput, o as PlannedSkillFile, p as SkillCapsulePlan, r as CompileSkillCapsuleInput, s as SkillCapsuleApplyStep, t as ApplySkillCapsuleDistributionOptions, u as SkillCapsuleDistributionPlan, v as compileResourceSkillCapsule, x as planSkillCapsuleDistribution, y as compileSkillCapsule } from "./index-CR7wJSSX.js";
3
3
  export { ApplySkillCapsuleDistributionOptions, CompileResourceSkillCapsuleInput, CompileSkillCapsuleInput, PlanSkillCapsuleDistributionInput, PlannedSkillCapsule, PlannedSkillFile, SkillCapsuleApplyStep, SkillCapsuleContentDigest, type SkillCapsuleDependency, SkillCapsuleDistributionError, SkillCapsuleDistributionPlan, SkillCapsuleDistributionReceipt, SkillCapsuleIdentity, SkillCapsulePlan, SkillCapsuleProvenanceManifest, SkillDescriptor, SkillReference, applySkillCapsuleDistributionPlan, compileResourceSkillCapsule, compileSkillCapsule, compilerSkillPackage, planSkillCapsuleDistribution, skillCapsuleDistributionProjection };
@@ -1,2 +1,2 @@
1
- import { a as compilerSkillPackage, i as compileSkillCapsule, n as applySkillCapsuleDistributionPlan, o as planSkillCapsuleDistribution, r as compileResourceSkillCapsule, s as skillCapsuleDistributionProjection, t as SkillCapsuleDistributionError } from "./src-CaQ25rMj.js";
1
+ import { a as compilerSkillPackage, i as compileSkillCapsule, n as applySkillCapsuleDistributionPlan, o as planSkillCapsuleDistribution, r as compileResourceSkillCapsule, s as skillCapsuleDistributionProjection, t as SkillCapsuleDistributionError } from "./src-DLJUCH0M.js";
2
2
  export { SkillCapsuleDistributionError, applySkillCapsuleDistributionPlan, compileResourceSkillCapsule, compileSkillCapsule, compilerSkillPackage, planSkillCapsuleDistribution, skillCapsuleDistributionProjection };
@@ -1,4 +1,4 @@
1
- import { n as loadResourceTree } from "./src-D3qSzGFn.js";
1
+ import { n as loadResourceTree } from "./src-jggOQtq3.js";
2
2
  import { readFile } from "node:fs/promises";
3
3
  import { dirname, join } from "node:path";
4
4
  import { parse } from "yaml";
@@ -388,14 +388,11 @@ async function readTextResource(module, record, kind) {
388
388
  async function readSkillCapsule(module, record) {
389
389
  const metadataMaterial = await readRequiredMaterial(module, record, "SkillMetadata");
390
390
  const template = await readRequiredMaterial(module, record, "Template");
391
- const version = record.metadata.version;
392
- const apiVersion = record.metadata.apiVersion;
393
- if (!apiVersion) throw new Error(`SKILL_CAPSULE_API_VERSION_MISSING: ${record.logicalPath} is missing XNL metadata apiVersion`);
394
- if (!version) throw new Error(`SKILL_CAPSULE_VERSION_MISSING: ${record.logicalPath} is missing XNL metadata version`);
395
391
  const parsedMetadata = parse(metadataMaterial.content);
396
392
  if (!parsedMetadata || typeof parsedMetadata !== "object" || Array.isArray(parsedMetadata)) throw new Error(`SKILL_CAPSULE_METADATA_INVALID: ${record.logicalPath} Skill metadata must be a YAML object`);
397
393
  const yamlVersion = parsedMetadata.version;
398
- if (yamlVersion !== void 0 && yamlVersion !== version) throw new Error(`SKILL_CAPSULE_VERSION_CONFLICT: ${requiredFqn(record)} YAML version ${JSON.stringify(yamlVersion)} does not match XNL version ${version}`);
394
+ if (typeof yamlVersion !== "string" || !yamlVersion.trim()) throw new Error(`SKILL_CAPSULE_VERSION_MISSING: ${record.logicalPath} Skill metadata must declare a non-empty version`);
395
+ const version = yamlVersion.trim();
399
396
  const hasXnlName = Object.prototype.hasOwnProperty.call(record.node.properties, "name");
400
397
  const xnlName = stringResourceValue(record.node.properties.name);
401
398
  if (hasXnlName && !xnlName) throw new Error(`SKILL_CAPSULE_NAME_INVALID: ${requiredFqn(record)} XNL name must be a non-empty string`);
@@ -404,7 +401,8 @@ async function readSkillCapsule(module, record) {
404
401
  kind: "SkillCapsule",
405
402
  fqn: requiredFqn(record),
406
403
  ...xnlName ? { name: xnlName } : {},
407
- apiVersion,
404
+ envelopeVersion: record.metadata.envelopeVersion,
405
+ specVersion: record.metadata.specVersion,
408
406
  version,
409
407
  description: requiredDescription(record),
410
408
  metadata: {
@@ -1,4 +1,4 @@
1
- import { l as resourceRefToFqn, u as resolveObjectOperationCompilation } from "./src-3pnDAjBD.js";
1
+ import { l as resourceRefToFqn, u as resolveObjectOperationCompilation } from "./src-B0Hja_dk.js";
2
2
  import { c as unsafeUnicodeCodeUnitIssue, i as planResourceMappings, o as safePathLexicalIssue, r as parseResourceMappings, t as ResourceMappingPathError } from "./src-25wZPUyX.js";
3
3
  import { lstat, mkdir, mkdtemp, readFile, readdir, rename, rm, writeFile } from "node:fs/promises";
4
4
  import { basename, dirname, join, posix, resolve } from "node:path";
@@ -70,7 +70,8 @@ async function planSkillCapsuleDistribution(input) {
70
70
  const targetRelativePath = posix.join(identity.name, file.targetRelativePath);
71
71
  return plannedSkillFile({
72
72
  skillFqn: identity.fqn,
73
- skillApiVersion: identity.apiVersion,
73
+ skillEnvelopeVersion: identity.envelopeVersion,
74
+ skillSpecVersion: identity.specVersion,
74
75
  skillVersion: identity.version,
75
76
  capsuleRelativePath: file.targetRelativePath,
76
77
  targetRelativePath
@@ -294,7 +295,8 @@ function skillIdentity(skill) {
294
295
  return Object.freeze({
295
296
  fqn: skill.fqn,
296
297
  name: skillOutputName(skill),
297
- apiVersion: skill.apiVersion,
298
+ envelopeVersion: skill.envelopeVersion,
299
+ specVersion: skill.specVersion,
298
300
  version: skill.version
299
301
  });
300
302
  }
@@ -338,7 +340,7 @@ function assertValidDistributionPlan(plan) {
338
340
  const capsuleByFqn = /* @__PURE__ */ new Map();
339
341
  for (const capsule of plan.capsules) {
340
342
  validateSkillOutputName(capsule.identity.name);
341
- if (!capsule.identity.fqn.trim() || !capsule.identity.apiVersion.trim() || !capsule.identity.version.trim()) failDistribution("SKILL_PLAN_IDENTITY_INVALID", "planned Skill identity requires non-empty FQN, apiVersion and version");
343
+ if (!capsule.identity.fqn.trim() || !capsule.identity.envelopeVersion.trim() || !Number.isSafeInteger(capsule.identity.specVersion) || capsule.identity.specVersion <= 0 || !capsule.identity.version.trim()) failDistribution("SKILL_PLAN_IDENTITY_INVALID", "planned Skill identity requires non-empty FQN/envelopeVersion/version and a positive specVersion");
342
344
  if (capsuleByFqn.has(capsule.identity.fqn)) failDistribution("SKILL_PLAN_CAPSULE_DUPLICATE", `duplicate planned capsule ${capsule.identity.fqn}`);
343
345
  capsuleByFqn.set(capsule.identity.fqn, capsule);
344
346
  for (const file of capsule.files) {
@@ -348,7 +350,7 @@ function assertValidDistributionPlan(plan) {
348
350
  assertCanonicalSkillEntry(capsule);
349
351
  for (const file of capsule.files) {
350
352
  assertValidPlannedFile(file);
351
- if (file.skillFqn !== capsule.identity.fqn || file.skillApiVersion !== capsule.identity.apiVersion || file.skillVersion !== capsule.identity.version) failDistribution("SKILL_PLAN_FILE_OWNER_INVALID", `file ${file.targetRelativePath} has the wrong Skill owner`);
353
+ if (file.skillFqn !== capsule.identity.fqn || file.skillEnvelopeVersion !== capsule.identity.envelopeVersion || file.skillSpecVersion !== capsule.identity.specVersion || file.skillVersion !== capsule.identity.version) failDistribution("SKILL_PLAN_FILE_OWNER_INVALID", `file ${file.targetRelativePath} has the wrong Skill owner`);
352
354
  if (file.targetRelativePath !== posix.join(capsule.identity.name, file.capsuleRelativePath)) failDistribution("SKILL_PLAN_TARGET_INVALID", `file ${file.targetRelativePath} is outside Skill output ${capsule.identity.name}`);
353
355
  }
354
356
  assertCanonicalSkillProvenance(capsule);
@@ -448,7 +450,8 @@ function bytesEqual(left, right) {
448
450
  function fileDigestProjection(file) {
449
451
  return {
450
452
  skillFqn: file.skillFqn,
451
- skillApiVersion: file.skillApiVersion,
453
+ skillEnvelopeVersion: file.skillEnvelopeVersion,
454
+ skillSpecVersion: file.skillSpecVersion,
452
455
  skillVersion: file.skillVersion,
453
456
  capsuleRelativePath: file.capsuleRelativePath,
454
457
  targetRelativePath: file.targetRelativePath,
@@ -476,7 +479,8 @@ function canonicalSkillProvenanceBytes(identity, payloadFiles) {
476
479
  generatedBy: "halfcode.skill-distribution/v1",
477
480
  source: {
478
481
  fqn: identity.fqn,
479
- apiVersion: identity.apiVersion,
482
+ envelopeVersion: identity.envelopeVersion,
483
+ specVersion: identity.specVersion,
480
484
  version: identity.version
481
485
  },
482
486
  payloadFiles: payloadFiles.map((file) => ({