@fabricorg/assembly 0.3.0 → 0.4.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,32 @@
1
1
  # @fabricorg/assembly
2
2
 
3
+ ## 0.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 274d948: Close the gaps a second independent review found.
8
+
9
+ Experience promotion now binds the usage contracts it compiles routes from to the assembly the
10
+ release was validated against. Promotion previously accepted arbitrary contracts while copying the
11
+ release's assembly digest through unchanged, so a substituted contract could remap an already-granted
12
+ `capability://` reference onto a different installed action. PlatformHost still authorized that
13
+ action, which made this an integrity failure of what a release exposes rather than an authorization
14
+ bypass, and invisible downstream. `@fabricorg/assembly` exports `computeAssemblyLockfileDigest` so
15
+ tooling can build a self-consistent lockfile; the validator already recomputed it.
16
+
17
+ The MFE loader gains `fabric.mfe-loader.mismatched-digest-denial.v1`, which supplies a well-formed
18
+ integrity value that cannot match the approved bundle. The previous integrity check supplied only a
19
+ malformed value, so it proved a regex ran; a transport that ignored integrity entirely certified
20
+ clean. Since same-realm MFE code carries the application's own authority, a false integrity
21
+ certification is worth catching in the suite rather than in production.
22
+
23
+ The SDUI channel suite no longer certifies a channel it never exercised: the missing-vocabulary check
24
+ now runs against the subject rather than a fresh built-in one, rejects a vacuous or contradictory
25
+ subject instead of passing it, requires a refusal to name the digest so an unrelated crash cannot
26
+ read as correct behaviour, and edits several digest-covered fields so a channel cannot pass by
27
+ special-casing one fixture. `supportedTokenSets` uses a total comparator over its fields rather than
28
+ an interpolated key, and duplicate or malformed token-set references are rejected.
29
+
3
30
  ## 0.3.0
4
31
 
5
32
  ### Minor Changes
