commit c9fde521b1640fe7ecbbdd6449a192d8f861f33d
parent 05dabaa5aef5b44c7979c33fe53cebea525c8eef
Author: triesap <tyson@radroots.org>
Date: Mon, 3 Aug 2026 13:24:18 +0000
packages: normalize generated artifact metadata
- Record exact generated package version, license, and SDK repository identity.
- Add deterministic SHA-256 provenance for every emitted TypeScript artifact.
- Preserve unique package names, root-only exports, and private build boundaries.
- Verify frozen install, build, typecheck, generation, and architecture gates.
Diffstat:
8 files changed, 82 insertions(+), 8 deletions(-)
diff --git a/contracts/provenance/typescript/core.json b/contracts/provenance/typescript/core.json
@@ -2,5 +2,12 @@
"crate": "radroots_core_bindings",
"generated": true,
"generator": "radroots_sdk_xtask",
- "package": "@radroots/core-bindings"
+ "license": "MIT OR Apache-2.0",
+ "outputs": {
+ "src/generated/types.ts": "d6e878ebdea0a057afae1af2a426756cb88a3c0700123610a459f796e7d92077"
+ },
+ "package": "@radroots/core-bindings",
+ "repository": "https://github.com/radrootslabs/sdk",
+ "repository_directory": "packages/core-bindings",
+ "version": "0.1.0"
}
diff --git a/contracts/provenance/typescript/event.json b/contracts/provenance/typescript/event.json
@@ -2,11 +2,20 @@
"crate": "radroots_event_bindings",
"generated": true,
"generator": "radroots_sdk_xtask",
+ "license": "MIT OR Apache-2.0",
+ "outputs": {
+ "src/generated/constants.ts": "8918f0fe056d0c4dc59d05cf1245481b93dc4c135a4150bf512e8811e3b524e8",
+ "src/generated/kinds.ts": "e4f01fdf45da2a1dc3dd363bfba5c3ac9adefb0196e40e08fd9affcc65f6c5bc",
+ "src/generated/types.ts": "fe4496950852715c573ff2abc7df8edede7161de75d9c68c3f4d6836e67f829a"
+ },
"package": "@radroots/event-bindings",
+ "repository": "https://github.com/radrootslabs/sdk",
+ "repository_directory": "packages/event-bindings",
"types_sha256": "fe4496950852715c573ff2abc7df8edede7161de75d9c68c3f4d6836e67f829a",
"types_source": "canonical_native_type_snapshot",
"types_source_packages": [
"radroots_event",
"radroots_core"
- ]
+ ],
+ "version": "0.1.0"
}
diff --git a/contracts/provenance/typescript/event_index.json b/contracts/provenance/typescript/event_index.json
@@ -2,5 +2,12 @@
"crate": "radroots_event_index_bindings",
"generated": true,
"generator": "radroots_sdk_xtask",
- "package": "@radroots/event-index-bindings"
+ "license": "MIT OR Apache-2.0",
+ "outputs": {
+ "src/generated/types.ts": "766d0998d909b1601c1f268348158d0273659cb93275da01b9989d91271337ef"
+ },
+ "package": "@radroots/event-index-bindings",
+ "repository": "https://github.com/radrootslabs/sdk",
+ "repository_directory": "packages/event-index-bindings",
+ "version": "0.1.0"
}
diff --git a/contracts/provenance/typescript/identity.json b/contracts/provenance/typescript/identity.json
@@ -2,5 +2,12 @@
"crate": "radroots_identity_bindings",
"generated": true,
"generator": "radroots_sdk_xtask",
- "package": "@radroots/identity-bindings"
+ "license": "MIT OR Apache-2.0",
+ "outputs": {
+ "src/generated/constants.ts": "8dbbe63fa4bead4560d862a8705b55d0259b7f2fc42dd23d48c608258844c66b"
+ },
+ "package": "@radroots/identity-bindings",
+ "repository": "https://github.com/radrootslabs/sdk",
+ "repository_directory": "packages/identity-bindings",
+ "version": "0.1.0"
}
diff --git a/contracts/provenance/typescript/replica_schema.json b/contracts/provenance/typescript/replica_schema.json
@@ -2,5 +2,12 @@
"crate": "radroots_replica_schema_bindings",
"generated": true,
"generator": "radroots_sdk_xtask",
- "package": "@radroots/replica-schema-bindings"
+ "license": "MIT OR Apache-2.0",
+ "outputs": {
+ "src/generated/types.ts": "359a2339ccdd966f805a41560e6b0a321a9e66f9832f7739928ddce58a9bcc1c"
+ },
+ "package": "@radroots/replica-schema-bindings",
+ "repository": "https://github.com/radrootslabs/sdk",
+ "repository_directory": "packages/replica-schema-bindings",
+ "version": "0.1.0"
}
diff --git a/contracts/provenance/typescript/trade.json b/contracts/provenance/typescript/trade.json
@@ -2,12 +2,19 @@
"crate": "radroots_trade_bindings",
"generated": true,
"generator": "radroots_sdk_xtask",
+ "license": "MIT OR Apache-2.0",
+ "outputs": {
+ "src/generated/types.ts": "49560c572206095bd7de5cfd377c234a7f136e4affc13d53516ae2c4b8998e87"
+ },
"package": "@radroots/trade-bindings",
+ "repository": "https://github.com/radrootslabs/sdk",
+ "repository_directory": "packages/trade-bindings",
"types_sha256": "49560c572206095bd7de5cfd377c234a7f136e4affc13d53516ae2c4b8998e87",
"types_source": "canonical_native_type_snapshot",
"types_source_packages": [
"radroots_trade",
"radroots_event",
"radroots_core"
- ]
+ ],
+ "version": "0.1.0"
}
diff --git a/tools/xtask/src/manifest.rs b/tools/xtask/src/manifest.rs
@@ -10,6 +10,10 @@ pub fn package_manifest(spec: PackageSpec) -> serde_json::Value {
json!({
"package": spec.package_name,
"crate": spec.crate_name,
+ "version": "0.1.0",
+ "license": "MIT OR Apache-2.0",
+ "repository": "https://github.com/radrootslabs/sdk",
+ "repository_directory": spec.package_dir,
"generator": "radroots_sdk_xtask",
"generated": false
})
@@ -35,5 +39,15 @@ mod tests {
let manifest = package_manifest(package_specs()[0]);
assert_eq!(manifest["package"], package_specs()[0].package_name);
assert_eq!(manifest["crate"], package_specs()[0].crate_name);
+ assert_eq!(manifest["version"], "0.1.0");
+ assert_eq!(manifest["license"], "MIT OR Apache-2.0");
+ assert_eq!(
+ manifest["repository"],
+ "https://github.com/radrootslabs/sdk"
+ );
+ assert_eq!(
+ manifest["repository_directory"],
+ package_specs()[0].package_dir
+ );
}
}
diff --git a/tools/xtask/src/output.rs b/tools/xtask/src/output.rs
@@ -102,7 +102,7 @@ impl PackageOutput {
pub fn provenance_file(&self) -> GeneratedFile {
GeneratedFile {
relative_path: manifest_relative_path(self.spec),
- contents: render_manifest(self.spec),
+ contents: render_manifest(self),
}
}
}
@@ -211,9 +211,25 @@ fn structured_imports_ts(imports: &[TypeScriptImport]) -> Option<String> {
)
}
-fn render_manifest(spec: PackageSpec) -> String {
+fn render_manifest(output: &PackageOutput) -> String {
+ let spec = output.spec;
let mut value = package_manifest(spec);
value["generated"] = serde_json::Value::Bool(true);
+ value["outputs"] = serde_json::Value::Object(
+ output
+ .files()
+ .into_iter()
+ .map(|file| {
+ (
+ file.relative_path,
+ serde_json::Value::String(format!(
+ "{:x}",
+ Sha256::digest(file.contents.as_bytes())
+ )),
+ )
+ })
+ .collect(),
+ );
if matches!(spec.key, "event" | "trade") {
let (sha256, source_packages) = match spec.key {
"event" => (EVENT_BINDINGS_TYPES_SHA256, EVENT_NATIVE_SOURCES),