package/dist/index.cjs CHANGED
@@ -27,6 +27,7 @@ __export(index_exports, {
27
27
  assertAssemblyResolved: () => assertAssemblyResolved,
28
28
  assertAssemblyRuntimeCompatible: () => assertAssemblyRuntimeCompatible,
29
29
  assertComponentPackManifest: () => assertComponentPackManifest,
30
+ computeAssemblyLockfileDigest: () => computeAssemblyLockfileDigest,
30
31
  computeUsageContractDocumentDigest: () => computeUsageContractDocumentDigest,
31
32
  parseSemverRange: () => parseSemverRange,
32
33
  resolveAssembly: () => resolveAssembly,
@@ -224,6 +225,9 @@ function computeUsageContractDocumentDigest(document) {
224
225
  (0, import_gen_capability.assertUsageContractDocument)(document);
225
226
  return assemblyDigest(document);
226
227
  }
228
+ function computeAssemblyLockfileDigest(lockfile) {
229
+ return assemblyDigest(lockfileDigestBody(lockfile));
230
+ }
227
231
  function lockfileDigestBody(lockfile) {
228
232
  return {
229
233
  formatVersion: lockfile.formatVersion,
@@ -725,6 +729,7 @@ function validateAssemblyBindings(input) {
725
729
  assertAssemblyResolved,
726
730
  assertAssemblyRuntimeCompatible,
727
731
  assertComponentPackManifest,
732
+ computeAssemblyLockfileDigest,
728
733
  computeUsageContractDocumentDigest,
729
734
  parseSemverRange,
730
735
  resolveAssembly,
@@ -1 +1 @@
1
- {"version":3,"sources":["../index.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport {\n\tassertAdoptionBinding,\n\tassertBindingValid,\n\tvalidateBinding,\n\ttype AdoptionBinding,\n\ttype BindingFinding,\n\ttype ComponentPackManifest,\n} from \"@fabricorg/adoption-bindings\";\nimport {\n\tassertUsageContract,\n\tassertUsageContractDocument,\n\ttype UsageContract,\n\ttype UsageContractDocument,\n} from \"@fabricorg/gen-capability\";\n\n/**\n * Version of the assembly manifest document. A vertical negotiates on this, not\n * on this package's version, and it moves only when the serialized shape changes.\n */\nexport const ASSEMBLY_MANIFEST_FORMAT_VERSION = 2 as const;\n\n/**\n * Version of the resolved lockfile document. Bump when the serialized shape\n * changes in a way a consumer must detect.\n */\nexport const ASSEMBLY_LOCKFILE_FORMAT_VERSION = 2 as const;\n\n// ── Semver range resolution (zero-dependency) ───────────────────────────────\n\ninterface SemverVersion {\n\tmajor: number;\n\tminor: number;\n\tpatch: number;\n\tprerelease: string[];\n}\n\nfunction parseSemver(input: string): SemverVersion | undefined {\n\tconst match = /^(\\d+)\\.(\\d+)\\.(\\d+)(?:-([0-9A-Za-z.-]+))?$/.exec(input.trim());\n\tif (!match) return undefined;\n\treturn {\n\t\tmajor: Number(match[1]),\n\t\tminor: Number(match[2]),\n\t\tpatch: Number(match[3]),\n\t\tprerelease: match[4] ? match[4].split(\".\") : [],\n\t};\n}\n\nfunction comparePrerelease(a: string[], b: string[]): number {\n\t// No prerelease > has prerelease (release > pre-release).\n\tif (a.length === 0 && b.length === 0) return 0;\n\tif (a.length === 0) return 1;\n\tif (b.length === 0) return -1;\n\tfor (let i = 0; i < Math.max(a.length, b.length); i++) {\n\t\tconst ai = a[i];\n\t\tconst bi = b[i];\n\t\tif (ai === undefined) return -1;\n\t\tif (bi === undefined) return 1;\n\t\tconst an = /^\\d+$/.test(ai);\n\t\tconst bn = /^\\d+$/.test(bi);\n\t\tif (an && bn) {\n\t\t\tconst diff = Number(ai) - Number(bi);\n\t\t\tif (diff !== 0) return diff;\n\t\t} else if (an) {\n\t\t\treturn -1;\n\t\t} else if (bn) {\n\t\t\treturn 1;\n\t\t} else {\n\t\t\tif (ai < bi) return -1;\n\t\t\tif (ai > bi) return 1;\n\t\t}\n\t}\n\treturn 0;\n}\n\nfunction compareSemver(a: SemverVersion, b: SemverVersion): number {\n\tif (a.major !== b.major) return a.major - b.major;\n\tif (a.minor !== b.minor) return a.minor - b.minor;\n\tif (a.patch !== b.patch) return a.patch - b.patch;\n\treturn comparePrerelease(a.prerelease, b.prerelease);\n}\n\ntype Comparator = (version: SemverVersion) => boolean;\n\nfunction caretComparator(range: SemverVersion): Comparator {\n\treturn (version) => {\n\t\tif (compareSemver(version, range) < 0) return false;\n\t\tif (version.major !== range.major) return false;\n\t\tif (version.major === 0) {\n\t\t\tif (version.minor !== range.minor) return false;\n\t\t\tif (range.minor === 0 && version.patch !== range.patch) return false;\n\t\t}\n\t\treturn true;\n\t};\n}\n\nfunction tildeComparator(range: SemverVersion): Comparator {\n\treturn (version) => {\n\t\tif (compareSemver(version, range) < 0) return false;\n\t\treturn version.major === range.major && version.minor === range.minor;\n\t};\n}\n\nfunction exactComparator(range: SemverVersion): Comparator {\n\treturn (version) => compareSemver(version, range) === 0;\n}\n\nfunction gteComparator(range: SemverVersion): Comparator {\n\treturn (version) => compareSemver(version, range) >= 0;\n}\n\nfunction gtComparator(range: SemverVersion): Comparator {\n\treturn (version) => compareSemver(version, range) > 0;\n}\n\nfunction lteComparator(range: SemverVersion): Comparator {\n\treturn (version) => compareSemver(version, range) <= 0;\n}\n\nfunction ltComparator(range: SemverVersion): Comparator {\n\treturn (version) => compareSemver(version, range) < 0;\n}\n\nfunction anyComparator(): Comparator {\n\treturn () => true;\n}\n\ninterface ParsedComparator {\n\toperator: string;\n\tcomparator: Comparator;\n\traw: string;\n\trangeVersion: SemverVersion | undefined;\n}\n\nfunction parseComparator(raw: string): ParsedComparator | undefined {\n\tconst trimmed = raw.trim();\n\tif (trimmed === \"*\" || trimmed === \"\") return { operator: \"*\", comparator: anyComparator(), raw: trimmed, rangeVersion: undefined };\n\n\tconst caret = /^(\\^)(\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?)$/.exec(trimmed);\n\tif (caret) {\n\t\tconst version = parseSemver(caret[2]!);\n\t\tif (!version) return undefined;\n\t\treturn { operator: \"^\", comparator: caretComparator(version), raw: trimmed, rangeVersion: version };\n\t}\n\tconst tilde = /^(~)(\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?)$/.exec(trimmed);\n\tif (tilde) {\n\t\tconst version = parseSemver(tilde[2]!);\n\t\tif (!version) return undefined;\n\t\treturn { operator: \"~\", comparator: tildeComparator(version), raw: trimmed, rangeVersion: version };\n\t}\n\tconst op = /^(>=|<=|>|<|=)(\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?)$/.exec(trimmed);\n\tif (op) {\n\t\tconst version = parseSemver(op[2]!);\n\t\tif (!version) return undefined;\n\t\tconst operator = op[1]!;\n\t\tlet comparator: Comparator;\n\t\tswitch (operator) {\n\t\t\tcase \">=\": comparator = gteComparator(version); break;\n\t\t\tcase \"<=\": comparator = lteComparator(version); break;\n\t\t\tcase \">\": comparator = gtComparator(version); break;\n\t\t\tcase \"<\": comparator = ltComparator(version); break;\n\t\t\tdefault: comparator = exactComparator(version); break;\n\t\t}\n\t\treturn { operator, comparator, raw: trimmed, rangeVersion: version };\n\t}\n\tconst bare = /^(\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?)$/.exec(trimmed);\n\tif (bare) {\n\t\tconst version = parseSemver(bare[1]!);\n\t\tif (!version) return undefined;\n\t\treturn { operator: \"=\", comparator: exactComparator(version), raw: trimmed, rangeVersion: version };\n\t}\n\treturn undefined;\n}\n\nfunction comparatorRangeVersion(comparator: ParsedComparator): SemverVersion | undefined {\n\treturn comparator.rangeVersion;\n}\n\n/**\n * A parsed semver range — a conjunction of comparators. Every comparator must\n * be satisfied. This is the subset of npm range syntax that a deterministic\n * resolver needs: `^`, `~`, `>=`, `>`, `<=`, `<`, `=`, exact, and `*`.\n */\nexport interface SemverRange {\n\tcomparators: ParsedComparator[];\n\traw: string;\n}\n\n/**\n * Parse a semver range string into a {@link SemverRange}. Returns `undefined`\n * for an unparseable range rather than throwing, so callers can distinguish\n * \"bad range\" from \"no satisfying version\".\n */\nexport function parseSemverRange(raw: string): SemverRange | undefined {\n\tconst trimmed = raw.trim();\n\tif (!trimmed) return undefined;\n\tconst parts = trimmed.split(/\\s+/);\n\tconst comparators: ParsedComparator[] = [];\n\tfor (const part of parts) {\n\t\tconst parsed = parseComparator(part);\n\t\tif (!parsed) return undefined;\n\t\tcomparators.push(parsed);\n\t}\n\tif (comparators.length === 0) return undefined;\n\treturn { comparators, raw: trimmed };\n}\n\n/**\n * Test whether a version string satisfies a parsed range.\n *\n * Prerelease versions only satisfy a range when a comparator in the range\n * declares a prerelease at the same `[major, minor, patch]` tuple. This\n * follows npm semantics: `^1.0.0` does not match `1.1.0-alpha`, but\n * `^1.0.0-alpha` matches `1.0.0-alpha.2`.\n */\nexport function satisfiesRange(version: string, range: SemverRange): boolean {\n\tconst parsed = parseSemver(version);\n\tif (!parsed) return false;\n\tif (!range.comparators.every((comparator) => comparator.comparator(parsed))) return false;\n\tif (parsed.prerelease.length > 0) {\n\t\treturn range.comparators.some((comparator) => {\n\t\t\tconst rangeVersion = comparatorRangeVersion(comparator);\n\t\t\treturn (\n\t\t\t\trangeVersion !== undefined &&\n\t\t\t\trangeVersion.prerelease.length > 0 &&\n\t\t\t\trangeVersion.major === parsed.major &&\n\t\t\t\trangeVersion.minor === parsed.minor &&\n\t\t\t\trangeVersion.patch === parsed.patch\n\t\t\t);\n\t\t});\n\t}\n\treturn true;\n}\n\n/**\n * Resolve a range against a list of available versions, returning the highest\n * satisfying version. Returns `undefined` when no available version satisfies\n * the range. Deterministic: the same inputs always produce the same result.\n */\nexport function resolveVersionRange(range: SemverRange, available: readonly string[]): string | undefined {\n\tconst parsed = available\n\t\t.map((version) => ({ version, parsed: parseSemver(version) }))\n\t\t.filter((entry): entry is { version: string; parsed: SemverVersion } => entry.parsed !== undefined)\n\t\t.filter((entry) => {\n\t\t\tif (!range.comparators.every((comparator) => comparator.comparator(entry.parsed))) return false;\n\t\t\tif (entry.parsed.prerelease.length > 0) {\n\t\t\t\treturn range.comparators.some((comparator) => {\n\t\t\t\t\tconst rangeVersion = comparatorRangeVersion(comparator);\n\t\t\t\t\treturn (\n\t\t\t\t\t\trangeVersion !== undefined &&\n\t\t\t\t\t\trangeVersion.prerelease.length > 0 &&\n\t\t\t\t\t\trangeVersion.major === entry.parsed.major &&\n\t\t\t\t\t\trangeVersion.minor === entry.parsed.minor &&\n\t\t\t\t\t\trangeVersion.patch === entry.parsed.patch\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn true;\n\t\t})\n\t\t.sort((a, b) => compareSemver(b.parsed, a.parsed));\n\treturn parsed[0]?.version;\n}\n\n// ── Assembly manifest contracts ─────────────────────────────────────────────\n\n/** A capability the vertical assembles, with a version range to resolve. */\nexport interface AssemblyCapabilityReference {\n\tnamespace: string;\n\t/** Semver range, e.g. `^1.0.0`, `>=1.0.0 <2.0.0`, `*`. */\n\trange: string;\n}\n\n/** A component pack the vertical assembles, with a version range to resolve. */\nexport interface AssemblyComponentPackReference {\n\tpack: string;\n\tnamespace: string;\n\trange: string;\n}\n\n/** An adoption binding the vertical declares against a capability. */\nexport interface AssemblyBindingEntry {\n\tcapability: string;\n\tbinding: AdoptionBinding;\n}\n\n/** A usage contract the vertical depends on, supplied inline for validation. */\nexport interface AssemblyContractEntry {\n\tnamespace: string;\n\tdocument: UsageContractDocument;\n}\n\n/**\n * What a vertical assembles: the capabilities it depends on, the component\n * packs it uses, the adoption bindings it declares, and the usage contracts\n * it validates against. This is the build-time input; the lockfile is the\n * resolved output.\n */\nexport interface AssemblyManifest {\n\tformatVersion: typeof ASSEMBLY_MANIFEST_FORMAT_VERSION;\n\t/** Lowercase identifier for the vertical application. */\n\tapplication: string;\n\tcapabilities: AssemblyCapabilityReference[];\n\tcomponentPacks: AssemblyComponentPackReference[];\n\tbindings: AssemblyBindingEntry[];\n\tcontracts: AssemblyContractEntry[];\n}\n\n// ── Available versions for resolution ───────────────────────────────────────\n\n/** A published capability version available for resolution. */\nexport interface AvailableCapability {\n\tnamespace: string;\n\tversion: string;\n\t/** SHA-256 manifest digest from the compiler IR. */\n\tmanifestDigest: string;\n}\n\n/**\n * Where a federated pack is loaded from, and what proves it is the pack that\n * was approved. The artifact digest identifies the pack that was reviewed; the\n * remote entry is what a shell actually executes, so it needs its own integrity\n * value or the review covers something other than what runs.\n */\nexport interface ComponentPackRemote {\n\t/** Remote entry URL the shell loads. */\n\tentry: string;\n\t/** Subresource-integrity value for that entry, e.g. `sha384-…`. */\n\tintegrity: string;\n\t/** Exposed module path keyed by the component name it provides. */\n\texposes: Record<string, string>;\n}\n\n/** A published component pack version available for resolution. */\nexport interface AvailableComponentPack {\n\tpack: string;\n\tnamespace: string;\n\tversion: string;\n\t/** SHA-256 digest of the published component-pack artifact. */\n\tartifactDigest: string;\n\t/** Present when this pack is delivered as a federated remote. */\n\tremote?: ComponentPackRemote;\n}\n\n// ── Lockfile contracts ──────────────────────────────────────────────────────\n\n/** A resolved capability in the lockfile. */\nexport interface ResolvedCapability {\n\tnamespace: string;\n\tversion: string;\n\trange: string;\n\tmanifestDigest: string;\n\t/** Digest of the exact generated usage-contract document validated for this capability. */\n\tusageContractDigest?: string;\n}\n\n/** A resolved component pack in the lockfile. */\nexport interface ResolvedComponentPack {\n\tpack: string;\n\tnamespace: string;\n\tversion: string;\n\trange: string;\n\tartifactDigest: string;\n\t/** Locked delivery binding, when the pack is a federated remote. */\n\tremote?: ComponentPackRemote;\n}\n\n/** A validated adoption binding in the lockfile. */\nexport interface ResolvedBinding {\n\tcapability: string;\n\tbindingDigest: string;\n\tvalid: boolean;\n\tfindings: BindingFinding[];\n}\n\n/**\n * The deterministic, resolved output of assembling a vertical. Every version\n * is locked, every binding is validated, and the whole document carries a\n * canonical digest so two builds with the same inputs produce the same lockfile.\n */\nexport interface AssemblyLockfile {\n\tformatVersion: typeof ASSEMBLY_LOCKFILE_FORMAT_VERSION;\n\tapplication: string;\n\t/** SHA-256 of this lockfile's canonical resolved body, excluding this field. */\n\tassemblyDigest: string;\n\tcapabilities: ResolvedCapability[];\n\tcomponentPacks: ResolvedComponentPack[];\n\tbindings: ResolvedBinding[];\n}\n\n// ── Findings ─────────────────────────────────────────────────────────────────\n\nexport type AssemblyFindingCode =\n\t| \"duplicate_capability\"\n\t| \"duplicate_component_pack\"\n\t| \"unresolved_capability\"\n\t| \"unresolved_component_pack\"\n\t| \"invalid_range\"\n\t| \"unknown_contract_for_binding\"\n\t| \"contract_namespace_mismatch\"\n\t| \"contract_manifest_digest_mismatch\"\n\t| \"binding_validation_failed\"\n\t| \"invalid_contract\"\n\t| \"invalid_component_pack\"\n\t| \"missing_component_pack_manifest\"\n\t| \"component_pack_artifact_digest_mismatch\"\n\t| \"duplicate_contract\";\n\nexport interface AssemblyFinding {\n\tcode: AssemblyFindingCode;\n\tpath: string;\n\tmessage: string;\n}\n\nexport interface AssemblyResult {\n\tlockfile: AssemblyLockfile | undefined;\n\tfindings: AssemblyFinding[];\n}\n\n// ── Stable serialization ───────────────────────────────────────────────────\n\nfunction sortJson(value: unknown): unknown {\n\tif (Array.isArray(value)) return value.map(sortJson);\n\tif (value && typeof value === \"object\") {\n\t\treturn Object.fromEntries(\n\t\t\tObject.entries(value as Record<string, unknown>)\n\t\t\t\t.sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))\n\t\t\t\t.map(([key, child]) => [key, sortJson(child)]),\n\t\t);\n\t}\n\treturn value;\n}\n\nfunction stableStringify(value: unknown): string {\n\treturn JSON.stringify(sortJson(value));\n}\n\nfunction assemblyDigest(value: unknown): string {\n\treturn createHash(\"sha256\").update(stableStringify(value)).digest(\"hex\");\n}\n\n/** Compute the digest stored for an exact generated usage-contract document. */\nexport function computeUsageContractDocumentDigest(document: UsageContractDocument): string {\n\tassertUsageContractDocument(document);\n\treturn assemblyDigest(document);\n}\n\nfunction lockfileDigestBody(lockfile: Omit<AssemblyLockfile, \"assemblyDigest\">): unknown {\n\treturn {\n\t\tformatVersion: lockfile.formatVersion,\n\t\tapplication: lockfile.application,\n\t\tcapabilities: lockfile.capabilities,\n\t\tcomponentPacks: lockfile.componentPacks,\n\t\tbindings: lockfile.bindings,\n\t};\n}\n\n// ── Structural validation ───────────────────────────────────────────────────\n\nfunction fail(path: string, message: string): never {\n\tthrow new Error(`Assembly manifest ${path} ${message}.`);\n}\n\nfunction requireString(value: unknown, path: string): string {\n\tif (typeof value !== \"string\" || !value.trim()) fail(path, \"must be a non-empty string\");\n\treturn value;\n}\n\nfunction requireArray(value: unknown, path: string): unknown[] {\n\tif (!Array.isArray(value)) fail(path, \"must be an array\");\n\treturn value;\n}\n\n/**\n * Structural validation of an assembly manifest. Checks the document's own\n * shape; does not resolve ranges or validate contracts/bindings.\n */\nexport function assertAssemblyManifest(value: unknown, path = \"assembly\"): asserts value is AssemblyManifest {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) fail(path, \"must be an object\");\n\tconst manifest = value as Record<string, unknown>;\n\tif (manifest.formatVersion !== ASSEMBLY_MANIFEST_FORMAT_VERSION) {\n\t\tfail(`${path}.formatVersion`, `must be ${ASSEMBLY_MANIFEST_FORMAT_VERSION}, received ${JSON.stringify(manifest.formatVersion)}`);\n\t}\n\tif (!/^[a-z][a-z0-9-]*$/.test(requireString(manifest.application, `${path}.application`))) {\n\t\tfail(`${path}.application`, \"must be lowercase letters, numbers and hyphens\");\n\t}\n\trequireArray(manifest.capabilities, `${path}.capabilities`).forEach((entry, index) => {\n\t\tconst capability = entry as Record<string, unknown>;\n\t\trequireString(capability?.namespace, `${path}.capabilities[${index}].namespace`);\n\t\trequireString(capability?.range, `${path}.capabilities[${index}].range`);\n\t});\n\trequireArray(manifest.componentPacks, `${path}.componentPacks`).forEach((entry, index) => {\n\t\tconst pack = entry as Record<string, unknown>;\n\t\trequireString(pack?.pack, `${path}.componentPacks[${index}].pack`);\n\t\trequireString(pack?.namespace, `${path}.componentPacks[${index}].namespace`);\n\t\trequireString(pack?.range, `${path}.componentPacks[${index}].range`);\n\t});\n\trequireArray(manifest.bindings, `${path}.bindings`).forEach((entry, index) => {\n\t\tconst binding = entry as Record<string, unknown>;\n\t\trequireString(binding?.capability, `${path}.bindings[${index}].capability`);\n\t\tassertAdoptionBinding(binding?.binding, `${path}.bindings[${index}].binding`);\n\t});\n\trequireArray(manifest.contracts, `${path}.contracts`).forEach((entry, index) => {\n\t\tconst contract = entry as Record<string, unknown>;\n\t\trequireString(contract?.namespace, `${path}.contracts[${index}].namespace`);\n\t\ttry {\n\t\t\tassertUsageContractDocument(contract?.document);\n\t\t} catch (error) {\n\t\t\tfail(`${path}.contracts[${index}].document`, error instanceof Error ? error.message : String(error));\n\t\t}\n\t});\n}\n\n/**\n * Structural validation of a component pack manifest.\n */\nexport function assertComponentPackManifest(value: unknown, path = \"pack\"): asserts value is ComponentPackManifest {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) fail(path, \"must be an object\");\n\tconst pack = value as Record<string, unknown>;\n\trequireString(pack.pack, `${path}.pack`);\n\trequireString(pack.namespace, `${path}.namespace`);\n\trequireString(pack.version, `${path}.version`);\n\tif (!/^\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?$/.test(pack.version as string)) {\n\t\tfail(`${path}.version`, \"must be a semver version\");\n\t}\n\tif (!pack.components || typeof pack.components !== \"object\" || Array.isArray(pack.components)) {\n\t\tfail(`${path}.components`, \"must be an object\");\n\t}\n\tif (!/^[0-9a-f]{64}$/.test(requireString(pack.artifactDigest, `${path}.artifactDigest`))) {\n\t\tfail(`${path}.artifactDigest`, \"must be a lowercase SHA-256 digest\");\n\t}\n}\n\n/**\n * Validate a resolved lockfile and verify that its digest still identifies its\n * exact application, capability, pack, contract, and binding content.\n */\nexport function assertAssemblyLockfile(value: unknown, path = \"lockfile\"): asserts value is AssemblyLockfile {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) fail(path, \"must be an object\");\n\tconst lockfile = value as Record<string, unknown>;\n\tif (lockfile.formatVersion !== ASSEMBLY_LOCKFILE_FORMAT_VERSION) {\n\t\tfail(`${path}.formatVersion`, `must be ${ASSEMBLY_LOCKFILE_FORMAT_VERSION}, received ${JSON.stringify(lockfile.formatVersion)}`);\n\t}\n\tif (!/^[a-z][a-z0-9-]*$/.test(requireString(lockfile.application, `${path}.application`))) {\n\t\tfail(`${path}.application`, \"must be lowercase letters, numbers and hyphens\");\n\t}\n\tif (!/^[0-9a-f]{64}$/.test(requireString(lockfile.assemblyDigest, `${path}.assemblyDigest`))) {\n\t\tfail(`${path}.assemblyDigest`, \"must be a lowercase SHA-256 digest\");\n\t}\n\tconst capabilities = requireArray(lockfile.capabilities, `${path}.capabilities`);\n\tconst componentPacks = requireArray(lockfile.componentPacks, `${path}.componentPacks`);\n\tconst bindings = requireArray(lockfile.bindings, `${path}.bindings`);\n\tconst seenCapabilities = new Set<string>();\n\tfor (const [index, entry] of capabilities.entries()) {\n\t\tconst capability = entry as Record<string, unknown>;\n\t\tconst namespace = String(capability?.namespace);\n\t\tif (seenCapabilities.has(namespace)) {\n\t\t\tfail(`${path}.capabilities[${index}]`, `declares capability \"${namespace}\" a second time`);\n\t\t}\n\t\tseenCapabilities.add(namespace);\n\t\trequireString(capability?.namespace, `${path}.capabilities[${index}].namespace`);\n\t\trequireString(capability?.version, `${path}.capabilities[${index}].version`);\n\t\trequireString(capability?.range, `${path}.capabilities[${index}].range`);\n\t\tif (!/^[0-9a-f]{64}$/.test(requireString(capability?.manifestDigest, `${path}.capabilities[${index}].manifestDigest`))) {\n\t\t\tfail(`${path}.capabilities[${index}].manifestDigest`, \"must be a lowercase SHA-256 digest\");\n\t\t}\n\t\tif (capability?.usageContractDigest !== undefined &&\n\t\t\t!/^[0-9a-f]{64}$/.test(requireString(capability.usageContractDigest, `${path}.capabilities[${index}].usageContractDigest`))) {\n\t\t\tfail(`${path}.capabilities[${index}].usageContractDigest`, \"must be a lowercase SHA-256 digest\");\n\t\t}\n\t}\n\tconst seenPackIdentities = new Set<string>();\n\tfor (const [index, entry] of componentPacks.entries()) {\n\t\tconst pack = entry as Record<string, unknown>;\n\t\trequireString(pack?.pack, `${path}.componentPacks[${index}].pack`);\n\t\tconst identity = `${String(pack?.namespace)}/${String(pack?.pack)}`;\n\t\tif (seenPackIdentities.has(identity)) {\n\t\t\tfail(`${path}.componentPacks[${index}]`, `declares component pack \"${identity}\" a second time; first-match resolution would make the choice arbitrary`);\n\t\t}\n\t\tseenPackIdentities.add(identity);\n\t\trequireString(pack?.namespace, `${path}.componentPacks[${index}].namespace`);\n\t\trequireString(pack?.version, `${path}.componentPacks[${index}].version`);\n\t\trequireString(pack?.range, `${path}.componentPacks[${index}].range`);\n\t\tif (!/^[0-9a-f]{64}$/.test(requireString(pack?.artifactDigest, `${path}.componentPacks[${index}].artifactDigest`))) {\n\t\t\tfail(`${path}.componentPacks[${index}].artifactDigest`, \"must be a lowercase SHA-256 digest\");\n\t\t}\n\t\tif (pack?.remote !== undefined) {\n\t\t\tconst remotePath = `${path}.componentPacks[${index}].remote`;\n\t\t\tconst remote = pack.remote as Record<string, unknown>;\n\t\t\tif (remote === null || typeof remote !== \"object\" || Array.isArray(remote)) fail(remotePath, \"must be an object\");\n\t\t\trequireString(remote.entry, `${remotePath}.entry`);\n\t\t\t// Integrity is the only thing standing between an approved pack and\n\t\t\t// whatever the remote entry happens to serve at load time.\n\t\t\tif (!/^sha(256|384|512)-[A-Za-z0-9+/]+={0,2}$/.test(requireString(remote.integrity, `${remotePath}.integrity`))) {\n\t\t\t\tfail(`${remotePath}.integrity`, \"must be a subresource-integrity value, e.g. \\\"sha384-…\\\"\");\n\t\t\t}\n\t\t\tconst exposes = remote.exposes as Record<string, unknown>;\n\t\t\tif (exposes === null || typeof exposes !== \"object\" || Array.isArray(exposes)) {\n\t\t\t\tfail(`${remotePath}.exposes`, \"must be an object\");\n\t\t\t}\n\t\t\tfor (const [component, modulePath] of Object.entries(exposes)) {\n\t\t\t\trequireString(modulePath, `${remotePath}.exposes.${component}`);\n\t\t\t}\n\t\t}\n\t}\n\tfor (const [index, entry] of bindings.entries()) {\n\t\tconst binding = entry as Record<string, unknown>;\n\t\trequireString(binding?.capability, `${path}.bindings[${index}].capability`);\n\t\tif (!/^[0-9a-f]{64}$/.test(requireString(binding?.bindingDigest, `${path}.bindings[${index}].bindingDigest`))) {\n\t\t\tfail(`${path}.bindings[${index}].bindingDigest`, \"must be a lowercase SHA-256 digest\");\n\t\t}\n\t\tif (binding?.valid !== true) fail(`${path}.bindings[${index}].valid`, \"must be true\");\n\t\trequireArray(binding?.findings, `${path}.bindings[${index}].findings`);\n\t}\n\tconst expected = assemblyDigest(lockfileDigestBody({\n\t\tformatVersion: ASSEMBLY_LOCKFILE_FORMAT_VERSION,\n\t\tapplication: lockfile.application as string,\n\t\tcapabilities: capabilities as unknown as ResolvedCapability[],\n\t\tcomponentPacks: componentPacks as unknown as ResolvedComponentPack[],\n\t\tbindings: bindings as unknown as ResolvedBinding[],\n\t}));\n\tif (lockfile.assemblyDigest !== expected) {\n\t\tfail(`${path}.assemblyDigest`, `does not match resolved lockfile content; expected \"${expected}\"`);\n\t}\n}\n\n/**\n * Verify that the capability artifacts loaded by a runtime are exactly those\n * approved by an integrity-checked assembly lockfile.\n */\nexport function assertAssemblyRuntimeCompatible(\n\tlockfile: AssemblyLockfile,\n\tloadedCapabilities: readonly AvailableCapability[],\n): void {\n\tassertAssemblyLockfile(lockfile);\n\tconst loadedByNamespace = new Map<string, AvailableCapability>();\n\tfor (const loaded of loadedCapabilities) {\n\t\tif (loadedByNamespace.has(loaded.namespace)) {\n\t\t\tthrow new Error(`Loaded capability \"${loaded.namespace}\" is duplicated.`);\n\t\t}\n\t\tloadedByNamespace.set(loaded.namespace, loaded);\n\t}\n\tfor (const approved of lockfile.capabilities) {\n\t\tconst loaded = loadedByNamespace.get(approved.namespace);\n\t\tif (!loaded ||\n\t\t\tloaded.version !== approved.version ||\n\t\t\tloaded.manifestDigest !== approved.manifestDigest) {\n\t\t\tthrow new Error(\n\t\t\t\t`Loaded capability \"${approved.namespace}\" does not match approved capability ` +\n\t\t\t\t`\"${approved.namespace}@${approved.version}\" with manifest digest \"${approved.manifestDigest}\".`,\n\t\t\t);\n\t\t}\n\t}\n\tfor (const loaded of loadedCapabilities) {\n\t\tif (!lockfile.capabilities.some((approved) => approved.namespace === loaded.namespace)) {\n\t\t\tthrow new Error(`Loaded capability \"${loaded.namespace}\" is not approved by assembly \"${lockfile.assemblyDigest}\".`);\n\t\t}\n\t}\n}\n\n// ── Resolution ───────────────────────────────────────────────────────────────\n\nexport interface ResolveAssemblyInput {\n\tmanifest: AssemblyManifest;\n\t/** Published capability versions available for resolution. */\n\tcapabilities: AvailableCapability[];\n\t/** Published component pack versions available for resolution. */\n\tcomponentPacks: AvailableComponentPack[];\n\t/** Component pack manifests for binding validation. */\n\tpackManifests?: ComponentPackManifest[];\n\t/** Core component vocabulary every renderer implements. */\n\tcoreComponents?: readonly string[];\n\t/** Contracts available for cross-capability fragment resolution. */\n\tavailableContracts?: UsageContract[];\n}\n\n/**\n * Resolve an assembly manifest into a deterministic lockfile. This is the\n * single build gate: it resolves version ranges, rejects unresolved or\n * duplicate capability identities, validates usage contracts, component\n * packs, and adoption bindings, and produces a lockfile with a canonical\n * digest.\n *\n * Returns every finding rather than throwing, so one CI run tells a vertical\n * everything it has to change. Use {@link assertAssemblyResolved} to throw\n * on the first invalid result.\n */\nexport function resolveAssembly(input: ResolveAssemblyInput): AssemblyResult {\n\tassertAssemblyManifest(input.manifest);\n\tconst findings: AssemblyFinding[] = [];\n\tconst add = (code: AssemblyFindingCode, path: string, message: string): void => {\n\t\tfindings.push({ code, path, message });\n\t};\n\n\t// ── Duplicate capability identities ──────────────────────────────────\n\tconst capabilityNamespaces = new Set<string>();\n\tfor (const capability of input.manifest.capabilities) {\n\t\tif (capabilityNamespaces.has(capability.namespace)) {\n\t\t\tadd(\"duplicate_capability\", `assembly.capabilities.${capability.namespace}`,\n\t\t\t\t`capability \"${capability.namespace}\" is declared more than once`);\n\t\t}\n\t\tcapabilityNamespaces.add(capability.namespace);\n\t}\n\n\t// ── Duplicate component pack identities ──────────────────────────────\n\tconst packKeys = new Set<string>();\n\tfor (const pack of input.manifest.componentPacks) {\n\t\tconst key = `${pack.namespace}/${pack.pack}`;\n\t\tif (packKeys.has(key)) {\n\t\t\tadd(\"duplicate_component_pack\", `assembly.componentPacks.${key}`,\n\t\t\t\t`component pack \"${key}\" is declared more than once`);\n\t\t}\n\t\tpackKeys.add(key);\n\t}\n\n\t// ── Duplicate contracts ──────────────────────────────────────────────\n\tconst contractNamespaces = new Set<string>();\n\tfor (const contract of input.manifest.contracts) {\n\t\tif (contractNamespaces.has(contract.namespace)) {\n\t\t\tadd(\"duplicate_contract\", `assembly.contracts.${contract.namespace}`,\n\t\t\t\t`contract for \"${contract.namespace}\" is declared more than once`);\n\t\t}\n\t\tcontractNamespaces.add(contract.namespace);\n\t}\n\n\t// ── Resolve capability ranges ────────────────────────────────────────\n\tconst resolvedCapabilities: ResolvedCapability[] = [];\n\tconst capabilitiesByNamespace = new Map<string, AvailableCapability[]>();\n\tfor (const available of input.capabilities) {\n\t\tconst list = capabilitiesByNamespace.get(available.namespace) ?? [];\n\t\tlist.push(available);\n\t\tcapabilitiesByNamespace.set(available.namespace, list);\n\t}\n\n\tfor (const ref of input.manifest.capabilities) {\n\t\tconst range = parseSemverRange(ref.range);\n\t\tif (!range) {\n\t\t\tadd(\"invalid_range\", `assembly.capabilities.${ref.namespace}.range`,\n\t\t\t\t`range \"${ref.range}\" is not a valid semver range`);\n\t\t\tcontinue;\n\t\t}\n\t\tconst available = capabilitiesByNamespace.get(ref.namespace) ?? [];\n\t\tconst versions = available.map((entry) => entry.version);\n\t\tconst resolved = resolveVersionRange(range, versions);\n\t\tif (!resolved) {\n\t\t\tadd(\"unresolved_capability\", `assembly.capabilities.${ref.namespace}`,\n\t\t\t\t`no available version of \"${ref.namespace}\" satisfies range \"${ref.range}\"`);\n\t\t\tcontinue;\n\t\t}\n\t\tconst matched = available.find((entry) => entry.version === resolved)!;\n\t\tresolvedCapabilities.push({\n\t\t\tnamespace: ref.namespace,\n\t\t\tversion: resolved,\n\t\t\trange: ref.range,\n\t\t\tmanifestDigest: matched.manifestDigest,\n\t\t});\n\t}\n\n\t// ── Resolve component pack ranges ────────────────────────────────────\n\tconst resolvedPacks: ResolvedComponentPack[] = [];\n\tconst packsByKey = new Map<string, AvailableComponentPack[]>();\n\tfor (const available of input.componentPacks) {\n\t\tconst key = `${available.namespace}/${available.pack}`;\n\t\tconst list = packsByKey.get(key) ?? [];\n\t\tlist.push(available);\n\t\tpacksByKey.set(key, list);\n\t}\n\n\tfor (const ref of input.manifest.componentPacks) {\n\t\tconst range = parseSemverRange(ref.range);\n\t\tif (!range) {\n\t\t\tadd(\"invalid_range\", `assembly.componentPacks.${ref.namespace}/${ref.pack}.range`,\n\t\t\t\t`range \"${ref.range}\" is not a valid semver range`);\n\t\t\tcontinue;\n\t\t}\n\t\tconst key = `${ref.namespace}/${ref.pack}`;\n\t\tconst available = packsByKey.get(key) ?? [];\n\t\tconst versions = available.map((entry) => entry.version);\n\t\tconst resolved = resolveVersionRange(range, versions);\n\t\tif (!resolved) {\n\t\t\tadd(\"unresolved_component_pack\", `assembly.componentPacks.${key}`,\n\t\t\t\t`no available version of pack \"${key}\" satisfies range \"${ref.range}\"`);\n\t\t\tcontinue;\n\t\t}\n\t\tconst matched = available.find((entry) => entry.version === resolved)!;\n\t\tresolvedPacks.push({\n\t\t\tpack: ref.pack,\n\t\t\tnamespace: ref.namespace,\n\t\t\tversion: resolved,\n\t\t\trange: ref.range,\n\t\t\tartifactDigest: matched.artifactDigest,\n\t\t\t...(matched.remote ? { remote: matched.remote } : {}),\n\t\t});\n\t}\n\n\t// ── Validate component pack manifests ───────────────────────────────\n\tconst packManifests = input.packManifests ?? [];\n\tfor (const pack of packManifests) {\n\t\ttry {\n\t\t\tassertComponentPackManifest(pack);\n\t\t} catch (error) {\n\t\t\tadd(\"invalid_component_pack\", `packManifests.${pack.namespace}/${pack.pack}`,\n\t\t\t\terror instanceof Error ? error.message : String(error));\n\t\t}\n\t}\n\tconst resolvedPackManifests: ComponentPackManifest[] = [];\n\tfor (const resolved of resolvedPacks) {\n\t\tconst key = `${resolved.namespace}/${resolved.pack}`;\n\t\tconst manifest = packManifests.find((candidate) =>\n\t\t\tcandidate.namespace === resolved.namespace &&\n\t\t\tcandidate.pack === resolved.pack &&\n\t\t\tcandidate.version === resolved.version\n\t\t);\n\t\tif (!manifest) {\n\t\t\tadd(\"missing_component_pack_manifest\", `assembly.componentPacks.${key}`,\n\t\t\t\t`resolved pack \"${key}@${resolved.version}\" has no matching component-pack manifest`);\n\t\t\tcontinue;\n\t\t}\n\t\tif (manifest.artifactDigest !== resolved.artifactDigest) {\n\t\t\tadd(\"component_pack_artifact_digest_mismatch\", `assembly.componentPacks.${key}.artifactDigest`,\n\t\t\t\t`component-pack manifest digest \"${manifest.artifactDigest}\" does not match resolved artifact digest \"${resolved.artifactDigest}\"`);\n\t\t\tcontinue;\n\t\t}\n\t\tresolvedPackManifests.push(manifest);\n\t}\n\n\t// ── Validate contracts ──────────────────────────────────────────────\n\tconst contractsByNamespace = new Map<string, UsageContract>();\n\tfor (const entry of input.manifest.contracts) {\n\t\ttry {\n\t\t\tassertUsageContractDocument(entry.document);\n\t\t} catch (error) {\n\t\t\tadd(\"invalid_contract\", `assembly.contracts.${entry.namespace}`,\n\t\t\t\terror instanceof Error ? error.message : String(error));\n\t\t\tcontinue;\n\t\t}\n\t\tif (entry.document.capability.namespace !== entry.namespace) {\n\t\t\tadd(\"contract_namespace_mismatch\", `assembly.contracts.${entry.namespace}`,\n\t\t\t\t`contract namespace \"${entry.document.capability.namespace}\" does not match assembly namespace \"${entry.namespace}\"`);\n\t\t}\n\t\tconst resolved = resolvedCapabilities.find((capability) => capability.namespace === entry.namespace);\n\t\tif (resolved && entry.document.manifestDigest !== resolved.manifestDigest) {\n\t\t\tadd(\"contract_manifest_digest_mismatch\", `assembly.contracts.${entry.namespace}.manifestDigest`,\n\t\t\t\t`contract manifest digest \"${entry.document.manifestDigest}\" does not match resolved capability digest \"${resolved.manifestDigest}\"`);\n\t\t} else if (resolved) {\n\t\t\tresolved.usageContractDigest = computeUsageContractDocumentDigest(entry.document);\n\t\t}\n\t\tcontractsByNamespace.set(entry.namespace, entry.document.capability);\n\t}\n\n\t// ── Validate bindings ───────────────────────────────────────────────\n\tconst resolvedBindings: ResolvedBinding[] = [];\n\tfor (const entry of input.manifest.bindings) {\n\t\tconst contract = contractsByNamespace.get(entry.capability);\n\t\tif (!contract) {\n\t\t\tadd(\"unknown_contract_for_binding\", `assembly.bindings.${entry.capability}`,\n\t\t\t\t`binding targets capability \"${entry.capability}\" but no contract for it is declared`);\n\t\t\tresolvedBindings.push({\n\t\t\t\tcapability: entry.capability,\n\t\t\t\tbindingDigest: assemblyDigest(entry.binding),\n\t\t\t\tvalid: false,\n\t\t\t\tfindings: [],\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\tconst result = validateBinding({\n\t\t\tcontract,\n\t\t\tbinding: entry.binding,\n\t\t\tpacks: resolvedPackManifests,\n\t\t\tcoreComponents: input.coreComponents ?? [],\n\t\t\tavailableContracts: input.availableContracts ?? [],\n\t\t});\n\t\tresolvedBindings.push({\n\t\t\tcapability: entry.capability,\n\t\t\tbindingDigest: assemblyDigest(entry.binding),\n\t\t\tvalid: result.valid,\n\t\t\tfindings: result.findings,\n\t\t});\n\t\tif (!result.valid) {\n\t\t\tfor (const finding of result.findings) {\n\t\t\t\tadd(\"binding_validation_failed\", `assembly.bindings.${entry.capability}.${finding.path}`,\n\t\t\t\t\tfinding.message);\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── Produce lockfile ─────────────────────────────────────────────────\n\tconst capabilities = [...resolvedCapabilities].sort((a, b) =>\n\t\t\ta.namespace < b.namespace ? -1 : a.namespace > b.namespace ? 1 : 0,\n\t\t);\n\tconst componentPacks = [...resolvedPacks].sort((a, b) => {\n\t\t\tconst key = (e: ResolvedComponentPack) => `${e.namespace}/${e.pack}`;\n\t\t\treturn key(a) < key(b) ? -1 : key(a) > key(b) ? 1 : 0;\n\t\t});\n\tconst bindings = [...resolvedBindings].sort((a, b) =>\n\t\t\ta.capability < b.capability ? -1 : a.capability > b.capability ? 1 : 0,\n\t\t);\n\tconst lockfileBody = {\n\t\tformatVersion: ASSEMBLY_LOCKFILE_FORMAT_VERSION,\n\t\tapplication: input.manifest.application,\n\t\tcapabilities,\n\t\tcomponentPacks,\n\t\tbindings,\n\t};\n\tconst lockfile: AssemblyLockfile = {\n\t\tformatVersion: ASSEMBLY_LOCKFILE_FORMAT_VERSION,\n\t\tapplication: input.manifest.application,\n\t\tassemblyDigest: assemblyDigest(lockfileDigestBody(lockfileBody)),\n\t\tcapabilities,\n\t\tcomponentPacks,\n\t\tbindings,\n\t};\n\n\treturn {\n\t\tlockfile: findings.length === 0 ? lockfile : undefined,\n\t\tfindings,\n\t};\n}\n\n/**\n * Throw with every finding listed, for use as a build step. Returns the\n * lockfile when valid.\n */\nexport function assertAssemblyResolved(input: ResolveAssemblyInput): AssemblyLockfile {\n\tconst result = resolveAssembly(input);\n\tif (result.findings.length === 0) return result.lockfile!;\n\tthrow new Error([\n\t\t`Assembly \"${input.manifest.application}\" could not be resolved:`,\n\t\t...result.findings.map((finding) => ` - [${finding.code}] ${finding.path}: ${finding.message}`),\n\t].join(\"\\n\"));\n}\n\n/**\n * Validate an assembly manifest's bindings as a standalone build gate,\n * without resolving versions. Useful when versions are already locked and\n * only the binding contracts need checking.\n */\nexport function validateAssemblyBindings(input: {\n\tmanifest: AssemblyManifest;\n\tpackManifests?: ComponentPackManifest[];\n\tcoreComponents?: readonly string[];\n\tavailableContracts?: UsageContract[];\n}): AssemblyResult {\n\tassertAssemblyManifest(input.manifest);\n\tconst findings: AssemblyFinding[] = [];\n\tconst add = (code: AssemblyFindingCode, path: string, message: string): void => {\n\t\tfindings.push({ code, path, message });\n\t};\n\n\tconst contractsByNamespace = new Map<string, UsageContract>();\n\tfor (const entry of input.manifest.contracts) {\n\t\ttry {\n\t\t\tassertUsageContractDocument(entry.document);\n\t\t} catch (error) {\n\t\t\tadd(\"invalid_contract\", `assembly.contracts.${entry.namespace}`,\n\t\t\t\terror instanceof Error ? error.message : String(error));\n\t\t\tcontinue;\n\t\t}\n\t\tcontractsByNamespace.set(entry.namespace, entry.document.capability);\n\t}\n\n\tconst packManifests = input.packManifests ?? [];\n\tfor (const entry of input.manifest.bindings) {\n\t\tconst contract = contractsByNamespace.get(entry.capability);\n\t\tif (!contract) {\n\t\t\tadd(\"unknown_contract_for_binding\", `assembly.bindings.${entry.capability}`,\n\t\t\t\t`binding targets capability \"${entry.capability}\" but no contract for it is declared`);\n\t\t\tcontinue;\n\t\t}\n\t\ttry {\n\t\t\tassertBindingValid({\n\t\t\t\tcontract,\n\t\t\t\tbinding: entry.binding,\n\t\t\t\tpacks: packManifests,\n\t\t\t\tcoreComponents: input.coreComponents ?? [],\n\t\t\t\tavailableContracts: input.availableContracts ?? [],\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tadd(\"binding_validation_failed\", `assembly.bindings.${entry.capability}`,\n\t\t\t\terror instanceof Error ? error.message : String(error));\n\t\t}\n\t}\n\n\treturn {\n\t\tlockfile: undefined,\n\t\tfindings,\n\t};\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../index.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport {\n\tassertAdoptionBinding,\n\tassertBindingValid,\n\tvalidateBinding,\n\ttype AdoptionBinding,\n\ttype BindingFinding,\n\ttype ComponentPackManifest,\n} from \"@fabricorg/adoption-bindings\";\nimport {\n\tassertUsageContract,\n\tassertUsageContractDocument,\n\ttype UsageContract,\n\ttype UsageContractDocument,\n} from \"@fabricorg/gen-capability\";\n\n/**\n * Version of the assembly manifest document. A vertical negotiates on this, not\n * on this package's version, and it moves only when the serialized shape changes.\n */\nexport const ASSEMBLY_MANIFEST_FORMAT_VERSION = 2 as const;\n\n/**\n * Version of the resolved lockfile document. Bump when the serialized shape\n * changes in a way a consumer must detect.\n */\nexport const ASSEMBLY_LOCKFILE_FORMAT_VERSION = 2 as const;\n\n// ── Semver range resolution (zero-dependency) ───────────────────────────────\n\ninterface SemverVersion {\n\tmajor: number;\n\tminor: number;\n\tpatch: number;\n\tprerelease: string[];\n}\n\nfunction parseSemver(input: string): SemverVersion | undefined {\n\tconst match = /^(\\d+)\\.(\\d+)\\.(\\d+)(?:-([0-9A-Za-z.-]+))?$/.exec(input.trim());\n\tif (!match) return undefined;\n\treturn {\n\t\tmajor: Number(match[1]),\n\t\tminor: Number(match[2]),\n\t\tpatch: Number(match[3]),\n\t\tprerelease: match[4] ? match[4].split(\".\") : [],\n\t};\n}\n\nfunction comparePrerelease(a: string[], b: string[]): number {\n\t// No prerelease > has prerelease (release > pre-release).\n\tif (a.length === 0 && b.length === 0) return 0;\n\tif (a.length === 0) return 1;\n\tif (b.length === 0) return -1;\n\tfor (let i = 0; i < Math.max(a.length, b.length); i++) {\n\t\tconst ai = a[i];\n\t\tconst bi = b[i];\n\t\tif (ai === undefined) return -1;\n\t\tif (bi === undefined) return 1;\n\t\tconst an = /^\\d+$/.test(ai);\n\t\tconst bn = /^\\d+$/.test(bi);\n\t\tif (an && bn) {\n\t\t\tconst diff = Number(ai) - Number(bi);\n\t\t\tif (diff !== 0) return diff;\n\t\t} else if (an) {\n\t\t\treturn -1;\n\t\t} else if (bn) {\n\t\t\treturn 1;\n\t\t} else {\n\t\t\tif (ai < bi) return -1;\n\t\t\tif (ai > bi) return 1;\n\t\t}\n\t}\n\treturn 0;\n}\n\nfunction compareSemver(a: SemverVersion, b: SemverVersion): number {\n\tif (a.major !== b.major) return a.major - b.major;\n\tif (a.minor !== b.minor) return a.minor - b.minor;\n\tif (a.patch !== b.patch) return a.patch - b.patch;\n\treturn comparePrerelease(a.prerelease, b.prerelease);\n}\n\ntype Comparator = (version: SemverVersion) => boolean;\n\nfunction caretComparator(range: SemverVersion): Comparator {\n\treturn (version) => {\n\t\tif (compareSemver(version, range) < 0) return false;\n\t\tif (version.major !== range.major) return false;\n\t\tif (version.major === 0) {\n\t\t\tif (version.minor !== range.minor) return false;\n\t\t\tif (range.minor === 0 && version.patch !== range.patch) return false;\n\t\t}\n\t\treturn true;\n\t};\n}\n\nfunction tildeComparator(range: SemverVersion): Comparator {\n\treturn (version) => {\n\t\tif (compareSemver(version, range) < 0) return false;\n\t\treturn version.major === range.major && version.minor === range.minor;\n\t};\n}\n\nfunction exactComparator(range: SemverVersion): Comparator {\n\treturn (version) => compareSemver(version, range) === 0;\n}\n\nfunction gteComparator(range: SemverVersion): Comparator {\n\treturn (version) => compareSemver(version, range) >= 0;\n}\n\nfunction gtComparator(range: SemverVersion): Comparator {\n\treturn (version) => compareSemver(version, range) > 0;\n}\n\nfunction lteComparator(range: SemverVersion): Comparator {\n\treturn (version) => compareSemver(version, range) <= 0;\n}\n\nfunction ltComparator(range: SemverVersion): Comparator {\n\treturn (version) => compareSemver(version, range) < 0;\n}\n\nfunction anyComparator(): Comparator {\n\treturn () => true;\n}\n\ninterface ParsedComparator {\n\toperator: string;\n\tcomparator: Comparator;\n\traw: string;\n\trangeVersion: SemverVersion | undefined;\n}\n\nfunction parseComparator(raw: string): ParsedComparator | undefined {\n\tconst trimmed = raw.trim();\n\tif (trimmed === \"*\" || trimmed === \"\") return { operator: \"*\", comparator: anyComparator(), raw: trimmed, rangeVersion: undefined };\n\n\tconst caret = /^(\\^)(\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?)$/.exec(trimmed);\n\tif (caret) {\n\t\tconst version = parseSemver(caret[2]!);\n\t\tif (!version) return undefined;\n\t\treturn { operator: \"^\", comparator: caretComparator(version), raw: trimmed, rangeVersion: version };\n\t}\n\tconst tilde = /^(~)(\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?)$/.exec(trimmed);\n\tif (tilde) {\n\t\tconst version = parseSemver(tilde[2]!);\n\t\tif (!version) return undefined;\n\t\treturn { operator: \"~\", comparator: tildeComparator(version), raw: trimmed, rangeVersion: version };\n\t}\n\tconst op = /^(>=|<=|>|<|=)(\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?)$/.exec(trimmed);\n\tif (op) {\n\t\tconst version = parseSemver(op[2]!);\n\t\tif (!version) return undefined;\n\t\tconst operator = op[1]!;\n\t\tlet comparator: Comparator;\n\t\tswitch (operator) {\n\t\t\tcase \">=\": comparator = gteComparator(version); break;\n\t\t\tcase \"<=\": comparator = lteComparator(version); break;\n\t\t\tcase \">\": comparator = gtComparator(version); break;\n\t\t\tcase \"<\": comparator = ltComparator(version); break;\n\t\t\tdefault: comparator = exactComparator(version); break;\n\t\t}\n\t\treturn { operator, comparator, raw: trimmed, rangeVersion: version };\n\t}\n\tconst bare = /^(\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?)$/.exec(trimmed);\n\tif (bare) {\n\t\tconst version = parseSemver(bare[1]!);\n\t\tif (!version) return undefined;\n\t\treturn { operator: \"=\", comparator: exactComparator(version), raw: trimmed, rangeVersion: version };\n\t}\n\treturn undefined;\n}\n\nfunction comparatorRangeVersion(comparator: ParsedComparator): SemverVersion | undefined {\n\treturn comparator.rangeVersion;\n}\n\n/**\n * A parsed semver range — a conjunction of comparators. Every comparator must\n * be satisfied. This is the subset of npm range syntax that a deterministic\n * resolver needs: `^`, `~`, `>=`, `>`, `<=`, `<`, `=`, exact, and `*`.\n */\nexport interface SemverRange {\n\tcomparators: ParsedComparator[];\n\traw: string;\n}\n\n/**\n * Parse a semver range string into a {@link SemverRange}. Returns `undefined`\n * for an unparseable range rather than throwing, so callers can distinguish\n * \"bad range\" from \"no satisfying version\".\n */\nexport function parseSemverRange(raw: string): SemverRange | undefined {\n\tconst trimmed = raw.trim();\n\tif (!trimmed) return undefined;\n\tconst parts = trimmed.split(/\\s+/);\n\tconst comparators: ParsedComparator[] = [];\n\tfor (const part of parts) {\n\t\tconst parsed = parseComparator(part);\n\t\tif (!parsed) return undefined;\n\t\tcomparators.push(parsed);\n\t}\n\tif (comparators.length === 0) return undefined;\n\treturn { comparators, raw: trimmed };\n}\n\n/**\n * Test whether a version string satisfies a parsed range.\n *\n * Prerelease versions only satisfy a range when a comparator in the range\n * declares a prerelease at the same `[major, minor, patch]` tuple. This\n * follows npm semantics: `^1.0.0` does not match `1.1.0-alpha`, but\n * `^1.0.0-alpha` matches `1.0.0-alpha.2`.\n */\nexport function satisfiesRange(version: string, range: SemverRange): boolean {\n\tconst parsed = parseSemver(version);\n\tif (!parsed) return false;\n\tif (!range.comparators.every((comparator) => comparator.comparator(parsed))) return false;\n\tif (parsed.prerelease.length > 0) {\n\t\treturn range.comparators.some((comparator) => {\n\t\t\tconst rangeVersion = comparatorRangeVersion(comparator);\n\t\t\treturn (\n\t\t\t\trangeVersion !== undefined &&\n\t\t\t\trangeVersion.prerelease.length > 0 &&\n\t\t\t\trangeVersion.major === parsed.major &&\n\t\t\t\trangeVersion.minor === parsed.minor &&\n\t\t\t\trangeVersion.patch === parsed.patch\n\t\t\t);\n\t\t});\n\t}\n\treturn true;\n}\n\n/**\n * Resolve a range against a list of available versions, returning the highest\n * satisfying version. Returns `undefined` when no available version satisfies\n * the range. Deterministic: the same inputs always produce the same result.\n */\nexport function resolveVersionRange(range: SemverRange, available: readonly string[]): string | undefined {\n\tconst parsed = available\n\t\t.map((version) => ({ version, parsed: parseSemver(version) }))\n\t\t.filter((entry): entry is { version: string; parsed: SemverVersion } => entry.parsed !== undefined)\n\t\t.filter((entry) => {\n\t\t\tif (!range.comparators.every((comparator) => comparator.comparator(entry.parsed))) return false;\n\t\t\tif (entry.parsed.prerelease.length > 0) {\n\t\t\t\treturn range.comparators.some((comparator) => {\n\t\t\t\t\tconst rangeVersion = comparatorRangeVersion(comparator);\n\t\t\t\t\treturn (\n\t\t\t\t\t\trangeVersion !== undefined &&\n\t\t\t\t\t\trangeVersion.prerelease.length > 0 &&\n\t\t\t\t\t\trangeVersion.major === entry.parsed.major &&\n\t\t\t\t\t\trangeVersion.minor === entry.parsed.minor &&\n\t\t\t\t\t\trangeVersion.patch === entry.parsed.patch\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn true;\n\t\t})\n\t\t.sort((a, b) => compareSemver(b.parsed, a.parsed));\n\treturn parsed[0]?.version;\n}\n\n// ── Assembly manifest contracts ─────────────────────────────────────────────\n\n/** A capability the vertical assembles, with a version range to resolve. */\nexport interface AssemblyCapabilityReference {\n\tnamespace: string;\n\t/** Semver range, e.g. `^1.0.0`, `>=1.0.0 <2.0.0`, `*`. */\n\trange: string;\n}\n\n/** A component pack the vertical assembles, with a version range to resolve. */\nexport interface AssemblyComponentPackReference {\n\tpack: string;\n\tnamespace: string;\n\trange: string;\n}\n\n/** An adoption binding the vertical declares against a capability. */\nexport interface AssemblyBindingEntry {\n\tcapability: string;\n\tbinding: AdoptionBinding;\n}\n\n/** A usage contract the vertical depends on, supplied inline for validation. */\nexport interface AssemblyContractEntry {\n\tnamespace: string;\n\tdocument: UsageContractDocument;\n}\n\n/**\n * What a vertical assembles: the capabilities it depends on, the component\n * packs it uses, the adoption bindings it declares, and the usage contracts\n * it validates against. This is the build-time input; the lockfile is the\n * resolved output.\n */\nexport interface AssemblyManifest {\n\tformatVersion: typeof ASSEMBLY_MANIFEST_FORMAT_VERSION;\n\t/** Lowercase identifier for the vertical application. */\n\tapplication: string;\n\tcapabilities: AssemblyCapabilityReference[];\n\tcomponentPacks: AssemblyComponentPackReference[];\n\tbindings: AssemblyBindingEntry[];\n\tcontracts: AssemblyContractEntry[];\n}\n\n// ── Available versions for resolution ───────────────────────────────────────\n\n/** A published capability version available for resolution. */\nexport interface AvailableCapability {\n\tnamespace: string;\n\tversion: string;\n\t/** SHA-256 manifest digest from the compiler IR. */\n\tmanifestDigest: string;\n}\n\n/**\n * Where a federated pack is loaded from, and what proves it is the pack that\n * was approved. The artifact digest identifies the pack that was reviewed; the\n * remote entry is what a shell actually executes, so it needs its own integrity\n * value or the review covers something other than what runs.\n */\nexport interface ComponentPackRemote {\n\t/** Remote entry URL the shell loads. */\n\tentry: string;\n\t/** Subresource-integrity value for that entry, e.g. `sha384-…`. */\n\tintegrity: string;\n\t/** Exposed module path keyed by the component name it provides. */\n\texposes: Record<string, string>;\n}\n\n/** A published component pack version available for resolution. */\nexport interface AvailableComponentPack {\n\tpack: string;\n\tnamespace: string;\n\tversion: string;\n\t/** SHA-256 digest of the published component-pack artifact. */\n\tartifactDigest: string;\n\t/** Present when this pack is delivered as a federated remote. */\n\tremote?: ComponentPackRemote;\n}\n\n// ── Lockfile contracts ──────────────────────────────────────────────────────\n\n/** A resolved capability in the lockfile. */\nexport interface ResolvedCapability {\n\tnamespace: string;\n\tversion: string;\n\trange: string;\n\tmanifestDigest: string;\n\t/** Digest of the exact generated usage-contract document validated for this capability. */\n\tusageContractDigest?: string;\n}\n\n/** A resolved component pack in the lockfile. */\nexport interface ResolvedComponentPack {\n\tpack: string;\n\tnamespace: string;\n\tversion: string;\n\trange: string;\n\tartifactDigest: string;\n\t/** Locked delivery binding, when the pack is a federated remote. */\n\tremote?: ComponentPackRemote;\n}\n\n/** A validated adoption binding in the lockfile. */\nexport interface ResolvedBinding {\n\tcapability: string;\n\tbindingDigest: string;\n\tvalid: boolean;\n\tfindings: BindingFinding[];\n}\n\n/**\n * The deterministic, resolved output of assembling a vertical. Every version\n * is locked, every binding is validated, and the whole document carries a\n * canonical digest so two builds with the same inputs produce the same lockfile.\n */\nexport interface AssemblyLockfile {\n\tformatVersion: typeof ASSEMBLY_LOCKFILE_FORMAT_VERSION;\n\tapplication: string;\n\t/** SHA-256 of this lockfile's canonical resolved body, excluding this field. */\n\tassemblyDigest: string;\n\tcapabilities: ResolvedCapability[];\n\tcomponentPacks: ResolvedComponentPack[];\n\tbindings: ResolvedBinding[];\n}\n\n// ── Findings ─────────────────────────────────────────────────────────────────\n\nexport type AssemblyFindingCode =\n\t| \"duplicate_capability\"\n\t| \"duplicate_component_pack\"\n\t| \"unresolved_capability\"\n\t| \"unresolved_component_pack\"\n\t| \"invalid_range\"\n\t| \"unknown_contract_for_binding\"\n\t| \"contract_namespace_mismatch\"\n\t| \"contract_manifest_digest_mismatch\"\n\t| \"binding_validation_failed\"\n\t| \"invalid_contract\"\n\t| \"invalid_component_pack\"\n\t| \"missing_component_pack_manifest\"\n\t| \"component_pack_artifact_digest_mismatch\"\n\t| \"duplicate_contract\";\n\nexport interface AssemblyFinding {\n\tcode: AssemblyFindingCode;\n\tpath: string;\n\tmessage: string;\n}\n\nexport interface AssemblyResult {\n\tlockfile: AssemblyLockfile | undefined;\n\tfindings: AssemblyFinding[];\n}\n\n// ── Stable serialization ───────────────────────────────────────────────────\n\nfunction sortJson(value: unknown): unknown {\n\tif (Array.isArray(value)) return value.map(sortJson);\n\tif (value && typeof value === \"object\") {\n\t\treturn Object.fromEntries(\n\t\t\tObject.entries(value as Record<string, unknown>)\n\t\t\t\t.sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))\n\t\t\t\t.map(([key, child]) => [key, sortJson(child)]),\n\t\t);\n\t}\n\treturn value;\n}\n\nfunction stableStringify(value: unknown): string {\n\treturn JSON.stringify(sortJson(value));\n}\n\nfunction assemblyDigest(value: unknown): string {\n\treturn createHash(\"sha256\").update(stableStringify(value)).digest(\"hex\");\n}\n\n/** Compute the digest stored for an exact generated usage-contract document. */\nexport function computeUsageContractDocumentDigest(document: UsageContractDocument): string {\n\tassertUsageContractDocument(document);\n\treturn assemblyDigest(document);\n}\n\n/**\n * The canonical digest of a lockfile's resolved content.\n *\n * `assertAssemblyLockfile` recomputes this on every load, so publishing it\n * grants nothing an attacker did not already have; it lets tooling and tests\n * construct a self-consistent lockfile instead of hand-fitting a hash. A\n * forged lockfile still fails downstream, because a release binds the assembly\n * digest it was validated against.\n */\nexport function computeAssemblyLockfileDigest(\n\tlockfile: Omit<AssemblyLockfile, \"assemblyDigest\">,\n): string {\n\treturn assemblyDigest(lockfileDigestBody(lockfile));\n}\n\nfunction lockfileDigestBody(lockfile: Omit<AssemblyLockfile, \"assemblyDigest\">): unknown {\n\treturn {\n\t\tformatVersion: lockfile.formatVersion,\n\t\tapplication: lockfile.application,\n\t\tcapabilities: lockfile.capabilities,\n\t\tcomponentPacks: lockfile.componentPacks,\n\t\tbindings: lockfile.bindings,\n\t};\n}\n\n// ── Structural validation ───────────────────────────────────────────────────\n\nfunction fail(path: string, message: string): never {\n\tthrow new Error(`Assembly manifest ${path} ${message}.`);\n}\n\nfunction requireString(value: unknown, path: string): string {\n\tif (typeof value !== \"string\" || !value.trim()) fail(path, \"must be a non-empty string\");\n\treturn value;\n}\n\nfunction requireArray(value: unknown, path: string): unknown[] {\n\tif (!Array.isArray(value)) fail(path, \"must be an array\");\n\treturn value;\n}\n\n/**\n * Structural validation of an assembly manifest. Checks the document's own\n * shape; does not resolve ranges or validate contracts/bindings.\n */\nexport function assertAssemblyManifest(value: unknown, path = \"assembly\"): asserts value is AssemblyManifest {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) fail(path, \"must be an object\");\n\tconst manifest = value as Record<string, unknown>;\n\tif (manifest.formatVersion !== ASSEMBLY_MANIFEST_FORMAT_VERSION) {\n\t\tfail(`${path}.formatVersion`, `must be ${ASSEMBLY_MANIFEST_FORMAT_VERSION}, received ${JSON.stringify(manifest.formatVersion)}`);\n\t}\n\tif (!/^[a-z][a-z0-9-]*$/.test(requireString(manifest.application, `${path}.application`))) {\n\t\tfail(`${path}.application`, \"must be lowercase letters, numbers and hyphens\");\n\t}\n\trequireArray(manifest.capabilities, `${path}.capabilities`).forEach((entry, index) => {\n\t\tconst capability = entry as Record<string, unknown>;\n\t\trequireString(capability?.namespace, `${path}.capabilities[${index}].namespace`);\n\t\trequireString(capability?.range, `${path}.capabilities[${index}].range`);\n\t});\n\trequireArray(manifest.componentPacks, `${path}.componentPacks`).forEach((entry, index) => {\n\t\tconst pack = entry as Record<string, unknown>;\n\t\trequireString(pack?.pack, `${path}.componentPacks[${index}].pack`);\n\t\trequireString(pack?.namespace, `${path}.componentPacks[${index}].namespace`);\n\t\trequireString(pack?.range, `${path}.componentPacks[${index}].range`);\n\t});\n\trequireArray(manifest.bindings, `${path}.bindings`).forEach((entry, index) => {\n\t\tconst binding = entry as Record<string, unknown>;\n\t\trequireString(binding?.capability, `${path}.bindings[${index}].capability`);\n\t\tassertAdoptionBinding(binding?.binding, `${path}.bindings[${index}].binding`);\n\t});\n\trequireArray(manifest.contracts, `${path}.contracts`).forEach((entry, index) => {\n\t\tconst contract = entry as Record<string, unknown>;\n\t\trequireString(contract?.namespace, `${path}.contracts[${index}].namespace`);\n\t\ttry {\n\t\t\tassertUsageContractDocument(contract?.document);\n\t\t} catch (error) {\n\t\t\tfail(`${path}.contracts[${index}].document`, error instanceof Error ? error.message : String(error));\n\t\t}\n\t});\n}\n\n/**\n * Structural validation of a component pack manifest.\n */\nexport function assertComponentPackManifest(value: unknown, path = \"pack\"): asserts value is ComponentPackManifest {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) fail(path, \"must be an object\");\n\tconst pack = value as Record<string, unknown>;\n\trequireString(pack.pack, `${path}.pack`);\n\trequireString(pack.namespace, `${path}.namespace`);\n\trequireString(pack.version, `${path}.version`);\n\tif (!/^\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?$/.test(pack.version as string)) {\n\t\tfail(`${path}.version`, \"must be a semver version\");\n\t}\n\tif (!pack.components || typeof pack.components !== \"object\" || Array.isArray(pack.components)) {\n\t\tfail(`${path}.components`, \"must be an object\");\n\t}\n\tif (!/^[0-9a-f]{64}$/.test(requireString(pack.artifactDigest, `${path}.artifactDigest`))) {\n\t\tfail(`${path}.artifactDigest`, \"must be a lowercase SHA-256 digest\");\n\t}\n}\n\n/**\n * Validate a resolved lockfile and verify that its digest still identifies its\n * exact application, capability, pack, contract, and binding content.\n */\nexport function assertAssemblyLockfile(value: unknown, path = \"lockfile\"): asserts value is AssemblyLockfile {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) fail(path, \"must be an object\");\n\tconst lockfile = value as Record<string, unknown>;\n\tif (lockfile.formatVersion !== ASSEMBLY_LOCKFILE_FORMAT_VERSION) {\n\t\tfail(`${path}.formatVersion`, `must be ${ASSEMBLY_LOCKFILE_FORMAT_VERSION}, received ${JSON.stringify(lockfile.formatVersion)}`);\n\t}\n\tif (!/^[a-z][a-z0-9-]*$/.test(requireString(lockfile.application, `${path}.application`))) {\n\t\tfail(`${path}.application`, \"must be lowercase letters, numbers and hyphens\");\n\t}\n\tif (!/^[0-9a-f]{64}$/.test(requireString(lockfile.assemblyDigest, `${path}.assemblyDigest`))) {\n\t\tfail(`${path}.assemblyDigest`, \"must be a lowercase SHA-256 digest\");\n\t}\n\tconst capabilities = requireArray(lockfile.capabilities, `${path}.capabilities`);\n\tconst componentPacks = requireArray(lockfile.componentPacks, `${path}.componentPacks`);\n\tconst bindings = requireArray(lockfile.bindings, `${path}.bindings`);\n\tconst seenCapabilities = new Set<string>();\n\tfor (const [index, entry] of capabilities.entries()) {\n\t\tconst capability = entry as Record<string, unknown>;\n\t\tconst namespace = String(capability?.namespace);\n\t\tif (seenCapabilities.has(namespace)) {\n\t\t\tfail(`${path}.capabilities[${index}]`, `declares capability \"${namespace}\" a second time`);\n\t\t}\n\t\tseenCapabilities.add(namespace);\n\t\trequireString(capability?.namespace, `${path}.capabilities[${index}].namespace`);\n\t\trequireString(capability?.version, `${path}.capabilities[${index}].version`);\n\t\trequireString(capability?.range, `${path}.capabilities[${index}].range`);\n\t\tif (!/^[0-9a-f]{64}$/.test(requireString(capability?.manifestDigest, `${path}.capabilities[${index}].manifestDigest`))) {\n\t\t\tfail(`${path}.capabilities[${index}].manifestDigest`, \"must be a lowercase SHA-256 digest\");\n\t\t}\n\t\tif (capability?.usageContractDigest !== undefined &&\n\t\t\t!/^[0-9a-f]{64}$/.test(requireString(capability.usageContractDigest, `${path}.capabilities[${index}].usageContractDigest`))) {\n\t\t\tfail(`${path}.capabilities[${index}].usageContractDigest`, \"must be a lowercase SHA-256 digest\");\n\t\t}\n\t}\n\tconst seenPackIdentities = new Set<string>();\n\tfor (const [index, entry] of componentPacks.entries()) {\n\t\tconst pack = entry as Record<string, unknown>;\n\t\trequireString(pack?.pack, `${path}.componentPacks[${index}].pack`);\n\t\tconst identity = `${String(pack?.namespace)}/${String(pack?.pack)}`;\n\t\tif (seenPackIdentities.has(identity)) {\n\t\t\tfail(`${path}.componentPacks[${index}]`, `declares component pack \"${identity}\" a second time; first-match resolution would make the choice arbitrary`);\n\t\t}\n\t\tseenPackIdentities.add(identity);\n\t\trequireString(pack?.namespace, `${path}.componentPacks[${index}].namespace`);\n\t\trequireString(pack?.version, `${path}.componentPacks[${index}].version`);\n\t\trequireString(pack?.range, `${path}.componentPacks[${index}].range`);\n\t\tif (!/^[0-9a-f]{64}$/.test(requireString(pack?.artifactDigest, `${path}.componentPacks[${index}].artifactDigest`))) {\n\t\t\tfail(`${path}.componentPacks[${index}].artifactDigest`, \"must be a lowercase SHA-256 digest\");\n\t\t}\n\t\tif (pack?.remote !== undefined) {\n\t\t\tconst remotePath = `${path}.componentPacks[${index}].remote`;\n\t\t\tconst remote = pack.remote as Record<string, unknown>;\n\t\t\tif (remote === null || typeof remote !== \"object\" || Array.isArray(remote)) fail(remotePath, \"must be an object\");\n\t\t\trequireString(remote.entry, `${remotePath}.entry`);\n\t\t\t// Integrity is the only thing standing between an approved pack and\n\t\t\t// whatever the remote entry happens to serve at load time.\n\t\t\tif (!/^sha(256|384|512)-[A-Za-z0-9+/]+={0,2}$/.test(requireString(remote.integrity, `${remotePath}.integrity`))) {\n\t\t\t\tfail(`${remotePath}.integrity`, \"must be a subresource-integrity value, e.g. \\\"sha384-…\\\"\");\n\t\t\t}\n\t\t\tconst exposes = remote.exposes as Record<string, unknown>;\n\t\t\tif (exposes === null || typeof exposes !== \"object\" || Array.isArray(exposes)) {\n\t\t\t\tfail(`${remotePath}.exposes`, \"must be an object\");\n\t\t\t}\n\t\t\tfor (const [component, modulePath] of Object.entries(exposes)) {\n\t\t\t\trequireString(modulePath, `${remotePath}.exposes.${component}`);\n\t\t\t}\n\t\t}\n\t}\n\tfor (const [index, entry] of bindings.entries()) {\n\t\tconst binding = entry as Record<string, unknown>;\n\t\trequireString(binding?.capability, `${path}.bindings[${index}].capability`);\n\t\tif (!/^[0-9a-f]{64}$/.test(requireString(binding?.bindingDigest, `${path}.bindings[${index}].bindingDigest`))) {\n\t\t\tfail(`${path}.bindings[${index}].bindingDigest`, \"must be a lowercase SHA-256 digest\");\n\t\t}\n\t\tif (binding?.valid !== true) fail(`${path}.bindings[${index}].valid`, \"must be true\");\n\t\trequireArray(binding?.findings, `${path}.bindings[${index}].findings`);\n\t}\n\tconst expected = assemblyDigest(lockfileDigestBody({\n\t\tformatVersion: ASSEMBLY_LOCKFILE_FORMAT_VERSION,\n\t\tapplication: lockfile.application as string,\n\t\tcapabilities: capabilities as unknown as ResolvedCapability[],\n\t\tcomponentPacks: componentPacks as unknown as ResolvedComponentPack[],\n\t\tbindings: bindings as unknown as ResolvedBinding[],\n\t}));\n\tif (lockfile.assemblyDigest !== expected) {\n\t\tfail(`${path}.assemblyDigest`, `does not match resolved lockfile content; expected \"${expected}\"`);\n\t}\n}\n\n/**\n * Verify that the capability artifacts loaded by a runtime are exactly those\n * approved by an integrity-checked assembly lockfile.\n */\nexport function assertAssemblyRuntimeCompatible(\n\tlockfile: AssemblyLockfile,\n\tloadedCapabilities: readonly AvailableCapability[],\n): void {\n\tassertAssemblyLockfile(lockfile);\n\tconst loadedByNamespace = new Map<string, AvailableCapability>();\n\tfor (const loaded of loadedCapabilities) {\n\t\tif (loadedByNamespace.has(loaded.namespace)) {\n\t\t\tthrow new Error(`Loaded capability \"${loaded.namespace}\" is duplicated.`);\n\t\t}\n\t\tloadedByNamespace.set(loaded.namespace, loaded);\n\t}\n\tfor (const approved of lockfile.capabilities) {\n\t\tconst loaded = loadedByNamespace.get(approved.namespace);\n\t\tif (!loaded ||\n\t\t\tloaded.version !== approved.version ||\n\t\t\tloaded.manifestDigest !== approved.manifestDigest) {\n\t\t\tthrow new Error(\n\t\t\t\t`Loaded capability \"${approved.namespace}\" does not match approved capability ` +\n\t\t\t\t`\"${approved.namespace}@${approved.version}\" with manifest digest \"${approved.manifestDigest}\".`,\n\t\t\t);\n\t\t}\n\t}\n\tfor (const loaded of loadedCapabilities) {\n\t\tif (!lockfile.capabilities.some((approved) => approved.namespace === loaded.namespace)) {\n\t\t\tthrow new Error(`Loaded capability \"${loaded.namespace}\" is not approved by assembly \"${lockfile.assemblyDigest}\".`);\n\t\t}\n\t}\n}\n\n// ── Resolution ───────────────────────────────────────────────────────────────\n\nexport interface ResolveAssemblyInput {\n\tmanifest: AssemblyManifest;\n\t/** Published capability versions available for resolution. */\n\tcapabilities: AvailableCapability[];\n\t/** Published component pack versions available for resolution. */\n\tcomponentPacks: AvailableComponentPack[];\n\t/** Component pack manifests for binding validation. */\n\tpackManifests?: ComponentPackManifest[];\n\t/** Core component vocabulary every renderer implements. */\n\tcoreComponents?: readonly string[];\n\t/** Contracts available for cross-capability fragment resolution. */\n\tavailableContracts?: UsageContract[];\n}\n\n/**\n * Resolve an assembly manifest into a deterministic lockfile. This is the\n * single build gate: it resolves version ranges, rejects unresolved or\n * duplicate capability identities, validates usage contracts, component\n * packs, and adoption bindings, and produces a lockfile with a canonical\n * digest.\n *\n * Returns every finding rather than throwing, so one CI run tells a vertical\n * everything it has to change. Use {@link assertAssemblyResolved} to throw\n * on the first invalid result.\n */\nexport function resolveAssembly(input: ResolveAssemblyInput): AssemblyResult {\n\tassertAssemblyManifest(input.manifest);\n\tconst findings: AssemblyFinding[] = [];\n\tconst add = (code: AssemblyFindingCode, path: string, message: string): void => {\n\t\tfindings.push({ code, path, message });\n\t};\n\n\t// ── Duplicate capability identities ──────────────────────────────────\n\tconst capabilityNamespaces = new Set<string>();\n\tfor (const capability of input.manifest.capabilities) {\n\t\tif (capabilityNamespaces.has(capability.namespace)) {\n\t\t\tadd(\"duplicate_capability\", `assembly.capabilities.${capability.namespace}`,\n\t\t\t\t`capability \"${capability.namespace}\" is declared more than once`);\n\t\t}\n\t\tcapabilityNamespaces.add(capability.namespace);\n\t}\n\n\t// ── Duplicate component pack identities ──────────────────────────────\n\tconst packKeys = new Set<string>();\n\tfor (const pack of input.manifest.componentPacks) {\n\t\tconst key = `${pack.namespace}/${pack.pack}`;\n\t\tif (packKeys.has(key)) {\n\t\t\tadd(\"duplicate_component_pack\", `assembly.componentPacks.${key}`,\n\t\t\t\t`component pack \"${key}\" is declared more than once`);\n\t\t}\n\t\tpackKeys.add(key);\n\t}\n\n\t// ── Duplicate contracts ──────────────────────────────────────────────\n\tconst contractNamespaces = new Set<string>();\n\tfor (const contract of input.manifest.contracts) {\n\t\tif (contractNamespaces.has(contract.namespace)) {\n\t\t\tadd(\"duplicate_contract\", `assembly.contracts.${contract.namespace}`,\n\t\t\t\t`contract for \"${contract.namespace}\" is declared more than once`);\n\t\t}\n\t\tcontractNamespaces.add(contract.namespace);\n\t}\n\n\t// ── Resolve capability ranges ────────────────────────────────────────\n\tconst resolvedCapabilities: ResolvedCapability[] = [];\n\tconst capabilitiesByNamespace = new Map<string, AvailableCapability[]>();\n\tfor (const available of input.capabilities) {\n\t\tconst list = capabilitiesByNamespace.get(available.namespace) ?? [];\n\t\tlist.push(available);\n\t\tcapabilitiesByNamespace.set(available.namespace, list);\n\t}\n\n\tfor (const ref of input.manifest.capabilities) {\n\t\tconst range = parseSemverRange(ref.range);\n\t\tif (!range) {\n\t\t\tadd(\"invalid_range\", `assembly.capabilities.${ref.namespace}.range`,\n\t\t\t\t`range \"${ref.range}\" is not a valid semver range`);\n\t\t\tcontinue;\n\t\t}\n\t\tconst available = capabilitiesByNamespace.get(ref.namespace) ?? [];\n\t\tconst versions = available.map((entry) => entry.version);\n\t\tconst resolved = resolveVersionRange(range, versions);\n\t\tif (!resolved) {\n\t\t\tadd(\"unresolved_capability\", `assembly.capabilities.${ref.namespace}`,\n\t\t\t\t`no available version of \"${ref.namespace}\" satisfies range \"${ref.range}\"`);\n\t\t\tcontinue;\n\t\t}\n\t\tconst matched = available.find((entry) => entry.version === resolved)!;\n\t\tresolvedCapabilities.push({\n\t\t\tnamespace: ref.namespace,\n\t\t\tversion: resolved,\n\t\t\trange: ref.range,\n\t\t\tmanifestDigest: matched.manifestDigest,\n\t\t});\n\t}\n\n\t// ── Resolve component pack ranges ────────────────────────────────────\n\tconst resolvedPacks: ResolvedComponentPack[] = [];\n\tconst packsByKey = new Map<string, AvailableComponentPack[]>();\n\tfor (const available of input.componentPacks) {\n\t\tconst key = `${available.namespace}/${available.pack}`;\n\t\tconst list = packsByKey.get(key) ?? [];\n\t\tlist.push(available);\n\t\tpacksByKey.set(key, list);\n\t}\n\n\tfor (const ref of input.manifest.componentPacks) {\n\t\tconst range = parseSemverRange(ref.range);\n\t\tif (!range) {\n\t\t\tadd(\"invalid_range\", `assembly.componentPacks.${ref.namespace}/${ref.pack}.range`,\n\t\t\t\t`range \"${ref.range}\" is not a valid semver range`);\n\t\t\tcontinue;\n\t\t}\n\t\tconst key = `${ref.namespace}/${ref.pack}`;\n\t\tconst available = packsByKey.get(key) ?? [];\n\t\tconst versions = available.map((entry) => entry.version);\n\t\tconst resolved = resolveVersionRange(range, versions);\n\t\tif (!resolved) {\n\t\t\tadd(\"unresolved_component_pack\", `assembly.componentPacks.${key}`,\n\t\t\t\t`no available version of pack \"${key}\" satisfies range \"${ref.range}\"`);\n\t\t\tcontinue;\n\t\t}\n\t\tconst matched = available.find((entry) => entry.version === resolved)!;\n\t\tresolvedPacks.push({\n\t\t\tpack: ref.pack,\n\t\t\tnamespace: ref.namespace,\n\t\t\tversion: resolved,\n\t\t\trange: ref.range,\n\t\t\tartifactDigest: matched.artifactDigest,\n\t\t\t...(matched.remote ? { remote: matched.remote } : {}),\n\t\t});\n\t}\n\n\t// ── Validate component pack manifests ───────────────────────────────\n\tconst packManifests = input.packManifests ?? [];\n\tfor (const pack of packManifests) {\n\t\ttry {\n\t\t\tassertComponentPackManifest(pack);\n\t\t} catch (error) {\n\t\t\tadd(\"invalid_component_pack\", `packManifests.${pack.namespace}/${pack.pack}`,\n\t\t\t\terror instanceof Error ? error.message : String(error));\n\t\t}\n\t}\n\tconst resolvedPackManifests: ComponentPackManifest[] = [];\n\tfor (const resolved of resolvedPacks) {\n\t\tconst key = `${resolved.namespace}/${resolved.pack}`;\n\t\tconst manifest = packManifests.find((candidate) =>\n\t\t\tcandidate.namespace === resolved.namespace &&\n\t\t\tcandidate.pack === resolved.pack &&\n\t\t\tcandidate.version === resolved.version\n\t\t);\n\t\tif (!manifest) {\n\t\t\tadd(\"missing_component_pack_manifest\", `assembly.componentPacks.${key}`,\n\t\t\t\t`resolved pack \"${key}@${resolved.version}\" has no matching component-pack manifest`);\n\t\t\tcontinue;\n\t\t}\n\t\tif (manifest.artifactDigest !== resolved.artifactDigest) {\n\t\t\tadd(\"component_pack_artifact_digest_mismatch\", `assembly.componentPacks.${key}.artifactDigest`,\n\t\t\t\t`component-pack manifest digest \"${manifest.artifactDigest}\" does not match resolved artifact digest \"${resolved.artifactDigest}\"`);\n\t\t\tcontinue;\n\t\t}\n\t\tresolvedPackManifests.push(manifest);\n\t}\n\n\t// ── Validate contracts ──────────────────────────────────────────────\n\tconst contractsByNamespace = new Map<string, UsageContract>();\n\tfor (const entry of input.manifest.contracts) {\n\t\ttry {\n\t\t\tassertUsageContractDocument(entry.document);\n\t\t} catch (error) {\n\t\t\tadd(\"invalid_contract\", `assembly.contracts.${entry.namespace}`,\n\t\t\t\terror instanceof Error ? error.message : String(error));\n\t\t\tcontinue;\n\t\t}\n\t\tif (entry.document.capability.namespace !== entry.namespace) {\n\t\t\tadd(\"contract_namespace_mismatch\", `assembly.contracts.${entry.namespace}`,\n\t\t\t\t`contract namespace \"${entry.document.capability.namespace}\" does not match assembly namespace \"${entry.namespace}\"`);\n\t\t}\n\t\tconst resolved = resolvedCapabilities.find((capability) => capability.namespace === entry.namespace);\n\t\tif (resolved && entry.document.manifestDigest !== resolved.manifestDigest) {\n\t\t\tadd(\"contract_manifest_digest_mismatch\", `assembly.contracts.${entry.namespace}.manifestDigest`,\n\t\t\t\t`contract manifest digest \"${entry.document.manifestDigest}\" does not match resolved capability digest \"${resolved.manifestDigest}\"`);\n\t\t} else if (resolved) {\n\t\t\tresolved.usageContractDigest = computeUsageContractDocumentDigest(entry.document);\n\t\t}\n\t\tcontractsByNamespace.set(entry.namespace, entry.document.capability);\n\t}\n\n\t// ── Validate bindings ───────────────────────────────────────────────\n\tconst resolvedBindings: ResolvedBinding[] = [];\n\tfor (const entry of input.manifest.bindings) {\n\t\tconst contract = contractsByNamespace.get(entry.capability);\n\t\tif (!contract) {\n\t\t\tadd(\"unknown_contract_for_binding\", `assembly.bindings.${entry.capability}`,\n\t\t\t\t`binding targets capability \"${entry.capability}\" but no contract for it is declared`);\n\t\t\tresolvedBindings.push({\n\t\t\t\tcapability: entry.capability,\n\t\t\t\tbindingDigest: assemblyDigest(entry.binding),\n\t\t\t\tvalid: false,\n\t\t\t\tfindings: [],\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\tconst result = validateBinding({\n\t\t\tcontract,\n\t\t\tbinding: entry.binding,\n\t\t\tpacks: resolvedPackManifests,\n\t\t\tcoreComponents: input.coreComponents ?? [],\n\t\t\tavailableContracts: input.availableContracts ?? [],\n\t\t});\n\t\tresolvedBindings.push({\n\t\t\tcapability: entry.capability,\n\t\t\tbindingDigest: assemblyDigest(entry.binding),\n\t\t\tvalid: result.valid,\n\t\t\tfindings: result.findings,\n\t\t});\n\t\tif (!result.valid) {\n\t\t\tfor (const finding of result.findings) {\n\t\t\t\tadd(\"binding_validation_failed\", `assembly.bindings.${entry.capability}.${finding.path}`,\n\t\t\t\t\tfinding.message);\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── Produce lockfile ─────────────────────────────────────────────────\n\tconst capabilities = [...resolvedCapabilities].sort((a, b) =>\n\t\t\ta.namespace < b.namespace ? -1 : a.namespace > b.namespace ? 1 : 0,\n\t\t);\n\tconst componentPacks = [...resolvedPacks].sort((a, b) => {\n\t\t\tconst key = (e: ResolvedComponentPack) => `${e.namespace}/${e.pack}`;\n\t\t\treturn key(a) < key(b) ? -1 : key(a) > key(b) ? 1 : 0;\n\t\t});\n\tconst bindings = [...resolvedBindings].sort((a, b) =>\n\t\t\ta.capability < b.capability ? -1 : a.capability > b.capability ? 1 : 0,\n\t\t);\n\tconst lockfileBody = {\n\t\tformatVersion: ASSEMBLY_LOCKFILE_FORMAT_VERSION,\n\t\tapplication: input.manifest.application,\n\t\tcapabilities,\n\t\tcomponentPacks,\n\t\tbindings,\n\t};\n\tconst lockfile: AssemblyLockfile = {\n\t\tformatVersion: ASSEMBLY_LOCKFILE_FORMAT_VERSION,\n\t\tapplication: input.manifest.application,\n\t\tassemblyDigest: assemblyDigest(lockfileDigestBody(lockfileBody)),\n\t\tcapabilities,\n\t\tcomponentPacks,\n\t\tbindings,\n\t};\n\n\treturn {\n\t\tlockfile: findings.length === 0 ? lockfile : undefined,\n\t\tfindings,\n\t};\n}\n\n/**\n * Throw with every finding listed, for use as a build step. Returns the\n * lockfile when valid.\n */\nexport function assertAssemblyResolved(input: ResolveAssemblyInput): AssemblyLockfile {\n\tconst result = resolveAssembly(input);\n\tif (result.findings.length === 0) return result.lockfile!;\n\tthrow new Error([\n\t\t`Assembly \"${input.manifest.application}\" could not be resolved:`,\n\t\t...result.findings.map((finding) => ` - [${finding.code}] ${finding.path}: ${finding.message}`),\n\t].join(\"\\n\"));\n}\n\n/**\n * Validate an assembly manifest's bindings as a standalone build gate,\n * without resolving versions. Useful when versions are already locked and\n * only the binding contracts need checking.\n */\nexport function validateAssemblyBindings(input: {\n\tmanifest: AssemblyManifest;\n\tpackManifests?: ComponentPackManifest[];\n\tcoreComponents?: readonly string[];\n\tavailableContracts?: UsageContract[];\n}): AssemblyResult {\n\tassertAssemblyManifest(input.manifest);\n\tconst findings: AssemblyFinding[] = [];\n\tconst add = (code: AssemblyFindingCode, path: string, message: string): void => {\n\t\tfindings.push({ code, path, message });\n\t};\n\n\tconst contractsByNamespace = new Map<string, UsageContract>();\n\tfor (const entry of input.manifest.contracts) {\n\t\ttry {\n\t\t\tassertUsageContractDocument(entry.document);\n\t\t} catch (error) {\n\t\t\tadd(\"invalid_contract\", `assembly.contracts.${entry.namespace}`,\n\t\t\t\terror instanceof Error ? error.message : String(error));\n\t\t\tcontinue;\n\t\t}\n\t\tcontractsByNamespace.set(entry.namespace, entry.document.capability);\n\t}\n\n\tconst packManifests = input.packManifests ?? [];\n\tfor (const entry of input.manifest.bindings) {\n\t\tconst contract = contractsByNamespace.get(entry.capability);\n\t\tif (!contract) {\n\t\t\tadd(\"unknown_contract_for_binding\", `assembly.bindings.${entry.capability}`,\n\t\t\t\t`binding targets capability \"${entry.capability}\" but no contract for it is declared`);\n\t\t\tcontinue;\n\t\t}\n\t\ttry {\n\t\t\tassertBindingValid({\n\t\t\t\tcontract,\n\t\t\t\tbinding: entry.binding,\n\t\t\t\tpacks: packManifests,\n\t\t\t\tcoreComponents: input.coreComponents ?? [],\n\t\t\t\tavailableContracts: input.availableContracts ?? [],\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tadd(\"binding_validation_failed\", `assembly.bindings.${entry.capability}`,\n\t\t\t\terror instanceof Error ? error.message : String(error));\n\t\t}\n\t}\n\n\treturn {\n\t\tlockfile: undefined,\n\t\tfindings,\n\t};\n}\n"],"mappings":"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","names":[]}
package/dist/index.d.cts CHANGED
@@ -174,6 +174,16 @@ interface AssemblyResult {
174
174
  }
175
175
  /** Compute the digest stored for an exact generated usage-contract document. */
176
176
  declare function computeUsageContractDocumentDigest(document: UsageContractDocument): string;
177
+ /**
178
+ * The canonical digest of a lockfile's resolved content.
179
+ *
180
+ * `assertAssemblyLockfile` recomputes this on every load, so publishing it
181
+ * grants nothing an attacker did not already have; it lets tooling and tests
182
+ * construct a self-consistent lockfile instead of hand-fitting a hash. A
183
+ * forged lockfile still fails downstream, because a release binds the assembly
184
+ * digest it was validated against.
185
+ */
186
+ declare function computeAssemblyLockfileDigest(lockfile: Omit<AssemblyLockfile, "assemblyDigest">): string;
177
187
  /**
178
188
  * Structural validation of an assembly manifest. Checks the document's own
179
189
  * shape; does not resolve ranges or validate contracts/bindings.
@@ -235,4 +245,4 @@ declare function validateAssemblyBindings(input: {
235
245
  availableContracts?: UsageContract[];
236
246
  }): AssemblyResult;
237
247
 
238
- export { ASSEMBLY_LOCKFILE_FORMAT_VERSION, ASSEMBLY_MANIFEST_FORMAT_VERSION, type AssemblyBindingEntry, type AssemblyCapabilityReference, type AssemblyComponentPackReference, type AssemblyContractEntry, type AssemblyFinding, type AssemblyFindingCode, type AssemblyLockfile, type AssemblyManifest, type AssemblyResult, type AvailableCapability, type AvailableComponentPack, type ComponentPackRemote, type ResolveAssemblyInput, type ResolvedBinding, type ResolvedCapability, type ResolvedComponentPack, type SemverRange, assertAssemblyLockfile, assertAssemblyManifest, assertAssemblyResolved, assertAssemblyRuntimeCompatible, assertComponentPackManifest, computeUsageContractDocumentDigest, parseSemverRange, resolveAssembly, resolveVersionRange, satisfiesRange, validateAssemblyBindings };
248
+ export { ASSEMBLY_LOCKFILE_FORMAT_VERSION, ASSEMBLY_MANIFEST_FORMAT_VERSION, type AssemblyBindingEntry, type AssemblyCapabilityReference, type AssemblyComponentPackReference, type AssemblyContractEntry, type AssemblyFinding, type AssemblyFindingCode, type AssemblyLockfile, type AssemblyManifest, type AssemblyResult, type AvailableCapability, type AvailableComponentPack, type ComponentPackRemote, type ResolveAssemblyInput, type ResolvedBinding, type ResolvedCapability, type ResolvedComponentPack, type SemverRange, assertAssemblyLockfile, assertAssemblyManifest, assertAssemblyResolved, assertAssemblyRuntimeCompatible, assertComponentPackManifest, computeAssemblyLockfileDigest, computeUsageContractDocumentDigest, parseSemverRange, resolveAssembly, resolveVersionRange, satisfiesRange, validateAssemblyBindings };
package/dist/index.d.ts CHANGED
@@ -174,6 +174,16 @@ interface AssemblyResult {
174
174
  }
175
175
  /** Compute the digest stored for an exact generated usage-contract document. */
176
176
  declare function computeUsageContractDocumentDigest(document: UsageContractDocument): string;
177
+ /**
178
+ * The canonical digest of a lockfile's resolved content.
179
+ *
180
+ * `assertAssemblyLockfile` recomputes this on every load, so publishing it
181
+ * grants nothing an attacker did not already have; it lets tooling and tests
182
+ * construct a self-consistent lockfile instead of hand-fitting a hash. A
183
+ * forged lockfile still fails downstream, because a release binds the assembly
184
+ * digest it was validated against.
185
+ */
186
+ declare function computeAssemblyLockfileDigest(lockfile: Omit<AssemblyLockfile, "assemblyDigest">): string;
177
187
  /**
178
188
  * Structural validation of an assembly manifest. Checks the document's own
179
189
  * shape; does not resolve ranges or validate contracts/bindings.
@@ -235,4 +245,4 @@ declare function validateAssemblyBindings(input: {
235
245
  availableContracts?: UsageContract[];
236
246
  }): AssemblyResult;
237
247
 
238
- export { ASSEMBLY_LOCKFILE_FORMAT_VERSION, ASSEMBLY_MANIFEST_FORMAT_VERSION, type AssemblyBindingEntry, type AssemblyCapabilityReference, type AssemblyComponentPackReference, type AssemblyContractEntry, type AssemblyFinding, type AssemblyFindingCode, type AssemblyLockfile, type AssemblyManifest, type AssemblyResult, type AvailableCapability, type AvailableComponentPack, type ComponentPackRemote, type ResolveAssemblyInput, type ResolvedBinding, type ResolvedCapability, type ResolvedComponentPack, type SemverRange, assertAssemblyLockfile, assertAssemblyManifest, assertAssemblyResolved, assertAssemblyRuntimeCompatible, assertComponentPackManifest, computeUsageContractDocumentDigest, parseSemverRange, resolveAssembly, resolveVersionRange, satisfiesRange, validateAssemblyBindings };
248
+ export { ASSEMBLY_LOCKFILE_FORMAT_VERSION, ASSEMBLY_MANIFEST_FORMAT_VERSION, type AssemblyBindingEntry, type AssemblyCapabilityReference, type AssemblyComponentPackReference, type AssemblyContractEntry, type AssemblyFinding, type AssemblyFindingCode, type AssemblyLockfile, type AssemblyManifest, type AssemblyResult, type AvailableCapability, type AvailableComponentPack, type ComponentPackRemote, type ResolveAssemblyInput, type ResolvedBinding, type ResolvedCapability, type ResolvedComponentPack, type SemverRange, assertAssemblyLockfile, assertAssemblyManifest, assertAssemblyResolved, assertAssemblyRuntimeCompatible, assertComponentPackManifest, computeAssemblyLockfileDigest, computeUsageContractDocumentDigest, parseSemverRange, resolveAssembly, resolveVersionRange, satisfiesRange, validateAssemblyBindings };
package/dist/index.js CHANGED
@@ -194,6 +194,9 @@ function computeUsageContractDocumentDigest(document) {
194
194
  assertUsageContractDocument(document);
195
195
  return assemblyDigest(document);
196
196
  }
197
+ function computeAssemblyLockfileDigest(lockfile) {
198
+ return assemblyDigest(lockfileDigestBody(lockfile));
199
+ }
197
200
  function lockfileDigestBody(lockfile) {
198
201
  return {
199
202
  formatVersion: lockfile.formatVersion,
@@ -694,6 +697,7 @@ export {
694
697
  assertAssemblyResolved,
695
698
  assertAssemblyRuntimeCompatible,
696
699
  assertComponentPackManifest,
700
+ computeAssemblyLockfileDigest,
697
701
  computeUsageContractDocumentDigest,
698
702
  parseSemverRange,
699
703
  resolveAssembly,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../index.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport {\n\tassertAdoptionBinding,\n\tassertBindingValid,\n\tvalidateBinding,\n\ttype AdoptionBinding,\n\ttype BindingFinding,\n\ttype ComponentPackManifest,\n} from \"@fabricorg/adoption-bindings\";\nimport {\n\tassertUsageContract,\n\tassertUsageContractDocument,\n\ttype UsageContract,\n\ttype UsageContractDocument,\n} from \"@fabricorg/gen-capability\";\n\n/**\n * Version of the assembly manifest document. A vertical negotiates on this, not\n * on this package's version, and it moves only when the serialized shape changes.\n */\nexport const ASSEMBLY_MANIFEST_FORMAT_VERSION = 2 as const;\n\n/**\n * Version of the resolved lockfile document. Bump when the serialized shape\n * changes in a way a consumer must detect.\n */\nexport const ASSEMBLY_LOCKFILE_FORMAT_VERSION = 2 as const;\n\n// ── Semver range resolution (zero-dependency) ───────────────────────────────\n\ninterface SemverVersion {\n\tmajor: number;\n\tminor: number;\n\tpatch: number;\n\tprerelease: string[];\n}\n\nfunction parseSemver(input: string): SemverVersion | undefined {\n\tconst match = /^(\\d+)\\.(\\d+)\\.(\\d+)(?:-([0-9A-Za-z.-]+))?$/.exec(input.trim());\n\tif (!match) return undefined;\n\treturn {\n\t\tmajor: Number(match[1]),\n\t\tminor: Number(match[2]),\n\t\tpatch: Number(match[3]),\n\t\tprerelease: match[4] ? match[4].split(\".\") : [],\n\t};\n}\n\nfunction comparePrerelease(a: string[], b: string[]): number {\n\t// No prerelease > has prerelease (release > pre-release).\n\tif (a.length === 0 && b.length === 0) return 0;\n\tif (a.length === 0) return 1;\n\tif (b.length === 0) return -1;\n\tfor (let i = 0; i < Math.max(a.length, b.length); i++) {\n\t\tconst ai = a[i];\n\t\tconst bi = b[i];\n\t\tif (ai === undefined) return -1;\n\t\tif (bi === undefined) return 1;\n\t\tconst an = /^\\d+$/.test(ai);\n\t\tconst bn = /^\\d+$/.test(bi);\n\t\tif (an && bn) {\n\t\t\tconst diff = Number(ai) - Number(bi);\n\t\t\tif (diff !== 0) return diff;\n\t\t} else if (an) {\n\t\t\treturn -1;\n\t\t} else if (bn) {\n\t\t\treturn 1;\n\t\t} else {\n\t\t\tif (ai < bi) return -1;\n\t\t\tif (ai > bi) return 1;\n\t\t}\n\t}\n\treturn 0;\n}\n\nfunction compareSemver(a: SemverVersion, b: SemverVersion): number {\n\tif (a.major !== b.major) return a.major - b.major;\n\tif (a.minor !== b.minor) return a.minor - b.minor;\n\tif (a.patch !== b.patch) return a.patch - b.patch;\n\treturn comparePrerelease(a.prerelease, b.prerelease);\n}\n\ntype Comparator = (version: SemverVersion) => boolean;\n\nfunction caretComparator(range: SemverVersion): Comparator {\n\treturn (version) => {\n\t\tif (compareSemver(version, range) < 0) return false;\n\t\tif (version.major !== range.major) return false;\n\t\tif (version.major === 0) {\n\t\t\tif (version.minor !== range.minor) return false;\n\t\t\tif (range.minor === 0 && version.patch !== range.patch) return false;\n\t\t}\n\t\treturn true;\n\t};\n}\n\nfunction tildeComparator(range: SemverVersion): Comparator {\n\treturn (version) => {\n\t\tif (compareSemver(version, range) < 0) return false;\n\t\treturn version.major === range.major && version.minor === range.minor;\n\t};\n}\n\nfunction exactComparator(range: SemverVersion): Comparator {\n\treturn (version) => compareSemver(version, range) === 0;\n}\n\nfunction gteComparator(range: SemverVersion): Comparator {\n\treturn (version) => compareSemver(version, range) >= 0;\n}\n\nfunction gtComparator(range: SemverVersion): Comparator {\n\treturn (version) => compareSemver(version, range) > 0;\n}\n\nfunction lteComparator(range: SemverVersion): Comparator {\n\treturn (version) => compareSemver(version, range) <= 0;\n}\n\nfunction ltComparator(range: SemverVersion): Comparator {\n\treturn (version) => compareSemver(version, range) < 0;\n}\n\nfunction anyComparator(): Comparator {\n\treturn () => true;\n}\n\ninterface ParsedComparator {\n\toperator: string;\n\tcomparator: Comparator;\n\traw: string;\n\trangeVersion: SemverVersion | undefined;\n}\n\nfunction parseComparator(raw: string): ParsedComparator | undefined {\n\tconst trimmed = raw.trim();\n\tif (trimmed === \"*\" || trimmed === \"\") return { operator: \"*\", comparator: anyComparator(), raw: trimmed, rangeVersion: undefined };\n\n\tconst caret = /^(\\^)(\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?)$/.exec(trimmed);\n\tif (caret) {\n\t\tconst version = parseSemver(caret[2]!);\n\t\tif (!version) return undefined;\n\t\treturn { operator: \"^\", comparator: caretComparator(version), raw: trimmed, rangeVersion: version };\n\t}\n\tconst tilde = /^(~)(\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?)$/.exec(trimmed);\n\tif (tilde) {\n\t\tconst version = parseSemver(tilde[2]!);\n\t\tif (!version) return undefined;\n\t\treturn { operator: \"~\", comparator: tildeComparator(version), raw: trimmed, rangeVersion: version };\n\t}\n\tconst op = /^(>=|<=|>|<|=)(\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?)$/.exec(trimmed);\n\tif (op) {\n\t\tconst version = parseSemver(op[2]!);\n\t\tif (!version) return undefined;\n\t\tconst operator = op[1]!;\n\t\tlet comparator: Comparator;\n\t\tswitch (operator) {\n\t\t\tcase \">=\": comparator = gteComparator(version); break;\n\t\t\tcase \"<=\": comparator = lteComparator(version); break;\n\t\t\tcase \">\": comparator = gtComparator(version); break;\n\t\t\tcase \"<\": comparator = ltComparator(version); break;\n\t\t\tdefault: comparator = exactComparator(version); break;\n\t\t}\n\t\treturn { operator, comparator, raw: trimmed, rangeVersion: version };\n\t}\n\tconst bare = /^(\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?)$/.exec(trimmed);\n\tif (bare) {\n\t\tconst version = parseSemver(bare[1]!);\n\t\tif (!version) return undefined;\n\t\treturn { operator: \"=\", comparator: exactComparator(version), raw: trimmed, rangeVersion: version };\n\t}\n\treturn undefined;\n}\n\nfunction comparatorRangeVersion(comparator: ParsedComparator): SemverVersion | undefined {\n\treturn comparator.rangeVersion;\n}\n\n/**\n * A parsed semver range — a conjunction of comparators. Every comparator must\n * be satisfied. This is the subset of npm range syntax that a deterministic\n * resolver needs: `^`, `~`, `>=`, `>`, `<=`, `<`, `=`, exact, and `*`.\n */\nexport interface SemverRange {\n\tcomparators: ParsedComparator[];\n\traw: string;\n}\n\n/**\n * Parse a semver range string into a {@link SemverRange}. Returns `undefined`\n * for an unparseable range rather than throwing, so callers can distinguish\n * \"bad range\" from \"no satisfying version\".\n */\nexport function parseSemverRange(raw: string): SemverRange | undefined {\n\tconst trimmed = raw.trim();\n\tif (!trimmed) return undefined;\n\tconst parts = trimmed.split(/\\s+/);\n\tconst comparators: ParsedComparator[] = [];\n\tfor (const part of parts) {\n\t\tconst parsed = parseComparator(part);\n\t\tif (!parsed) return undefined;\n\t\tcomparators.push(parsed);\n\t}\n\tif (comparators.length === 0) return undefined;\n\treturn { comparators, raw: trimmed };\n}\n\n/**\n * Test whether a version string satisfies a parsed range.\n *\n * Prerelease versions only satisfy a range when a comparator in the range\n * declares a prerelease at the same `[major, minor, patch]` tuple. This\n * follows npm semantics: `^1.0.0` does not match `1.1.0-alpha`, but\n * `^1.0.0-alpha` matches `1.0.0-alpha.2`.\n */\nexport function satisfiesRange(version: string, range: SemverRange): boolean {\n\tconst parsed = parseSemver(version);\n\tif (!parsed) return false;\n\tif (!range.comparators.every((comparator) => comparator.comparator(parsed))) return false;\n\tif (parsed.prerelease.length > 0) {\n\t\treturn range.comparators.some((comparator) => {\n\t\t\tconst rangeVersion = comparatorRangeVersion(comparator);\n\t\t\treturn (\n\t\t\t\trangeVersion !== undefined &&\n\t\t\t\trangeVersion.prerelease.length > 0 &&\n\t\t\t\trangeVersion.major === parsed.major &&\n\t\t\t\trangeVersion.minor === parsed.minor &&\n\t\t\t\trangeVersion.patch === parsed.patch\n\t\t\t);\n\t\t});\n\t}\n\treturn true;\n}\n\n/**\n * Resolve a range against a list of available versions, returning the highest\n * satisfying version. Returns `undefined` when no available version satisfies\n * the range. Deterministic: the same inputs always produce the same result.\n */\nexport function resolveVersionRange(range: SemverRange, available: readonly string[]): string | undefined {\n\tconst parsed = available\n\t\t.map((version) => ({ version, parsed: parseSemver(version) }))\n\t\t.filter((entry): entry is { version: string; parsed: SemverVersion } => entry.parsed !== undefined)\n\t\t.filter((entry) => {\n\t\t\tif (!range.comparators.every((comparator) => comparator.comparator(entry.parsed))) return false;\n\t\t\tif (entry.parsed.prerelease.length > 0) {\n\t\t\t\treturn range.comparators.some((comparator) => {\n\t\t\t\t\tconst rangeVersion = comparatorRangeVersion(comparator);\n\t\t\t\t\treturn (\n\t\t\t\t\t\trangeVersion !== undefined &&\n\t\t\t\t\t\trangeVersion.prerelease.length > 0 &&\n\t\t\t\t\t\trangeVersion.major === entry.parsed.major &&\n\t\t\t\t\t\trangeVersion.minor === entry.parsed.minor &&\n\t\t\t\t\t\trangeVersion.patch === entry.parsed.patch\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn true;\n\t\t})\n\t\t.sort((a, b) => compareSemver(b.parsed, a.parsed));\n\treturn parsed[0]?.version;\n}\n\n// ── Assembly manifest contracts ─────────────────────────────────────────────\n\n/** A capability the vertical assembles, with a version range to resolve. */\nexport interface AssemblyCapabilityReference {\n\tnamespace: string;\n\t/** Semver range, e.g. `^1.0.0`, `>=1.0.0 <2.0.0`, `*`. */\n\trange: string;\n}\n\n/** A component pack the vertical assembles, with a version range to resolve. */\nexport interface AssemblyComponentPackReference {\n\tpack: string;\n\tnamespace: string;\n\trange: string;\n}\n\n/** An adoption binding the vertical declares against a capability. */\nexport interface AssemblyBindingEntry {\n\tcapability: string;\n\tbinding: AdoptionBinding;\n}\n\n/** A usage contract the vertical depends on, supplied inline for validation. */\nexport interface AssemblyContractEntry {\n\tnamespace: string;\n\tdocument: UsageContractDocument;\n}\n\n/**\n * What a vertical assembles: the capabilities it depends on, the component\n * packs it uses, the adoption bindings it declares, and the usage contracts\n * it validates against. This is the build-time input; the lockfile is the\n * resolved output.\n */\nexport interface AssemblyManifest {\n\tformatVersion: typeof ASSEMBLY_MANIFEST_FORMAT_VERSION;\n\t/** Lowercase identifier for the vertical application. */\n\tapplication: string;\n\tcapabilities: AssemblyCapabilityReference[];\n\tcomponentPacks: AssemblyComponentPackReference[];\n\tbindings: AssemblyBindingEntry[];\n\tcontracts: AssemblyContractEntry[];\n}\n\n// ── Available versions for resolution ───────────────────────────────────────\n\n/** A published capability version available for resolution. */\nexport interface AvailableCapability {\n\tnamespace: string;\n\tversion: string;\n\t/** SHA-256 manifest digest from the compiler IR. */\n\tmanifestDigest: string;\n}\n\n/**\n * Where a federated pack is loaded from, and what proves it is the pack that\n * was approved. The artifact digest identifies the pack that was reviewed; the\n * remote entry is what a shell actually executes, so it needs its own integrity\n * value or the review covers something other than what runs.\n */\nexport interface ComponentPackRemote {\n\t/** Remote entry URL the shell loads. */\n\tentry: string;\n\t/** Subresource-integrity value for that entry, e.g. `sha384-…`. */\n\tintegrity: string;\n\t/** Exposed module path keyed by the component name it provides. */\n\texposes: Record<string, string>;\n}\n\n/** A published component pack version available for resolution. */\nexport interface AvailableComponentPack {\n\tpack: string;\n\tnamespace: string;\n\tversion: string;\n\t/** SHA-256 digest of the published component-pack artifact. */\n\tartifactDigest: string;\n\t/** Present when this pack is delivered as a federated remote. */\n\tremote?: ComponentPackRemote;\n}\n\n// ── Lockfile contracts ──────────────────────────────────────────────────────\n\n/** A resolved capability in the lockfile. */\nexport interface ResolvedCapability {\n\tnamespace: string;\n\tversion: string;\n\trange: string;\n\tmanifestDigest: string;\n\t/** Digest of the exact generated usage-contract document validated for this capability. */\n\tusageContractDigest?: string;\n}\n\n/** A resolved component pack in the lockfile. */\nexport interface ResolvedComponentPack {\n\tpack: string;\n\tnamespace: string;\n\tversion: string;\n\trange: string;\n\tartifactDigest: string;\n\t/** Locked delivery binding, when the pack is a federated remote. */\n\tremote?: ComponentPackRemote;\n}\n\n/** A validated adoption binding in the lockfile. */\nexport interface ResolvedBinding {\n\tcapability: string;\n\tbindingDigest: string;\n\tvalid: boolean;\n\tfindings: BindingFinding[];\n}\n\n/**\n * The deterministic, resolved output of assembling a vertical. Every version\n * is locked, every binding is validated, and the whole document carries a\n * canonical digest so two builds with the same inputs produce the same lockfile.\n */\nexport interface AssemblyLockfile {\n\tformatVersion: typeof ASSEMBLY_LOCKFILE_FORMAT_VERSION;\n\tapplication: string;\n\t/** SHA-256 of this lockfile's canonical resolved body, excluding this field. */\n\tassemblyDigest: string;\n\tcapabilities: ResolvedCapability[];\n\tcomponentPacks: ResolvedComponentPack[];\n\tbindings: ResolvedBinding[];\n}\n\n// ── Findings ─────────────────────────────────────────────────────────────────\n\nexport type AssemblyFindingCode =\n\t| \"duplicate_capability\"\n\t| \"duplicate_component_pack\"\n\t| \"unresolved_capability\"\n\t| \"unresolved_component_pack\"\n\t| \"invalid_range\"\n\t| \"unknown_contract_for_binding\"\n\t| \"contract_namespace_mismatch\"\n\t| \"contract_manifest_digest_mismatch\"\n\t| \"binding_validation_failed\"\n\t| \"invalid_contract\"\n\t| \"invalid_component_pack\"\n\t| \"missing_component_pack_manifest\"\n\t| \"component_pack_artifact_digest_mismatch\"\n\t| \"duplicate_contract\";\n\nexport interface AssemblyFinding {\n\tcode: AssemblyFindingCode;\n\tpath: string;\n\tmessage: string;\n}\n\nexport interface AssemblyResult {\n\tlockfile: AssemblyLockfile | undefined;\n\tfindings: AssemblyFinding[];\n}\n\n// ── Stable serialization ───────────────────────────────────────────────────\n\nfunction sortJson(value: unknown): unknown {\n\tif (Array.isArray(value)) return value.map(sortJson);\n\tif (value && typeof value === \"object\") {\n\t\treturn Object.fromEntries(\n\t\t\tObject.entries(value as Record<string, unknown>)\n\t\t\t\t.sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))\n\t\t\t\t.map(([key, child]) => [key, sortJson(child)]),\n\t\t);\n\t}\n\treturn value;\n}\n\nfunction stableStringify(value: unknown): string {\n\treturn JSON.stringify(sortJson(value));\n}\n\nfunction assemblyDigest(value: unknown): string {\n\treturn createHash(\"sha256\").update(stableStringify(value)).digest(\"hex\");\n}\n\n/** Compute the digest stored for an exact generated usage-contract document. */\nexport function computeUsageContractDocumentDigest(document: UsageContractDocument): string {\n\tassertUsageContractDocument(document);\n\treturn assemblyDigest(document);\n}\n\nfunction lockfileDigestBody(lockfile: Omit<AssemblyLockfile, \"assemblyDigest\">): unknown {\n\treturn {\n\t\tformatVersion: lockfile.formatVersion,\n\t\tapplication: lockfile.application,\n\t\tcapabilities: lockfile.capabilities,\n\t\tcomponentPacks: lockfile.componentPacks,\n\t\tbindings: lockfile.bindings,\n\t};\n}\n\n// ── Structural validation ───────────────────────────────────────────────────\n\nfunction fail(path: string, message: string): never {\n\tthrow new Error(`Assembly manifest ${path} ${message}.`);\n}\n\nfunction requireString(value: unknown, path: string): string {\n\tif (typeof value !== \"string\" || !value.trim()) fail(path, \"must be a non-empty string\");\n\treturn value;\n}\n\nfunction requireArray(value: unknown, path: string): unknown[] {\n\tif (!Array.isArray(value)) fail(path, \"must be an array\");\n\treturn value;\n}\n\n/**\n * Structural validation of an assembly manifest. Checks the document's own\n * shape; does not resolve ranges or validate contracts/bindings.\n */\nexport function assertAssemblyManifest(value: unknown, path = \"assembly\"): asserts value is AssemblyManifest {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) fail(path, \"must be an object\");\n\tconst manifest = value as Record<string, unknown>;\n\tif (manifest.formatVersion !== ASSEMBLY_MANIFEST_FORMAT_VERSION) {\n\t\tfail(`${path}.formatVersion`, `must be ${ASSEMBLY_MANIFEST_FORMAT_VERSION}, received ${JSON.stringify(manifest.formatVersion)}`);\n\t}\n\tif (!/^[a-z][a-z0-9-]*$/.test(requireString(manifest.application, `${path}.application`))) {\n\t\tfail(`${path}.application`, \"must be lowercase letters, numbers and hyphens\");\n\t}\n\trequireArray(manifest.capabilities, `${path}.capabilities`).forEach((entry, index) => {\n\t\tconst capability = entry as Record<string, unknown>;\n\t\trequireString(capability?.namespace, `${path}.capabilities[${index}].namespace`);\n\t\trequireString(capability?.range, `${path}.capabilities[${index}].range`);\n\t});\n\trequireArray(manifest.componentPacks, `${path}.componentPacks`).forEach((entry, index) => {\n\t\tconst pack = entry as Record<string, unknown>;\n\t\trequireString(pack?.pack, `${path}.componentPacks[${index}].pack`);\n\t\trequireString(pack?.namespace, `${path}.componentPacks[${index}].namespace`);\n\t\trequireString(pack?.range, `${path}.componentPacks[${index}].range`);\n\t});\n\trequireArray(manifest.bindings, `${path}.bindings`).forEach((entry, index) => {\n\t\tconst binding = entry as Record<string, unknown>;\n\t\trequireString(binding?.capability, `${path}.bindings[${index}].capability`);\n\t\tassertAdoptionBinding(binding?.binding, `${path}.bindings[${index}].binding`);\n\t});\n\trequireArray(manifest.contracts, `${path}.contracts`).forEach((entry, index) => {\n\t\tconst contract = entry as Record<string, unknown>;\n\t\trequireString(contract?.namespace, `${path}.contracts[${index}].namespace`);\n\t\ttry {\n\t\t\tassertUsageContractDocument(contract?.document);\n\t\t} catch (error) {\n\t\t\tfail(`${path}.contracts[${index}].document`, error instanceof Error ? error.message : String(error));\n\t\t}\n\t});\n}\n\n/**\n * Structural validation of a component pack manifest.\n */\nexport function assertComponentPackManifest(value: unknown, path = \"pack\"): asserts value is ComponentPackManifest {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) fail(path, \"must be an object\");\n\tconst pack = value as Record<string, unknown>;\n\trequireString(pack.pack, `${path}.pack`);\n\trequireString(pack.namespace, `${path}.namespace`);\n\trequireString(pack.version, `${path}.version`);\n\tif (!/^\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?$/.test(pack.version as string)) {\n\t\tfail(`${path}.version`, \"must be a semver version\");\n\t}\n\tif (!pack.components || typeof pack.components !== \"object\" || Array.isArray(pack.components)) {\n\t\tfail(`${path}.components`, \"must be an object\");\n\t}\n\tif (!/^[0-9a-f]{64}$/.test(requireString(pack.artifactDigest, `${path}.artifactDigest`))) {\n\t\tfail(`${path}.artifactDigest`, \"must be a lowercase SHA-256 digest\");\n\t}\n}\n\n/**\n * Validate a resolved lockfile and verify that its digest still identifies its\n * exact application, capability, pack, contract, and binding content.\n */\nexport function assertAssemblyLockfile(value: unknown, path = \"lockfile\"): asserts value is AssemblyLockfile {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) fail(path, \"must be an object\");\n\tconst lockfile = value as Record<string, unknown>;\n\tif (lockfile.formatVersion !== ASSEMBLY_LOCKFILE_FORMAT_VERSION) {\n\t\tfail(`${path}.formatVersion`, `must be ${ASSEMBLY_LOCKFILE_FORMAT_VERSION}, received ${JSON.stringify(lockfile.formatVersion)}`);\n\t}\n\tif (!/^[a-z][a-z0-9-]*$/.test(requireString(lockfile.application, `${path}.application`))) {\n\t\tfail(`${path}.application`, \"must be lowercase letters, numbers and hyphens\");\n\t}\n\tif (!/^[0-9a-f]{64}$/.test(requireString(lockfile.assemblyDigest, `${path}.assemblyDigest`))) {\n\t\tfail(`${path}.assemblyDigest`, \"must be a lowercase SHA-256 digest\");\n\t}\n\tconst capabilities = requireArray(lockfile.capabilities, `${path}.capabilities`);\n\tconst componentPacks = requireArray(lockfile.componentPacks, `${path}.componentPacks`);\n\tconst bindings = requireArray(lockfile.bindings, `${path}.bindings`);\n\tconst seenCapabilities = new Set<string>();\n\tfor (const [index, entry] of capabilities.entries()) {\n\t\tconst capability = entry as Record<string, unknown>;\n\t\tconst namespace = String(capability?.namespace);\n\t\tif (seenCapabilities.has(namespace)) {\n\t\t\tfail(`${path}.capabilities[${index}]`, `declares capability \"${namespace}\" a second time`);\n\t\t}\n\t\tseenCapabilities.add(namespace);\n\t\trequireString(capability?.namespace, `${path}.capabilities[${index}].namespace`);\n\t\trequireString(capability?.version, `${path}.capabilities[${index}].version`);\n\t\trequireString(capability?.range, `${path}.capabilities[${index}].range`);\n\t\tif (!/^[0-9a-f]{64}$/.test(requireString(capability?.manifestDigest, `${path}.capabilities[${index}].manifestDigest`))) {\n\t\t\tfail(`${path}.capabilities[${index}].manifestDigest`, \"must be a lowercase SHA-256 digest\");\n\t\t}\n\t\tif (capability?.usageContractDigest !== undefined &&\n\t\t\t!/^[0-9a-f]{64}$/.test(requireString(capability.usageContractDigest, `${path}.capabilities[${index}].usageContractDigest`))) {\n\t\t\tfail(`${path}.capabilities[${index}].usageContractDigest`, \"must be a lowercase SHA-256 digest\");\n\t\t}\n\t}\n\tconst seenPackIdentities = new Set<string>();\n\tfor (const [index, entry] of componentPacks.entries()) {\n\t\tconst pack = entry as Record<string, unknown>;\n\t\trequireString(pack?.pack, `${path}.componentPacks[${index}].pack`);\n\t\tconst identity = `${String(pack?.namespace)}/${String(pack?.pack)}`;\n\t\tif (seenPackIdentities.has(identity)) {\n\t\t\tfail(`${path}.componentPacks[${index}]`, `declares component pack \"${identity}\" a second time; first-match resolution would make the choice arbitrary`);\n\t\t}\n\t\tseenPackIdentities.add(identity);\n\t\trequireString(pack?.namespace, `${path}.componentPacks[${index}].namespace`);\n\t\trequireString(pack?.version, `${path}.componentPacks[${index}].version`);\n\t\trequireString(pack?.range, `${path}.componentPacks[${index}].range`);\n\t\tif (!/^[0-9a-f]{64}$/.test(requireString(pack?.artifactDigest, `${path}.componentPacks[${index}].artifactDigest`))) {\n\t\t\tfail(`${path}.componentPacks[${index}].artifactDigest`, \"must be a lowercase SHA-256 digest\");\n\t\t}\n\t\tif (pack?.remote !== undefined) {\n\t\t\tconst remotePath = `${path}.componentPacks[${index}].remote`;\n\t\t\tconst remote = pack.remote as Record<string, unknown>;\n\t\t\tif (remote === null || typeof remote !== \"object\" || Array.isArray(remote)) fail(remotePath, \"must be an object\");\n\t\t\trequireString(remote.entry, `${remotePath}.entry`);\n\t\t\t// Integrity is the only thing standing between an approved pack and\n\t\t\t// whatever the remote entry happens to serve at load time.\n\t\t\tif (!/^sha(256|384|512)-[A-Za-z0-9+/]+={0,2}$/.test(requireString(remote.integrity, `${remotePath}.integrity`))) {\n\t\t\t\tfail(`${remotePath}.integrity`, \"must be a subresource-integrity value, e.g. \\\"sha384-…\\\"\");\n\t\t\t}\n\t\t\tconst exposes = remote.exposes as Record<string, unknown>;\n\t\t\tif (exposes === null || typeof exposes !== \"object\" || Array.isArray(exposes)) {\n\t\t\t\tfail(`${remotePath}.exposes`, \"must be an object\");\n\t\t\t}\n\t\t\tfor (const [component, modulePath] of Object.entries(exposes)) {\n\t\t\t\trequireString(modulePath, `${remotePath}.exposes.${component}`);\n\t\t\t}\n\t\t}\n\t}\n\tfor (const [index, entry] of bindings.entries()) {\n\t\tconst binding = entry as Record<string, unknown>;\n\t\trequireString(binding?.capability, `${path}.bindings[${index}].capability`);\n\t\tif (!/^[0-9a-f]{64}$/.test(requireString(binding?.bindingDigest, `${path}.bindings[${index}].bindingDigest`))) {\n\t\t\tfail(`${path}.bindings[${index}].bindingDigest`, \"must be a lowercase SHA-256 digest\");\n\t\t}\n\t\tif (binding?.valid !== true) fail(`${path}.bindings[${index}].valid`, \"must be true\");\n\t\trequireArray(binding?.findings, `${path}.bindings[${index}].findings`);\n\t}\n\tconst expected = assemblyDigest(lockfileDigestBody({\n\t\tformatVersion: ASSEMBLY_LOCKFILE_FORMAT_VERSION,\n\t\tapplication: lockfile.application as string,\n\t\tcapabilities: capabilities as unknown as ResolvedCapability[],\n\t\tcomponentPacks: componentPacks as unknown as ResolvedComponentPack[],\n\t\tbindings: bindings as unknown as ResolvedBinding[],\n\t}));\n\tif (lockfile.assemblyDigest !== expected) {\n\t\tfail(`${path}.assemblyDigest`, `does not match resolved lockfile content; expected \"${expected}\"`);\n\t}\n}\n\n/**\n * Verify that the capability artifacts loaded by a runtime are exactly those\n * approved by an integrity-checked assembly lockfile.\n */\nexport function assertAssemblyRuntimeCompatible(\n\tlockfile: AssemblyLockfile,\n\tloadedCapabilities: readonly AvailableCapability[],\n): void {\n\tassertAssemblyLockfile(lockfile);\n\tconst loadedByNamespace = new Map<string, AvailableCapability>();\n\tfor (const loaded of loadedCapabilities) {\n\t\tif (loadedByNamespace.has(loaded.namespace)) {\n\t\t\tthrow new Error(`Loaded capability \"${loaded.namespace}\" is duplicated.`);\n\t\t}\n\t\tloadedByNamespace.set(loaded.namespace, loaded);\n\t}\n\tfor (const approved of lockfile.capabilities) {\n\t\tconst loaded = loadedByNamespace.get(approved.namespace);\n\t\tif (!loaded ||\n\t\t\tloaded.version !== approved.version ||\n\t\t\tloaded.manifestDigest !== approved.manifestDigest) {\n\t\t\tthrow new Error(\n\t\t\t\t`Loaded capability \"${approved.namespace}\" does not match approved capability ` +\n\t\t\t\t`\"${approved.namespace}@${approved.version}\" with manifest digest \"${approved.manifestDigest}\".`,\n\t\t\t);\n\t\t}\n\t}\n\tfor (const loaded of loadedCapabilities) {\n\t\tif (!lockfile.capabilities.some((approved) => approved.namespace === loaded.namespace)) {\n\t\t\tthrow new Error(`Loaded capability \"${loaded.namespace}\" is not approved by assembly \"${lockfile.assemblyDigest}\".`);\n\t\t}\n\t}\n}\n\n// ── Resolution ───────────────────────────────────────────────────────────────\n\nexport interface ResolveAssemblyInput {\n\tmanifest: AssemblyManifest;\n\t/** Published capability versions available for resolution. */\n\tcapabilities: AvailableCapability[];\n\t/** Published component pack versions available for resolution. */\n\tcomponentPacks: AvailableComponentPack[];\n\t/** Component pack manifests for binding validation. */\n\tpackManifests?: ComponentPackManifest[];\n\t/** Core component vocabulary every renderer implements. */\n\tcoreComponents?: readonly string[];\n\t/** Contracts available for cross-capability fragment resolution. */\n\tavailableContracts?: UsageContract[];\n}\n\n/**\n * Resolve an assembly manifest into a deterministic lockfile. This is the\n * single build gate: it resolves version ranges, rejects unresolved or\n * duplicate capability identities, validates usage contracts, component\n * packs, and adoption bindings, and produces a lockfile with a canonical\n * digest.\n *\n * Returns every finding rather than throwing, so one CI run tells a vertical\n * everything it has to change. Use {@link assertAssemblyResolved} to throw\n * on the first invalid result.\n */\nexport function resolveAssembly(input: ResolveAssemblyInput): AssemblyResult {\n\tassertAssemblyManifest(input.manifest);\n\tconst findings: AssemblyFinding[] = [];\n\tconst add = (code: AssemblyFindingCode, path: string, message: string): void => {\n\t\tfindings.push({ code, path, message });\n\t};\n\n\t// ── Duplicate capability identities ──────────────────────────────────\n\tconst capabilityNamespaces = new Set<string>();\n\tfor (const capability of input.manifest.capabilities) {\n\t\tif (capabilityNamespaces.has(capability.namespace)) {\n\t\t\tadd(\"duplicate_capability\", `assembly.capabilities.${capability.namespace}`,\n\t\t\t\t`capability \"${capability.namespace}\" is declared more than once`);\n\t\t}\n\t\tcapabilityNamespaces.add(capability.namespace);\n\t}\n\n\t// ── Duplicate component pack identities ──────────────────────────────\n\tconst packKeys = new Set<string>();\n\tfor (const pack of input.manifest.componentPacks) {\n\t\tconst key = `${pack.namespace}/${pack.pack}`;\n\t\tif (packKeys.has(key)) {\n\t\t\tadd(\"duplicate_component_pack\", `assembly.componentPacks.${key}`,\n\t\t\t\t`component pack \"${key}\" is declared more than once`);\n\t\t}\n\t\tpackKeys.add(key);\n\t}\n\n\t// ── Duplicate contracts ──────────────────────────────────────────────\n\tconst contractNamespaces = new Set<string>();\n\tfor (const contract of input.manifest.contracts) {\n\t\tif (contractNamespaces.has(contract.namespace)) {\n\t\t\tadd(\"duplicate_contract\", `assembly.contracts.${contract.namespace}`,\n\t\t\t\t`contract for \"${contract.namespace}\" is declared more than once`);\n\t\t}\n\t\tcontractNamespaces.add(contract.namespace);\n\t}\n\n\t// ── Resolve capability ranges ────────────────────────────────────────\n\tconst resolvedCapabilities: ResolvedCapability[] = [];\n\tconst capabilitiesByNamespace = new Map<string, AvailableCapability[]>();\n\tfor (const available of input.capabilities) {\n\t\tconst list = capabilitiesByNamespace.get(available.namespace) ?? [];\n\t\tlist.push(available);\n\t\tcapabilitiesByNamespace.set(available.namespace, list);\n\t}\n\n\tfor (const ref of input.manifest.capabilities) {\n\t\tconst range = parseSemverRange(ref.range);\n\t\tif (!range) {\n\t\t\tadd(\"invalid_range\", `assembly.capabilities.${ref.namespace}.range`,\n\t\t\t\t`range \"${ref.range}\" is not a valid semver range`);\n\t\t\tcontinue;\n\t\t}\n\t\tconst available = capabilitiesByNamespace.get(ref.namespace) ?? [];\n\t\tconst versions = available.map((entry) => entry.version);\n\t\tconst resolved = resolveVersionRange(range, versions);\n\t\tif (!resolved) {\n\t\t\tadd(\"unresolved_capability\", `assembly.capabilities.${ref.namespace}`,\n\t\t\t\t`no available version of \"${ref.namespace}\" satisfies range \"${ref.range}\"`);\n\t\t\tcontinue;\n\t\t}\n\t\tconst matched = available.find((entry) => entry.version === resolved)!;\n\t\tresolvedCapabilities.push({\n\t\t\tnamespace: ref.namespace,\n\t\t\tversion: resolved,\n\t\t\trange: ref.range,\n\t\t\tmanifestDigest: matched.manifestDigest,\n\t\t});\n\t}\n\n\t// ── Resolve component pack ranges ────────────────────────────────────\n\tconst resolvedPacks: ResolvedComponentPack[] = [];\n\tconst packsByKey = new Map<string, AvailableComponentPack[]>();\n\tfor (const available of input.componentPacks) {\n\t\tconst key = `${available.namespace}/${available.pack}`;\n\t\tconst list = packsByKey.get(key) ?? [];\n\t\tlist.push(available);\n\t\tpacksByKey.set(key, list);\n\t}\n\n\tfor (const ref of input.manifest.componentPacks) {\n\t\tconst range = parseSemverRange(ref.range);\n\t\tif (!range) {\n\t\t\tadd(\"invalid_range\", `assembly.componentPacks.${ref.namespace}/${ref.pack}.range`,\n\t\t\t\t`range \"${ref.range}\" is not a valid semver range`);\n\t\t\tcontinue;\n\t\t}\n\t\tconst key = `${ref.namespace}/${ref.pack}`;\n\t\tconst available = packsByKey.get(key) ?? [];\n\t\tconst versions = available.map((entry) => entry.version);\n\t\tconst resolved = resolveVersionRange(range, versions);\n\t\tif (!resolved) {\n\t\t\tadd(\"unresolved_component_pack\", `assembly.componentPacks.${key}`,\n\t\t\t\t`no available version of pack \"${key}\" satisfies range \"${ref.range}\"`);\n\t\t\tcontinue;\n\t\t}\n\t\tconst matched = available.find((entry) => entry.version === resolved)!;\n\t\tresolvedPacks.push({\n\t\t\tpack: ref.pack,\n\t\t\tnamespace: ref.namespace,\n\t\t\tversion: resolved,\n\t\t\trange: ref.range,\n\t\t\tartifactDigest: matched.artifactDigest,\n\t\t\t...(matched.remote ? { remote: matched.remote } : {}),\n\t\t});\n\t}\n\n\t// ── Validate component pack manifests ───────────────────────────────\n\tconst packManifests = input.packManifests ?? [];\n\tfor (const pack of packManifests) {\n\t\ttry {\n\t\t\tassertComponentPackManifest(pack);\n\t\t} catch (error) {\n\t\t\tadd(\"invalid_component_pack\", `packManifests.${pack.namespace}/${pack.pack}`,\n\t\t\t\terror instanceof Error ? error.message : String(error));\n\t\t}\n\t}\n\tconst resolvedPackManifests: ComponentPackManifest[] = [];\n\tfor (const resolved of resolvedPacks) {\n\t\tconst key = `${resolved.namespace}/${resolved.pack}`;\n\t\tconst manifest = packManifests.find((candidate) =>\n\t\t\tcandidate.namespace === resolved.namespace &&\n\t\t\tcandidate.pack === resolved.pack &&\n\t\t\tcandidate.version === resolved.version\n\t\t);\n\t\tif (!manifest) {\n\t\t\tadd(\"missing_component_pack_manifest\", `assembly.componentPacks.${key}`,\n\t\t\t\t`resolved pack \"${key}@${resolved.version}\" has no matching component-pack manifest`);\n\t\t\tcontinue;\n\t\t}\n\t\tif (manifest.artifactDigest !== resolved.artifactDigest) {\n\t\t\tadd(\"component_pack_artifact_digest_mismatch\", `assembly.componentPacks.${key}.artifactDigest`,\n\t\t\t\t`component-pack manifest digest \"${manifest.artifactDigest}\" does not match resolved artifact digest \"${resolved.artifactDigest}\"`);\n\t\t\tcontinue;\n\t\t}\n\t\tresolvedPackManifests.push(manifest);\n\t}\n\n\t// ── Validate contracts ──────────────────────────────────────────────\n\tconst contractsByNamespace = new Map<string, UsageContract>();\n\tfor (const entry of input.manifest.contracts) {\n\t\ttry {\n\t\t\tassertUsageContractDocument(entry.document);\n\t\t} catch (error) {\n\t\t\tadd(\"invalid_contract\", `assembly.contracts.${entry.namespace}`,\n\t\t\t\terror instanceof Error ? error.message : String(error));\n\t\t\tcontinue;\n\t\t}\n\t\tif (entry.document.capability.namespace !== entry.namespace) {\n\t\t\tadd(\"contract_namespace_mismatch\", `assembly.contracts.${entry.namespace}`,\n\t\t\t\t`contract namespace \"${entry.document.capability.namespace}\" does not match assembly namespace \"${entry.namespace}\"`);\n\t\t}\n\t\tconst resolved = resolvedCapabilities.find((capability) => capability.namespace === entry.namespace);\n\t\tif (resolved && entry.document.manifestDigest !== resolved.manifestDigest) {\n\t\t\tadd(\"contract_manifest_digest_mismatch\", `assembly.contracts.${entry.namespace}.manifestDigest`,\n\t\t\t\t`contract manifest digest \"${entry.document.manifestDigest}\" does not match resolved capability digest \"${resolved.manifestDigest}\"`);\n\t\t} else if (resolved) {\n\t\t\tresolved.usageContractDigest = computeUsageContractDocumentDigest(entry.document);\n\t\t}\n\t\tcontractsByNamespace.set(entry.namespace, entry.document.capability);\n\t}\n\n\t// ── Validate bindings ───────────────────────────────────────────────\n\tconst resolvedBindings: ResolvedBinding[] = [];\n\tfor (const entry of input.manifest.bindings) {\n\t\tconst contract = contractsByNamespace.get(entry.capability);\n\t\tif (!contract) {\n\t\t\tadd(\"unknown_contract_for_binding\", `assembly.bindings.${entry.capability}`,\n\t\t\t\t`binding targets capability \"${entry.capability}\" but no contract for it is declared`);\n\t\t\tresolvedBindings.push({\n\t\t\t\tcapability: entry.capability,\n\t\t\t\tbindingDigest: assemblyDigest(entry.binding),\n\t\t\t\tvalid: false,\n\t\t\t\tfindings: [],\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\tconst result = validateBinding({\n\t\t\tcontract,\n\t\t\tbinding: entry.binding,\n\t\t\tpacks: resolvedPackManifests,\n\t\t\tcoreComponents: input.coreComponents ?? [],\n\t\t\tavailableContracts: input.availableContracts ?? [],\n\t\t});\n\t\tresolvedBindings.push({\n\t\t\tcapability: entry.capability,\n\t\t\tbindingDigest: assemblyDigest(entry.binding),\n\t\t\tvalid: result.valid,\n\t\t\tfindings: result.findings,\n\t\t});\n\t\tif (!result.valid) {\n\t\t\tfor (const finding of result.findings) {\n\t\t\t\tadd(\"binding_validation_failed\", `assembly.bindings.${entry.capability}.${finding.path}`,\n\t\t\t\t\tfinding.message);\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── Produce lockfile ─────────────────────────────────────────────────\n\tconst capabilities = [...resolvedCapabilities].sort((a, b) =>\n\t\t\ta.namespace < b.namespace ? -1 : a.namespace > b.namespace ? 1 : 0,\n\t\t);\n\tconst componentPacks = [...resolvedPacks].sort((a, b) => {\n\t\t\tconst key = (e: ResolvedComponentPack) => `${e.namespace}/${e.pack}`;\n\t\t\treturn key(a) < key(b) ? -1 : key(a) > key(b) ? 1 : 0;\n\t\t});\n\tconst bindings = [...resolvedBindings].sort((a, b) =>\n\t\t\ta.capability < b.capability ? -1 : a.capability > b.capability ? 1 : 0,\n\t\t);\n\tconst lockfileBody = {\n\t\tformatVersion: ASSEMBLY_LOCKFILE_FORMAT_VERSION,\n\t\tapplication: input.manifest.application,\n\t\tcapabilities,\n\t\tcomponentPacks,\n\t\tbindings,\n\t};\n\tconst lockfile: AssemblyLockfile = {\n\t\tformatVersion: ASSEMBLY_LOCKFILE_FORMAT_VERSION,\n\t\tapplication: input.manifest.application,\n\t\tassemblyDigest: assemblyDigest(lockfileDigestBody(lockfileBody)),\n\t\tcapabilities,\n\t\tcomponentPacks,\n\t\tbindings,\n\t};\n\n\treturn {\n\t\tlockfile: findings.length === 0 ? lockfile : undefined,\n\t\tfindings,\n\t};\n}\n\n/**\n * Throw with every finding listed, for use as a build step. Returns the\n * lockfile when valid.\n */\nexport function assertAssemblyResolved(input: ResolveAssemblyInput): AssemblyLockfile {\n\tconst result = resolveAssembly(input);\n\tif (result.findings.length === 0) return result.lockfile!;\n\tthrow new Error([\n\t\t`Assembly \"${input.manifest.application}\" could not be resolved:`,\n\t\t...result.findings.map((finding) => ` - [${finding.code}] ${finding.path}: ${finding.message}`),\n\t].join(\"\\n\"));\n}\n\n/**\n * Validate an assembly manifest's bindings as a standalone build gate,\n * without resolving versions. Useful when versions are already locked and\n * only the binding contracts need checking.\n */\nexport function validateAssemblyBindings(input: {\n\tmanifest: AssemblyManifest;\n\tpackManifests?: ComponentPackManifest[];\n\tcoreComponents?: readonly string[];\n\tavailableContracts?: UsageContract[];\n}): AssemblyResult {\n\tassertAssemblyManifest(input.manifest);\n\tconst findings: AssemblyFinding[] = [];\n\tconst add = (code: AssemblyFindingCode, path: string, message: string): void => {\n\t\tfindings.push({ code, path, message });\n\t};\n\n\tconst contractsByNamespace = new Map<string, UsageContract>();\n\tfor (const entry of input.manifest.contracts) {\n\t\ttry {\n\t\t\tassertUsageContractDocument(entry.document);\n\t\t} catch (error) {\n\t\t\tadd(\"invalid_contract\", `assembly.contracts.${entry.namespace}`,\n\t\t\t\terror instanceof Error ? error.message : String(error));\n\t\t\tcontinue;\n\t\t}\n\t\tcontractsByNamespace.set(entry.namespace, entry.document.capability);\n\t}\n\n\tconst packManifests = input.packManifests ?? [];\n\tfor (const entry of input.manifest.bindings) {\n\t\tconst contract = contractsByNamespace.get(entry.capability);\n\t\tif (!contract) {\n\t\t\tadd(\"unknown_contract_for_binding\", `assembly.bindings.${entry.capability}`,\n\t\t\t\t`binding targets capability \"${entry.capability}\" but no contract for it is declared`);\n\t\t\tcontinue;\n\t\t}\n\t\ttry {\n\t\t\tassertBindingValid({\n\t\t\t\tcontract,\n\t\t\t\tbinding: entry.binding,\n\t\t\t\tpacks: packManifests,\n\t\t\t\tcoreComponents: input.coreComponents ?? [],\n\t\t\t\tavailableContracts: input.availableContracts ?? [],\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tadd(\"binding_validation_failed\", `assembly.bindings.${entry.capability}`,\n\t\t\t\terror instanceof Error ? error.message : String(error));\n\t\t}\n\t}\n\n\treturn {\n\t\tlockfile: undefined,\n\t\tfindings,\n\t};\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../index.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport {\n\tassertAdoptionBinding,\n\tassertBindingValid,\n\tvalidateBinding,\n\ttype AdoptionBinding,\n\ttype BindingFinding,\n\ttype ComponentPackManifest,\n} from \"@fabricorg/adoption-bindings\";\nimport {\n\tassertUsageContract,\n\tassertUsageContractDocument,\n\ttype UsageContract,\n\ttype UsageContractDocument,\n} from \"@fabricorg/gen-capability\";\n\n/**\n * Version of the assembly manifest document. A vertical negotiates on this, not\n * on this package's version, and it moves only when the serialized shape changes.\n */\nexport const ASSEMBLY_MANIFEST_FORMAT_VERSION = 2 as const;\n\n/**\n * Version of the resolved lockfile document. Bump when the serialized shape\n * changes in a way a consumer must detect.\n */\nexport const ASSEMBLY_LOCKFILE_FORMAT_VERSION = 2 as const;\n\n// ── Semver range resolution (zero-dependency) ───────────────────────────────\n\ninterface SemverVersion {\n\tmajor: number;\n\tminor: number;\n\tpatch: number;\n\tprerelease: string[];\n}\n\nfunction parseSemver(input: string): SemverVersion | undefined {\n\tconst match = /^(\\d+)\\.(\\d+)\\.(\\d+)(?:-([0-9A-Za-z.-]+))?$/.exec(input.trim());\n\tif (!match) return undefined;\n\treturn {\n\t\tmajor: Number(match[1]),\n\t\tminor: Number(match[2]),\n\t\tpatch: Number(match[3]),\n\t\tprerelease: match[4] ? match[4].split(\".\") : [],\n\t};\n}\n\nfunction comparePrerelease(a: string[], b: string[]): number {\n\t// No prerelease > has prerelease (release > pre-release).\n\tif (a.length === 0 && b.length === 0) return 0;\n\tif (a.length === 0) return 1;\n\tif (b.length === 0) return -1;\n\tfor (let i = 0; i < Math.max(a.length, b.length); i++) {\n\t\tconst ai = a[i];\n\t\tconst bi = b[i];\n\t\tif (ai === undefined) return -1;\n\t\tif (bi === undefined) return 1;\n\t\tconst an = /^\\d+$/.test(ai);\n\t\tconst bn = /^\\d+$/.test(bi);\n\t\tif (an && bn) {\n\t\t\tconst diff = Number(ai) - Number(bi);\n\t\t\tif (diff !== 0) return diff;\n\t\t} else if (an) {\n\t\t\treturn -1;\n\t\t} else if (bn) {\n\t\t\treturn 1;\n\t\t} else {\n\t\t\tif (ai < bi) return -1;\n\t\t\tif (ai > bi) return 1;\n\t\t}\n\t}\n\treturn 0;\n}\n\nfunction compareSemver(a: SemverVersion, b: SemverVersion): number {\n\tif (a.major !== b.major) return a.major - b.major;\n\tif (a.minor !== b.minor) return a.minor - b.minor;\n\tif (a.patch !== b.patch) return a.patch - b.patch;\n\treturn comparePrerelease(a.prerelease, b.prerelease);\n}\n\ntype Comparator = (version: SemverVersion) => boolean;\n\nfunction caretComparator(range: SemverVersion): Comparator {\n\treturn (version) => {\n\t\tif (compareSemver(version, range) < 0) return false;\n\t\tif (version.major !== range.major) return false;\n\t\tif (version.major === 0) {\n\t\t\tif (version.minor !== range.minor) return false;\n\t\t\tif (range.minor === 0 && version.patch !== range.patch) return false;\n\t\t}\n\t\treturn true;\n\t};\n}\n\nfunction tildeComparator(range: SemverVersion): Comparator {\n\treturn (version) => {\n\t\tif (compareSemver(version, range) < 0) return false;\n\t\treturn version.major === range.major && version.minor === range.minor;\n\t};\n}\n\nfunction exactComparator(range: SemverVersion): Comparator {\n\treturn (version) => compareSemver(version, range) === 0;\n}\n\nfunction gteComparator(range: SemverVersion): Comparator {\n\treturn (version) => compareSemver(version, range) >= 0;\n}\n\nfunction gtComparator(range: SemverVersion): Comparator {\n\treturn (version) => compareSemver(version, range) > 0;\n}\n\nfunction lteComparator(range: SemverVersion): Comparator {\n\treturn (version) => compareSemver(version, range) <= 0;\n}\n\nfunction ltComparator(range: SemverVersion): Comparator {\n\treturn (version) => compareSemver(version, range) < 0;\n}\n\nfunction anyComparator(): Comparator {\n\treturn () => true;\n}\n\ninterface ParsedComparator {\n\toperator: string;\n\tcomparator: Comparator;\n\traw: string;\n\trangeVersion: SemverVersion | undefined;\n}\n\nfunction parseComparator(raw: string): ParsedComparator | undefined {\n\tconst trimmed = raw.trim();\n\tif (trimmed === \"*\" || trimmed === \"\") return { operator: \"*\", comparator: anyComparator(), raw: trimmed, rangeVersion: undefined };\n\n\tconst caret = /^(\\^)(\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?)$/.exec(trimmed);\n\tif (caret) {\n\t\tconst version = parseSemver(caret[2]!);\n\t\tif (!version) return undefined;\n\t\treturn { operator: \"^\", comparator: caretComparator(version), raw: trimmed, rangeVersion: version };\n\t}\n\tconst tilde = /^(~)(\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?)$/.exec(trimmed);\n\tif (tilde) {\n\t\tconst version = parseSemver(tilde[2]!);\n\t\tif (!version) return undefined;\n\t\treturn { operator: \"~\", comparator: tildeComparator(version), raw: trimmed, rangeVersion: version };\n\t}\n\tconst op = /^(>=|<=|>|<|=)(\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?)$/.exec(trimmed);\n\tif (op) {\n\t\tconst version = parseSemver(op[2]!);\n\t\tif (!version) return undefined;\n\t\tconst operator = op[1]!;\n\t\tlet comparator: Comparator;\n\t\tswitch (operator) {\n\t\t\tcase \">=\": comparator = gteComparator(version); break;\n\t\t\tcase \"<=\": comparator = lteComparator(version); break;\n\t\t\tcase \">\": comparator = gtComparator(version); break;\n\t\t\tcase \"<\": comparator = ltComparator(version); break;\n\t\t\tdefault: comparator = exactComparator(version); break;\n\t\t}\n\t\treturn { operator, comparator, raw: trimmed, rangeVersion: version };\n\t}\n\tconst bare = /^(\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?)$/.exec(trimmed);\n\tif (bare) {\n\t\tconst version = parseSemver(bare[1]!);\n\t\tif (!version) return undefined;\n\t\treturn { operator: \"=\", comparator: exactComparator(version), raw: trimmed, rangeVersion: version };\n\t}\n\treturn undefined;\n}\n\nfunction comparatorRangeVersion(comparator: ParsedComparator): SemverVersion | undefined {\n\treturn comparator.rangeVersion;\n}\n\n/**\n * A parsed semver range — a conjunction of comparators. Every comparator must\n * be satisfied. This is the subset of npm range syntax that a deterministic\n * resolver needs: `^`, `~`, `>=`, `>`, `<=`, `<`, `=`, exact, and `*`.\n */\nexport interface SemverRange {\n\tcomparators: ParsedComparator[];\n\traw: string;\n}\n\n/**\n * Parse a semver range string into a {@link SemverRange}. Returns `undefined`\n * for an unparseable range rather than throwing, so callers can distinguish\n * \"bad range\" from \"no satisfying version\".\n */\nexport function parseSemverRange(raw: string): SemverRange | undefined {\n\tconst trimmed = raw.trim();\n\tif (!trimmed) return undefined;\n\tconst parts = trimmed.split(/\\s+/);\n\tconst comparators: ParsedComparator[] = [];\n\tfor (const part of parts) {\n\t\tconst parsed = parseComparator(part);\n\t\tif (!parsed) return undefined;\n\t\tcomparators.push(parsed);\n\t}\n\tif (comparators.length === 0) return undefined;\n\treturn { comparators, raw: trimmed };\n}\n\n/**\n * Test whether a version string satisfies a parsed range.\n *\n * Prerelease versions only satisfy a range when a comparator in the range\n * declares a prerelease at the same `[major, minor, patch]` tuple. This\n * follows npm semantics: `^1.0.0` does not match `1.1.0-alpha`, but\n * `^1.0.0-alpha` matches `1.0.0-alpha.2`.\n */\nexport function satisfiesRange(version: string, range: SemverRange): boolean {\n\tconst parsed = parseSemver(version);\n\tif (!parsed) return false;\n\tif (!range.comparators.every((comparator) => comparator.comparator(parsed))) return false;\n\tif (parsed.prerelease.length > 0) {\n\t\treturn range.comparators.some((comparator) => {\n\t\t\tconst rangeVersion = comparatorRangeVersion(comparator);\n\t\t\treturn (\n\t\t\t\trangeVersion !== undefined &&\n\t\t\t\trangeVersion.prerelease.length > 0 &&\n\t\t\t\trangeVersion.major === parsed.major &&\n\t\t\t\trangeVersion.minor === parsed.minor &&\n\t\t\t\trangeVersion.patch === parsed.patch\n\t\t\t);\n\t\t});\n\t}\n\treturn true;\n}\n\n/**\n * Resolve a range against a list of available versions, returning the highest\n * satisfying version. Returns `undefined` when no available version satisfies\n * the range. Deterministic: the same inputs always produce the same result.\n */\nexport function resolveVersionRange(range: SemverRange, available: readonly string[]): string | undefined {\n\tconst parsed = available\n\t\t.map((version) => ({ version, parsed: parseSemver(version) }))\n\t\t.filter((entry): entry is { version: string; parsed: SemverVersion } => entry.parsed !== undefined)\n\t\t.filter((entry) => {\n\t\t\tif (!range.comparators.every((comparator) => comparator.comparator(entry.parsed))) return false;\n\t\t\tif (entry.parsed.prerelease.length > 0) {\n\t\t\t\treturn range.comparators.some((comparator) => {\n\t\t\t\t\tconst rangeVersion = comparatorRangeVersion(comparator);\n\t\t\t\t\treturn (\n\t\t\t\t\t\trangeVersion !== undefined &&\n\t\t\t\t\t\trangeVersion.prerelease.length > 0 &&\n\t\t\t\t\t\trangeVersion.major === entry.parsed.major &&\n\t\t\t\t\t\trangeVersion.minor === entry.parsed.minor &&\n\t\t\t\t\t\trangeVersion.patch === entry.parsed.patch\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn true;\n\t\t})\n\t\t.sort((a, b) => compareSemver(b.parsed, a.parsed));\n\treturn parsed[0]?.version;\n}\n\n// ── Assembly manifest contracts ─────────────────────────────────────────────\n\n/** A capability the vertical assembles, with a version range to resolve. */\nexport interface AssemblyCapabilityReference {\n\tnamespace: string;\n\t/** Semver range, e.g. `^1.0.0`, `>=1.0.0 <2.0.0`, `*`. */\n\trange: string;\n}\n\n/** A component pack the vertical assembles, with a version range to resolve. */\nexport interface AssemblyComponentPackReference {\n\tpack: string;\n\tnamespace: string;\n\trange: string;\n}\n\n/** An adoption binding the vertical declares against a capability. */\nexport interface AssemblyBindingEntry {\n\tcapability: string;\n\tbinding: AdoptionBinding;\n}\n\n/** A usage contract the vertical depends on, supplied inline for validation. */\nexport interface AssemblyContractEntry {\n\tnamespace: string;\n\tdocument: UsageContractDocument;\n}\n\n/**\n * What a vertical assembles: the capabilities it depends on, the component\n * packs it uses, the adoption bindings it declares, and the usage contracts\n * it validates against. This is the build-time input; the lockfile is the\n * resolved output.\n */\nexport interface AssemblyManifest {\n\tformatVersion: typeof ASSEMBLY_MANIFEST_FORMAT_VERSION;\n\t/** Lowercase identifier for the vertical application. */\n\tapplication: string;\n\tcapabilities: AssemblyCapabilityReference[];\n\tcomponentPacks: AssemblyComponentPackReference[];\n\tbindings: AssemblyBindingEntry[];\n\tcontracts: AssemblyContractEntry[];\n}\n\n// ── Available versions for resolution ───────────────────────────────────────\n\n/** A published capability version available for resolution. */\nexport interface AvailableCapability {\n\tnamespace: string;\n\tversion: string;\n\t/** SHA-256 manifest digest from the compiler IR. */\n\tmanifestDigest: string;\n}\n\n/**\n * Where a federated pack is loaded from, and what proves it is the pack that\n * was approved. The artifact digest identifies the pack that was reviewed; the\n * remote entry is what a shell actually executes, so it needs its own integrity\n * value or the review covers something other than what runs.\n */\nexport interface ComponentPackRemote {\n\t/** Remote entry URL the shell loads. */\n\tentry: string;\n\t/** Subresource-integrity value for that entry, e.g. `sha384-…`. */\n\tintegrity: string;\n\t/** Exposed module path keyed by the component name it provides. */\n\texposes: Record<string, string>;\n}\n\n/** A published component pack version available for resolution. */\nexport interface AvailableComponentPack {\n\tpack: string;\n\tnamespace: string;\n\tversion: string;\n\t/** SHA-256 digest of the published component-pack artifact. */\n\tartifactDigest: string;\n\t/** Present when this pack is delivered as a federated remote. */\n\tremote?: ComponentPackRemote;\n}\n\n// ── Lockfile contracts ──────────────────────────────────────────────────────\n\n/** A resolved capability in the lockfile. */\nexport interface ResolvedCapability {\n\tnamespace: string;\n\tversion: string;\n\trange: string;\n\tmanifestDigest: string;\n\t/** Digest of the exact generated usage-contract document validated for this capability. */\n\tusageContractDigest?: string;\n}\n\n/** A resolved component pack in the lockfile. */\nexport interface ResolvedComponentPack {\n\tpack: string;\n\tnamespace: string;\n\tversion: string;\n\trange: string;\n\tartifactDigest: string;\n\t/** Locked delivery binding, when the pack is a federated remote. */\n\tremote?: ComponentPackRemote;\n}\n\n/** A validated adoption binding in the lockfile. */\nexport interface ResolvedBinding {\n\tcapability: string;\n\tbindingDigest: string;\n\tvalid: boolean;\n\tfindings: BindingFinding[];\n}\n\n/**\n * The deterministic, resolved output of assembling a vertical. Every version\n * is locked, every binding is validated, and the whole document carries a\n * canonical digest so two builds with the same inputs produce the same lockfile.\n */\nexport interface AssemblyLockfile {\n\tformatVersion: typeof ASSEMBLY_LOCKFILE_FORMAT_VERSION;\n\tapplication: string;\n\t/** SHA-256 of this lockfile's canonical resolved body, excluding this field. */\n\tassemblyDigest: string;\n\tcapabilities: ResolvedCapability[];\n\tcomponentPacks: ResolvedComponentPack[];\n\tbindings: ResolvedBinding[];\n}\n\n// ── Findings ─────────────────────────────────────────────────────────────────\n\nexport type AssemblyFindingCode =\n\t| \"duplicate_capability\"\n\t| \"duplicate_component_pack\"\n\t| \"unresolved_capability\"\n\t| \"unresolved_component_pack\"\n\t| \"invalid_range\"\n\t| \"unknown_contract_for_binding\"\n\t| \"contract_namespace_mismatch\"\n\t| \"contract_manifest_digest_mismatch\"\n\t| \"binding_validation_failed\"\n\t| \"invalid_contract\"\n\t| \"invalid_component_pack\"\n\t| \"missing_component_pack_manifest\"\n\t| \"component_pack_artifact_digest_mismatch\"\n\t| \"duplicate_contract\";\n\nexport interface AssemblyFinding {\n\tcode: AssemblyFindingCode;\n\tpath: string;\n\tmessage: string;\n}\n\nexport interface AssemblyResult {\n\tlockfile: AssemblyLockfile | undefined;\n\tfindings: AssemblyFinding[];\n}\n\n// ── Stable serialization ───────────────────────────────────────────────────\n\nfunction sortJson(value: unknown): unknown {\n\tif (Array.isArray(value)) return value.map(sortJson);\n\tif (value && typeof value === \"object\") {\n\t\treturn Object.fromEntries(\n\t\t\tObject.entries(value as Record<string, unknown>)\n\t\t\t\t.sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))\n\t\t\t\t.map(([key, child]) => [key, sortJson(child)]),\n\t\t);\n\t}\n\treturn value;\n}\n\nfunction stableStringify(value: unknown): string {\n\treturn JSON.stringify(sortJson(value));\n}\n\nfunction assemblyDigest(value: unknown): string {\n\treturn createHash(\"sha256\").update(stableStringify(value)).digest(\"hex\");\n}\n\n/** Compute the digest stored for an exact generated usage-contract document. */\nexport function computeUsageContractDocumentDigest(document: UsageContractDocument): string {\n\tassertUsageContractDocument(document);\n\treturn assemblyDigest(document);\n}\n\n/**\n * The canonical digest of a lockfile's resolved content.\n *\n * `assertAssemblyLockfile` recomputes this on every load, so publishing it\n * grants nothing an attacker did not already have; it lets tooling and tests\n * construct a self-consistent lockfile instead of hand-fitting a hash. A\n * forged lockfile still fails downstream, because a release binds the assembly\n * digest it was validated against.\n */\nexport function computeAssemblyLockfileDigest(\n\tlockfile: Omit<AssemblyLockfile, \"assemblyDigest\">,\n): string {\n\treturn assemblyDigest(lockfileDigestBody(lockfile));\n}\n\nfunction lockfileDigestBody(lockfile: Omit<AssemblyLockfile, \"assemblyDigest\">): unknown {\n\treturn {\n\t\tformatVersion: lockfile.formatVersion,\n\t\tapplication: lockfile.application,\n\t\tcapabilities: lockfile.capabilities,\n\t\tcomponentPacks: lockfile.componentPacks,\n\t\tbindings: lockfile.bindings,\n\t};\n}\n\n// ── Structural validation ───────────────────────────────────────────────────\n\nfunction fail(path: string, message: string): never {\n\tthrow new Error(`Assembly manifest ${path} ${message}.`);\n}\n\nfunction requireString(value: unknown, path: string): string {\n\tif (typeof value !== \"string\" || !value.trim()) fail(path, \"must be a non-empty string\");\n\treturn value;\n}\n\nfunction requireArray(value: unknown, path: string): unknown[] {\n\tif (!Array.isArray(value)) fail(path, \"must be an array\");\n\treturn value;\n}\n\n/**\n * Structural validation of an assembly manifest. Checks the document's own\n * shape; does not resolve ranges or validate contracts/bindings.\n */\nexport function assertAssemblyManifest(value: unknown, path = \"assembly\"): asserts value is AssemblyManifest {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) fail(path, \"must be an object\");\n\tconst manifest = value as Record<string, unknown>;\n\tif (manifest.formatVersion !== ASSEMBLY_MANIFEST_FORMAT_VERSION) {\n\t\tfail(`${path}.formatVersion`, `must be ${ASSEMBLY_MANIFEST_FORMAT_VERSION}, received ${JSON.stringify(manifest.formatVersion)}`);\n\t}\n\tif (!/^[a-z][a-z0-9-]*$/.test(requireString(manifest.application, `${path}.application`))) {\n\t\tfail(`${path}.application`, \"must be lowercase letters, numbers and hyphens\");\n\t}\n\trequireArray(manifest.capabilities, `${path}.capabilities`).forEach((entry, index) => {\n\t\tconst capability = entry as Record<string, unknown>;\n\t\trequireString(capability?.namespace, `${path}.capabilities[${index}].namespace`);\n\t\trequireString(capability?.range, `${path}.capabilities[${index}].range`);\n\t});\n\trequireArray(manifest.componentPacks, `${path}.componentPacks`).forEach((entry, index) => {\n\t\tconst pack = entry as Record<string, unknown>;\n\t\trequireString(pack?.pack, `${path}.componentPacks[${index}].pack`);\n\t\trequireString(pack?.namespace, `${path}.componentPacks[${index}].namespace`);\n\t\trequireString(pack?.range, `${path}.componentPacks[${index}].range`);\n\t});\n\trequireArray(manifest.bindings, `${path}.bindings`).forEach((entry, index) => {\n\t\tconst binding = entry as Record<string, unknown>;\n\t\trequireString(binding?.capability, `${path}.bindings[${index}].capability`);\n\t\tassertAdoptionBinding(binding?.binding, `${path}.bindings[${index}].binding`);\n\t});\n\trequireArray(manifest.contracts, `${path}.contracts`).forEach((entry, index) => {\n\t\tconst contract = entry as Record<string, unknown>;\n\t\trequireString(contract?.namespace, `${path}.contracts[${index}].namespace`);\n\t\ttry {\n\t\t\tassertUsageContractDocument(contract?.document);\n\t\t} catch (error) {\n\t\t\tfail(`${path}.contracts[${index}].document`, error instanceof Error ? error.message : String(error));\n\t\t}\n\t});\n}\n\n/**\n * Structural validation of a component pack manifest.\n */\nexport function assertComponentPackManifest(value: unknown, path = \"pack\"): asserts value is ComponentPackManifest {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) fail(path, \"must be an object\");\n\tconst pack = value as Record<string, unknown>;\n\trequireString(pack.pack, `${path}.pack`);\n\trequireString(pack.namespace, `${path}.namespace`);\n\trequireString(pack.version, `${path}.version`);\n\tif (!/^\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?$/.test(pack.version as string)) {\n\t\tfail(`${path}.version`, \"must be a semver version\");\n\t}\n\tif (!pack.components || typeof pack.components !== \"object\" || Array.isArray(pack.components)) {\n\t\tfail(`${path}.components`, \"must be an object\");\n\t}\n\tif (!/^[0-9a-f]{64}$/.test(requireString(pack.artifactDigest, `${path}.artifactDigest`))) {\n\t\tfail(`${path}.artifactDigest`, \"must be a lowercase SHA-256 digest\");\n\t}\n}\n\n/**\n * Validate a resolved lockfile and verify that its digest still identifies its\n * exact application, capability, pack, contract, and binding content.\n */\nexport function assertAssemblyLockfile(value: unknown, path = \"lockfile\"): asserts value is AssemblyLockfile {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) fail(path, \"must be an object\");\n\tconst lockfile = value as Record<string, unknown>;\n\tif (lockfile.formatVersion !== ASSEMBLY_LOCKFILE_FORMAT_VERSION) {\n\t\tfail(`${path}.formatVersion`, `must be ${ASSEMBLY_LOCKFILE_FORMAT_VERSION}, received ${JSON.stringify(lockfile.formatVersion)}`);\n\t}\n\tif (!/^[a-z][a-z0-9-]*$/.test(requireString(lockfile.application, `${path}.application`))) {\n\t\tfail(`${path}.application`, \"must be lowercase letters, numbers and hyphens\");\n\t}\n\tif (!/^[0-9a-f]{64}$/.test(requireString(lockfile.assemblyDigest, `${path}.assemblyDigest`))) {\n\t\tfail(`${path}.assemblyDigest`, \"must be a lowercase SHA-256 digest\");\n\t}\n\tconst capabilities = requireArray(lockfile.capabilities, `${path}.capabilities`);\n\tconst componentPacks = requireArray(lockfile.componentPacks, `${path}.componentPacks`);\n\tconst bindings = requireArray(lockfile.bindings, `${path}.bindings`);\n\tconst seenCapabilities = new Set<string>();\n\tfor (const [index, entry] of capabilities.entries()) {\n\t\tconst capability = entry as Record<string, unknown>;\n\t\tconst namespace = String(capability?.namespace);\n\t\tif (seenCapabilities.has(namespace)) {\n\t\t\tfail(`${path}.capabilities[${index}]`, `declares capability \"${namespace}\" a second time`);\n\t\t}\n\t\tseenCapabilities.add(namespace);\n\t\trequireString(capability?.namespace, `${path}.capabilities[${index}].namespace`);\n\t\trequireString(capability?.version, `${path}.capabilities[${index}].version`);\n\t\trequireString(capability?.range, `${path}.capabilities[${index}].range`);\n\t\tif (!/^[0-9a-f]{64}$/.test(requireString(capability?.manifestDigest, `${path}.capabilities[${index}].manifestDigest`))) {\n\t\t\tfail(`${path}.capabilities[${index}].manifestDigest`, \"must be a lowercase SHA-256 digest\");\n\t\t}\n\t\tif (capability?.usageContractDigest !== undefined &&\n\t\t\t!/^[0-9a-f]{64}$/.test(requireString(capability.usageContractDigest, `${path}.capabilities[${index}].usageContractDigest`))) {\n\t\t\tfail(`${path}.capabilities[${index}].usageContractDigest`, \"must be a lowercase SHA-256 digest\");\n\t\t}\n\t}\n\tconst seenPackIdentities = new Set<string>();\n\tfor (const [index, entry] of componentPacks.entries()) {\n\t\tconst pack = entry as Record<string, unknown>;\n\t\trequireString(pack?.pack, `${path}.componentPacks[${index}].pack`);\n\t\tconst identity = `${String(pack?.namespace)}/${String(pack?.pack)}`;\n\t\tif (seenPackIdentities.has(identity)) {\n\t\t\tfail(`${path}.componentPacks[${index}]`, `declares component pack \"${identity}\" a second time; first-match resolution would make the choice arbitrary`);\n\t\t}\n\t\tseenPackIdentities.add(identity);\n\t\trequireString(pack?.namespace, `${path}.componentPacks[${index}].namespace`);\n\t\trequireString(pack?.version, `${path}.componentPacks[${index}].version`);\n\t\trequireString(pack?.range, `${path}.componentPacks[${index}].range`);\n\t\tif (!/^[0-9a-f]{64}$/.test(requireString(pack?.artifactDigest, `${path}.componentPacks[${index}].artifactDigest`))) {\n\t\t\tfail(`${path}.componentPacks[${index}].artifactDigest`, \"must be a lowercase SHA-256 digest\");\n\t\t}\n\t\tif (pack?.remote !== undefined) {\n\t\t\tconst remotePath = `${path}.componentPacks[${index}].remote`;\n\t\t\tconst remote = pack.remote as Record<string, unknown>;\n\t\t\tif (remote === null || typeof remote !== \"object\" || Array.isArray(remote)) fail(remotePath, \"must be an object\");\n\t\t\trequireString(remote.entry, `${remotePath}.entry`);\n\t\t\t// Integrity is the only thing standing between an approved pack and\n\t\t\t// whatever the remote entry happens to serve at load time.\n\t\t\tif (!/^sha(256|384|512)-[A-Za-z0-9+/]+={0,2}$/.test(requireString(remote.integrity, `${remotePath}.integrity`))) {\n\t\t\t\tfail(`${remotePath}.integrity`, \"must be a subresource-integrity value, e.g. \\\"sha384-…\\\"\");\n\t\t\t}\n\t\t\tconst exposes = remote.exposes as Record<string, unknown>;\n\t\t\tif (exposes === null || typeof exposes !== \"object\" || Array.isArray(exposes)) {\n\t\t\t\tfail(`${remotePath}.exposes`, \"must be an object\");\n\t\t\t}\n\t\t\tfor (const [component, modulePath] of Object.entries(exposes)) {\n\t\t\t\trequireString(modulePath, `${remotePath}.exposes.${component}`);\n\t\t\t}\n\t\t}\n\t}\n\tfor (const [index, entry] of bindings.entries()) {\n\t\tconst binding = entry as Record<string, unknown>;\n\t\trequireString(binding?.capability, `${path}.bindings[${index}].capability`);\n\t\tif (!/^[0-9a-f]{64}$/.test(requireString(binding?.bindingDigest, `${path}.bindings[${index}].bindingDigest`))) {\n\t\t\tfail(`${path}.bindings[${index}].bindingDigest`, \"must be a lowercase SHA-256 digest\");\n\t\t}\n\t\tif (binding?.valid !== true) fail(`${path}.bindings[${index}].valid`, \"must be true\");\n\t\trequireArray(binding?.findings, `${path}.bindings[${index}].findings`);\n\t}\n\tconst expected = assemblyDigest(lockfileDigestBody({\n\t\tformatVersion: ASSEMBLY_LOCKFILE_FORMAT_VERSION,\n\t\tapplication: lockfile.application as string,\n\t\tcapabilities: capabilities as unknown as ResolvedCapability[],\n\t\tcomponentPacks: componentPacks as unknown as ResolvedComponentPack[],\n\t\tbindings: bindings as unknown as ResolvedBinding[],\n\t}));\n\tif (lockfile.assemblyDigest !== expected) {\n\t\tfail(`${path}.assemblyDigest`, `does not match resolved lockfile content; expected \"${expected}\"`);\n\t}\n}\n\n/**\n * Verify that the capability artifacts loaded by a runtime are exactly those\n * approved by an integrity-checked assembly lockfile.\n */\nexport function assertAssemblyRuntimeCompatible(\n\tlockfile: AssemblyLockfile,\n\tloadedCapabilities: readonly AvailableCapability[],\n): void {\n\tassertAssemblyLockfile(lockfile);\n\tconst loadedByNamespace = new Map<string, AvailableCapability>();\n\tfor (const loaded of loadedCapabilities) {\n\t\tif (loadedByNamespace.has(loaded.namespace)) {\n\t\t\tthrow new Error(`Loaded capability \"${loaded.namespace}\" is duplicated.`);\n\t\t}\n\t\tloadedByNamespace.set(loaded.namespace, loaded);\n\t}\n\tfor (const approved of lockfile.capabilities) {\n\t\tconst loaded = loadedByNamespace.get(approved.namespace);\n\t\tif (!loaded ||\n\t\t\tloaded.version !== approved.version ||\n\t\t\tloaded.manifestDigest !== approved.manifestDigest) {\n\t\t\tthrow new Error(\n\t\t\t\t`Loaded capability \"${approved.namespace}\" does not match approved capability ` +\n\t\t\t\t`\"${approved.namespace}@${approved.version}\" with manifest digest \"${approved.manifestDigest}\".`,\n\t\t\t);\n\t\t}\n\t}\n\tfor (const loaded of loadedCapabilities) {\n\t\tif (!lockfile.capabilities.some((approved) => approved.namespace === loaded.namespace)) {\n\t\t\tthrow new Error(`Loaded capability \"${loaded.namespace}\" is not approved by assembly \"${lockfile.assemblyDigest}\".`);\n\t\t}\n\t}\n}\n\n// ── Resolution ───────────────────────────────────────────────────────────────\n\nexport interface ResolveAssemblyInput {\n\tmanifest: AssemblyManifest;\n\t/** Published capability versions available for resolution. */\n\tcapabilities: AvailableCapability[];\n\t/** Published component pack versions available for resolution. */\n\tcomponentPacks: AvailableComponentPack[];\n\t/** Component pack manifests for binding validation. */\n\tpackManifests?: ComponentPackManifest[];\n\t/** Core component vocabulary every renderer implements. */\n\tcoreComponents?: readonly string[];\n\t/** Contracts available for cross-capability fragment resolution. */\n\tavailableContracts?: UsageContract[];\n}\n\n/**\n * Resolve an assembly manifest into a deterministic lockfile. This is the\n * single build gate: it resolves version ranges, rejects unresolved or\n * duplicate capability identities, validates usage contracts, component\n * packs, and adoption bindings, and produces a lockfile with a canonical\n * digest.\n *\n * Returns every finding rather than throwing, so one CI run tells a vertical\n * everything it has to change. Use {@link assertAssemblyResolved} to throw\n * on the first invalid result.\n */\nexport function resolveAssembly(input: ResolveAssemblyInput): AssemblyResult {\n\tassertAssemblyManifest(input.manifest);\n\tconst findings: AssemblyFinding[] = [];\n\tconst add = (code: AssemblyFindingCode, path: string, message: string): void => {\n\t\tfindings.push({ code, path, message });\n\t};\n\n\t// ── Duplicate capability identities ──────────────────────────────────\n\tconst capabilityNamespaces = new Set<string>();\n\tfor (const capability of input.manifest.capabilities) {\n\t\tif (capabilityNamespaces.has(capability.namespace)) {\n\t\t\tadd(\"duplicate_capability\", `assembly.capabilities.${capability.namespace}`,\n\t\t\t\t`capability \"${capability.namespace}\" is declared more than once`);\n\t\t}\n\t\tcapabilityNamespaces.add(capability.namespace);\n\t}\n\n\t// ── Duplicate component pack identities ──────────────────────────────\n\tconst packKeys = new Set<string>();\n\tfor (const pack of input.manifest.componentPacks) {\n\t\tconst key = `${pack.namespace}/${pack.pack}`;\n\t\tif (packKeys.has(key)) {\n\t\t\tadd(\"duplicate_component_pack\", `assembly.componentPacks.${key}`,\n\t\t\t\t`component pack \"${key}\" is declared more than once`);\n\t\t}\n\t\tpackKeys.add(key);\n\t}\n\n\t// ── Duplicate contracts ──────────────────────────────────────────────\n\tconst contractNamespaces = new Set<string>();\n\tfor (const contract of input.manifest.contracts) {\n\t\tif (contractNamespaces.has(contract.namespace)) {\n\t\t\tadd(\"duplicate_contract\", `assembly.contracts.${contract.namespace}`,\n\t\t\t\t`contract for \"${contract.namespace}\" is declared more than once`);\n\t\t}\n\t\tcontractNamespaces.add(contract.namespace);\n\t}\n\n\t// ── Resolve capability ranges ────────────────────────────────────────\n\tconst resolvedCapabilities: ResolvedCapability[] = [];\n\tconst capabilitiesByNamespace = new Map<string, AvailableCapability[]>();\n\tfor (const available of input.capabilities) {\n\t\tconst list = capabilitiesByNamespace.get(available.namespace) ?? [];\n\t\tlist.push(available);\n\t\tcapabilitiesByNamespace.set(available.namespace, list);\n\t}\n\n\tfor (const ref of input.manifest.capabilities) {\n\t\tconst range = parseSemverRange(ref.range);\n\t\tif (!range) {\n\t\t\tadd(\"invalid_range\", `assembly.capabilities.${ref.namespace}.range`,\n\t\t\t\t`range \"${ref.range}\" is not a valid semver range`);\n\t\t\tcontinue;\n\t\t}\n\t\tconst available = capabilitiesByNamespace.get(ref.namespace) ?? [];\n\t\tconst versions = available.map((entry) => entry.version);\n\t\tconst resolved = resolveVersionRange(range, versions);\n\t\tif (!resolved) {\n\t\t\tadd(\"unresolved_capability\", `assembly.capabilities.${ref.namespace}`,\n\t\t\t\t`no available version of \"${ref.namespace}\" satisfies range \"${ref.range}\"`);\n\t\t\tcontinue;\n\t\t}\n\t\tconst matched = available.find((entry) => entry.version === resolved)!;\n\t\tresolvedCapabilities.push({\n\t\t\tnamespace: ref.namespace,\n\t\t\tversion: resolved,\n\t\t\trange: ref.range,\n\t\t\tmanifestDigest: matched.manifestDigest,\n\t\t});\n\t}\n\n\t// ── Resolve component pack ranges ────────────────────────────────────\n\tconst resolvedPacks: ResolvedComponentPack[] = [];\n\tconst packsByKey = new Map<string, AvailableComponentPack[]>();\n\tfor (const available of input.componentPacks) {\n\t\tconst key = `${available.namespace}/${available.pack}`;\n\t\tconst list = packsByKey.get(key) ?? [];\n\t\tlist.push(available);\n\t\tpacksByKey.set(key, list);\n\t}\n\n\tfor (const ref of input.manifest.componentPacks) {\n\t\tconst range = parseSemverRange(ref.range);\n\t\tif (!range) {\n\t\t\tadd(\"invalid_range\", `assembly.componentPacks.${ref.namespace}/${ref.pack}.range`,\n\t\t\t\t`range \"${ref.range}\" is not a valid semver range`);\n\t\t\tcontinue;\n\t\t}\n\t\tconst key = `${ref.namespace}/${ref.pack}`;\n\t\tconst available = packsByKey.get(key) ?? [];\n\t\tconst versions = available.map((entry) => entry.version);\n\t\tconst resolved = resolveVersionRange(range, versions);\n\t\tif (!resolved) {\n\t\t\tadd(\"unresolved_component_pack\", `assembly.componentPacks.${key}`,\n\t\t\t\t`no available version of pack \"${key}\" satisfies range \"${ref.range}\"`);\n\t\t\tcontinue;\n\t\t}\n\t\tconst matched = available.find((entry) => entry.version === resolved)!;\n\t\tresolvedPacks.push({\n\t\t\tpack: ref.pack,\n\t\t\tnamespace: ref.namespace,\n\t\t\tversion: resolved,\n\t\t\trange: ref.range,\n\t\t\tartifactDigest: matched.artifactDigest,\n\t\t\t...(matched.remote ? { remote: matched.remote } : {}),\n\t\t});\n\t}\n\n\t// ── Validate component pack manifests ───────────────────────────────\n\tconst packManifests = input.packManifests ?? [];\n\tfor (const pack of packManifests) {\n\t\ttry {\n\t\t\tassertComponentPackManifest(pack);\n\t\t} catch (error) {\n\t\t\tadd(\"invalid_component_pack\", `packManifests.${pack.namespace}/${pack.pack}`,\n\t\t\t\terror instanceof Error ? error.message : String(error));\n\t\t}\n\t}\n\tconst resolvedPackManifests: ComponentPackManifest[] = [];\n\tfor (const resolved of resolvedPacks) {\n\t\tconst key = `${resolved.namespace}/${resolved.pack}`;\n\t\tconst manifest = packManifests.find((candidate) =>\n\t\t\tcandidate.namespace === resolved.namespace &&\n\t\t\tcandidate.pack === resolved.pack &&\n\t\t\tcandidate.version === resolved.version\n\t\t);\n\t\tif (!manifest) {\n\t\t\tadd(\"missing_component_pack_manifest\", `assembly.componentPacks.${key}`,\n\t\t\t\t`resolved pack \"${key}@${resolved.version}\" has no matching component-pack manifest`);\n\t\t\tcontinue;\n\t\t}\n\t\tif (manifest.artifactDigest !== resolved.artifactDigest) {\n\t\t\tadd(\"component_pack_artifact_digest_mismatch\", `assembly.componentPacks.${key}.artifactDigest`,\n\t\t\t\t`component-pack manifest digest \"${manifest.artifactDigest}\" does not match resolved artifact digest \"${resolved.artifactDigest}\"`);\n\t\t\tcontinue;\n\t\t}\n\t\tresolvedPackManifests.push(manifest);\n\t}\n\n\t// ── Validate contracts ──────────────────────────────────────────────\n\tconst contractsByNamespace = new Map<string, UsageContract>();\n\tfor (const entry of input.manifest.contracts) {\n\t\ttry {\n\t\t\tassertUsageContractDocument(entry.document);\n\t\t} catch (error) {\n\t\t\tadd(\"invalid_contract\", `assembly.contracts.${entry.namespace}`,\n\t\t\t\terror instanceof Error ? error.message : String(error));\n\t\t\tcontinue;\n\t\t}\n\t\tif (entry.document.capability.namespace !== entry.namespace) {\n\t\t\tadd(\"contract_namespace_mismatch\", `assembly.contracts.${entry.namespace}`,\n\t\t\t\t`contract namespace \"${entry.document.capability.namespace}\" does not match assembly namespace \"${entry.namespace}\"`);\n\t\t}\n\t\tconst resolved = resolvedCapabilities.find((capability) => capability.namespace === entry.namespace);\n\t\tif (resolved && entry.document.manifestDigest !== resolved.manifestDigest) {\n\t\t\tadd(\"contract_manifest_digest_mismatch\", `assembly.contracts.${entry.namespace}.manifestDigest`,\n\t\t\t\t`contract manifest digest \"${entry.document.manifestDigest}\" does not match resolved capability digest \"${resolved.manifestDigest}\"`);\n\t\t} else if (resolved) {\n\t\t\tresolved.usageContractDigest = computeUsageContractDocumentDigest(entry.document);\n\t\t}\n\t\tcontractsByNamespace.set(entry.namespace, entry.document.capability);\n\t}\n\n\t// ── Validate bindings ───────────────────────────────────────────────\n\tconst resolvedBindings: ResolvedBinding[] = [];\n\tfor (const entry of input.manifest.bindings) {\n\t\tconst contract = contractsByNamespace.get(entry.capability);\n\t\tif (!contract) {\n\t\t\tadd(\"unknown_contract_for_binding\", `assembly.bindings.${entry.capability}`,\n\t\t\t\t`binding targets capability \"${entry.capability}\" but no contract for it is declared`);\n\t\t\tresolvedBindings.push({\n\t\t\t\tcapability: entry.capability,\n\t\t\t\tbindingDigest: assemblyDigest(entry.binding),\n\t\t\t\tvalid: false,\n\t\t\t\tfindings: [],\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\tconst result = validateBinding({\n\t\t\tcontract,\n\t\t\tbinding: entry.binding,\n\t\t\tpacks: resolvedPackManifests,\n\t\t\tcoreComponents: input.coreComponents ?? [],\n\t\t\tavailableContracts: input.availableContracts ?? [],\n\t\t});\n\t\tresolvedBindings.push({\n\t\t\tcapability: entry.capability,\n\t\t\tbindingDigest: assemblyDigest(entry.binding),\n\t\t\tvalid: result.valid,\n\t\t\tfindings: result.findings,\n\t\t});\n\t\tif (!result.valid) {\n\t\t\tfor (const finding of result.findings) {\n\t\t\t\tadd(\"binding_validation_failed\", `assembly.bindings.${entry.capability}.${finding.path}`,\n\t\t\t\t\tfinding.message);\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── Produce lockfile ─────────────────────────────────────────────────\n\tconst capabilities = [...resolvedCapabilities].sort((a, b) =>\n\t\t\ta.namespace < b.namespace ? -1 : a.namespace > b.namespace ? 1 : 0,\n\t\t);\n\tconst componentPacks = [...resolvedPacks].sort((a, b) => {\n\t\t\tconst key = (e: ResolvedComponentPack) => `${e.namespace}/${e.pack}`;\n\t\t\treturn key(a) < key(b) ? -1 : key(a) > key(b) ? 1 : 0;\n\t\t});\n\tconst bindings = [...resolvedBindings].sort((a, b) =>\n\t\t\ta.capability < b.capability ? -1 : a.capability > b.capability ? 1 : 0,\n\t\t);\n\tconst lockfileBody = {\n\t\tformatVersion: ASSEMBLY_LOCKFILE_FORMAT_VERSION,\n\t\tapplication: input.manifest.application,\n\t\tcapabilities,\n\t\tcomponentPacks,\n\t\tbindings,\n\t};\n\tconst lockfile: AssemblyLockfile = {\n\t\tformatVersion: ASSEMBLY_LOCKFILE_FORMAT_VERSION,\n\t\tapplication: input.manifest.application,\n\t\tassemblyDigest: assemblyDigest(lockfileDigestBody(lockfileBody)),\n\t\tcapabilities,\n\t\tcomponentPacks,\n\t\tbindings,\n\t};\n\n\treturn {\n\t\tlockfile: findings.length === 0 ? lockfile : undefined,\n\t\tfindings,\n\t};\n}\n\n/**\n * Throw with every finding listed, for use as a build step. Returns the\n * lockfile when valid.\n */\nexport function assertAssemblyResolved(input: ResolveAssemblyInput): AssemblyLockfile {\n\tconst result = resolveAssembly(input);\n\tif (result.findings.length === 0) return result.lockfile!;\n\tthrow new Error([\n\t\t`Assembly \"${input.manifest.application}\" could not be resolved:`,\n\t\t...result.findings.map((finding) => ` - [${finding.code}] ${finding.path}: ${finding.message}`),\n\t].join(\"\\n\"));\n}\n\n/**\n * Validate an assembly manifest's bindings as a standalone build gate,\n * without resolving versions. Useful when versions are already locked and\n * only the binding contracts need checking.\n */\nexport function validateAssemblyBindings(input: {\n\tmanifest: AssemblyManifest;\n\tpackManifests?: ComponentPackManifest[];\n\tcoreComponents?: readonly string[];\n\tavailableContracts?: UsageContract[];\n}): AssemblyResult {\n\tassertAssemblyManifest(input.manifest);\n\tconst findings: AssemblyFinding[] = [];\n\tconst add = (code: AssemblyFindingCode, path: string, message: string): void => {\n\t\tfindings.push({ code, path, message });\n\t};\n\n\tconst contractsByNamespace = new Map<string, UsageContract>();\n\tfor (const entry of input.manifest.contracts) {\n\t\ttry {\n\t\t\tassertUsageContractDocument(entry.document);\n\t\t} catch (error) {\n\t\t\tadd(\"invalid_contract\", `assembly.contracts.${entry.namespace}`,\n\t\t\t\terror instanceof Error ? error.message : String(error));\n\t\t\tcontinue;\n\t\t}\n\t\tcontractsByNamespace.set(entry.namespace, entry.document.capability);\n\t}\n\n\tconst packManifests = input.packManifests ?? [];\n\tfor (const entry of input.manifest.bindings) {\n\t\tconst contract = contractsByNamespace.get(entry.capability);\n\t\tif (!contract) {\n\t\t\tadd(\"unknown_contract_for_binding\", `assembly.bindings.${entry.capability}`,\n\t\t\t\t`binding targets capability \"${entry.capability}\" but no contract for it is declared`);\n\t\t\tcontinue;\n\t\t}\n\t\ttry {\n\t\t\tassertBindingValid({\n\t\t\t\tcontract,\n\t\t\t\tbinding: entry.binding,\n\t\t\t\tpacks: packManifests,\n\t\t\t\tcoreComponents: input.coreComponents ?? [],\n\t\t\t\tavailableContracts: input.availableContracts ?? [],\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tadd(\"binding_validation_failed\", `assembly.bindings.${entry.capability}`,\n\t\t\t\terror instanceof Error ? error.message : String(error));\n\t\t}\n\t}\n\n\treturn {\n\t\tlockfile: undefined,\n\t\tfindings,\n\t};\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fabricorg/assembly",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Deterministic application assembly: versioned manifests, resolved lockfiles, and a single build gate for capabilities, component packs, and adoption bindings.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -30,16 +30,16 @@
30
30
  "@fabricorg/gen-capability": "^0.5.0"
31
31
  },
32
32
  "peerDependencies": {
33
- "@fabricorg/platform": "^1.2.0"
33
+ "@fabricorg/platform": "^1.3.0"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@types/node": "^22.10.0",
37
37
  "tsup": "^8.5.0",
38
38
  "typescript": "^5.7.3",
39
39
  "vitest": "^4.1.5",
40
- "@fabricorg/adoption-bindings": "^0.2.1",
41
40
  "@fabricorg/gen-capability": "^0.5.0",
42
- "@fabricorg/platform": "^1.2.0"
41
+ "@fabricorg/adoption-bindings": "^0.2.1",
42
+ "@fabricorg/platform": "^1.3.0"
43
43
  },
44
44
  "engines": {
45
45
  "node": ">=20"