diff --git a/AGENTS.md b/AGENTS.md index dbbe2ce..4d2a29c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -322,7 +322,7 @@ cargo xtask compliance cargo xtask wire ``` -Format changed Rust with `cargo fmt --all`. Before handoff, run: +Format changed Rust with `cargo fmt --all`. The authoritative repository gate is: ```text cargo xtask ci @@ -334,6 +334,20 @@ exchange and product conformance, fixtures, compatibility matrix, bindings, package smoke tests, release evidence, fuzz smoke tests, WASM, and compliance evidence. +### GitHub-first verification policy + +Use GitHub CI as the single default verification run. Push the bounded change +to its PR without first running local build, test, lint, formal, package, fuzz, +or secret-scanning gates. Running the same expensive suite locally and then in +GitHub duplicates work without removing the required hosted gate. + +If GitHub CI fails, inspect the hosted failure first. Reproduce only the +specific failing check locally when that is useful for diagnosis, then push the +fix and let GitHub CI verify it again. Run local checks before the first push +only when the user explicitly requests them or when a repository-local result +is required to construct the change. Never report an unrun local check as +passing; cite the successful GitHub run as the merge evidence. + CI separately enforces dependency policy and secret scanning. Release work must also pass `cargo xtask release-check`. @@ -341,17 +355,17 @@ Do not claim completion because a narrow crate test passed when the change affects wire compatibility, another language, a layer boundary, or generated evidence. Report exactly which checks ran and any checks that could not run. -### Mandatory pre-commit secret scan and correction +### Secret scan and correction -Before every commit, stage only the intended changes and scan that exact staged -diff: +GitHub CI's full-history Gitleaks job is the required merge gate. If that job +fails, or if the user explicitly requests a local pre-commit scan, stage only +the intended changes and scan that exact staged diff: ```text gitleaks git --pre-commit --staged --redact --no-banner ``` -Use gitleaks `v8.28.0`, matching `.github/workflows/ci.yml`. Do not create the -commit until this scan passes. +Use gitleaks `v8.28.0`, matching `.github/workflows/ci.yml`. If the staged scan reports a finding: @@ -365,14 +379,14 @@ If the staged scan reports a finding: fingerprint-specific `.gitleaksignore` entry; 5. never add a broad path, rule, regex, or file allowlist. -After the local commits are complete, also run CI's full-history command: +CI runs the full-history command: ```text gitleaks git --redact --no-banner ``` -This second scan verifies commit-specific fingerprints and full CI parity. It -is not a substitute for correcting staged content before the commit. +This scan verifies commit-specific fingerprints. A local staged scan, when one +is run, is not a substitute for correcting staged content before the commit. ## Change discipline for agents diff --git a/Cargo.lock b/Cargo.lock index 86afca7..c2dd4d4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -226,11 +226,11 @@ dependencies = [ "auths-proof-exchange-memory", "auths-proof-exchange-model", "auths-proof-exchange-port", + "auths-proof-sdk", "auths-raw-key", "auths-receipts", "auths-registries", "auths-runtime", - "auths-sdk", "auths-signature", "ed25519-dalek 2.2.0", "iroh", @@ -389,7 +389,7 @@ name = "auths-deployment" version = "0.1.0" dependencies = [ "auths-enforcement", - "auths-sdk", + "auths-proof-sdk", "thiserror 2.0.19", ] @@ -437,7 +437,7 @@ name = "auths-enforcement" version = "0.1.0" dependencies = [ "auths-profile-api", - "auths-sdk", + "auths-proof-sdk", "thiserror 2.0.19", ] @@ -494,7 +494,7 @@ dependencies = [ "auths-lifecycle", "auths-model", "auths-profile-api", - "auths-sdk", + "auths-proof-sdk", "base64ct", "hex", "proptest", @@ -520,10 +520,10 @@ dependencies = [ "auths-model", "auths-ports", "auths-profile-api", + "auths-proof-sdk", "auths-raw-key", "auths-registries", "auths-runtime", - "auths-sdk", "auths-signature", "auths-stores", "axum", @@ -558,7 +558,7 @@ dependencies = [ "auths-lifecycle", "auths-model", "auths-profile-api", - "auths-sdk", + "auths-proof-sdk", "auths-stores", "hex", "serde", @@ -581,10 +581,10 @@ dependencies = [ "auths-model", "auths-ports", "auths-profile-api", + "auths-proof-sdk", "auths-raw-key", "auths-registries", "auths-runtime", - "auths-sdk", "auths-signature", "auths-stores", "axum", @@ -708,7 +708,7 @@ dependencies = [ "auths-lifecycle", "auths-model", "auths-profile-api", - "auths-sdk", + "auths-proof-sdk", "auths-stores", "hex", "serde", @@ -729,7 +729,7 @@ dependencies = [ "auths-model", "auths-opentofu", "auths-profile-api", - "auths-sdk", + "auths-proof-sdk", "auths-stores", "axum", "dotenvy", @@ -775,7 +775,7 @@ dependencies = [ "auths-lifecycle", "auths-model", "auths-profile-api", - "auths-sdk", + "auths-proof-sdk", "auths-stores", "hex", "serde", @@ -799,7 +799,7 @@ dependencies = [ "auths-model", "auths-postgresql", "auths-profile-api", - "auths-sdk", + "auths-proof-sdk", "auths-stores", "axum", "dotenvy", @@ -1056,6 +1056,29 @@ dependencies = [ "pyo3", ] +[[package]] +name = "auths-proof-sdk" +version = "0.1.0" +dependencies = [ + "auths-author", + "auths-codec", + "auths-custody", + "auths-did-keri", + "auths-did-key", + "auths-model", + "auths-ports", + "auths-profile-api", + "auths-profile-domains", + "auths-profile-mcp", + "auths-raw-key", + "auths-registries", + "auths-runtime", + "auths-signature", + "auths-testkit", + "auths-verifier", + "thiserror 2.0.19", +] + [[package]] name = "auths-proof-wasm" version = "0.1.0" @@ -1083,10 +1106,10 @@ dependencies = [ "auths-lifecycle", "auths-model", "auths-profile-api", + "auths-proof-sdk", "auths-raw-key", "auths-receipts", "auths-registries", - "auths-sdk", "auths-signature", "auths-stores", "auths-verifier", @@ -1111,11 +1134,11 @@ dependencies = [ "auths-model", "auths-ports", "auths-profile-api", + "auths-proof-sdk", "auths-radicle", "auths-raw-key", "auths-registries", "auths-runtime", - "auths-sdk", "auths-signature", "auths-stores", "axum", @@ -1163,7 +1186,7 @@ dependencies = [ "auths-lifecycle", "auths-model", "auths-profile-api", - "auths-sdk", + "auths-proof-sdk", "auths-stores", "ed25519-dalek 2.2.0", "hex", @@ -1192,11 +1215,11 @@ dependencies = [ "auths-proof-exchange-iroh", "auths-proof-exchange-model", "auths-proof-exchange-port", + "auths-proof-sdk", "auths-raw-key", "auths-records-api", "auths-registries", "auths-runtime", - "auths-sdk", "auths-signature", "auths-stores", "axum", @@ -1258,29 +1281,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "auths-sdk" -version = "0.1.0" -dependencies = [ - "auths-author", - "auths-codec", - "auths-custody", - "auths-did-keri", - "auths-did-key", - "auths-model", - "auths-ports", - "auths-profile-api", - "auths-profile-domains", - "auths-profile-mcp", - "auths-raw-key", - "auths-registries", - "auths-runtime", - "auths-signature", - "auths-testkit", - "auths-verifier", - "thiserror 2.0.19", -] - [[package]] name = "auths-signature" version = "0.1.0" @@ -1335,10 +1335,10 @@ dependencies = [ "auths-model", "auths-ports", "auths-profile-api", + "auths-proof-sdk", "auths-raw-key", "auths-registries", "auths-runtime", - "auths-sdk", "auths-signature", "ed25519-dalek 2.2.0", "hex", @@ -1376,10 +1376,10 @@ dependencies = [ "auths-model", "auths-ports", "auths-profile-api", + "auths-proof-sdk", "auths-raw-key", "auths-registries", "auths-runtime", - "auths-sdk", "auths-signature", "auths-stripe", "axum", @@ -1404,7 +1404,7 @@ name = "auths-stripe-payment-authorize-demo" version = "0.1.0" dependencies = [ "auths-profile-api", - "auths-sdk", + "auths-proof-sdk", "auths-stripe", "auths-stripe-payment-demo-common", "axum", @@ -1425,7 +1425,7 @@ name = "auths-stripe-payment-cancel-demo" version = "0.1.0" dependencies = [ "auths-profile-api", - "auths-sdk", + "auths-proof-sdk", "auths-stripe", "auths-stripe-payment-demo-common", "axum", @@ -1446,7 +1446,7 @@ name = "auths-stripe-payment-capture-demo" version = "0.1.0" dependencies = [ "auths-profile-api", - "auths-sdk", + "auths-proof-sdk", "auths-stripe", "auths-stripe-payment-demo-common", "axum", @@ -1467,7 +1467,7 @@ name = "auths-stripe-payment-collect-demo" version = "0.1.0" dependencies = [ "auths-profile-api", - "auths-sdk", + "auths-proof-sdk", "auths-stripe", "auths-stripe-payment-demo-common", "axum", @@ -1491,10 +1491,10 @@ dependencies = [ "auths-codec", "auths-model", "auths-ports", + "auths-proof-sdk", "auths-raw-key", "auths-registries", "auths-runtime", - "auths-sdk", "auths-signature", "auths-stripe", "ed25519-dalek 2.2.0", @@ -1509,7 +1509,7 @@ name = "auths-stripe-payment-mandate-demo" version = "0.1.0" dependencies = [ "auths-profile-api", - "auths-sdk", + "auths-proof-sdk", "auths-stripe", "auths-stripe-payment-demo-common", "axum", @@ -1546,7 +1546,7 @@ version = "0.1.0" dependencies = [ "auths-model", "auths-profile-api", - "auths-sdk", + "auths-proof-sdk", "auths-stripe", "auths-stripe-payment-demo-common", "axum", @@ -1584,7 +1584,7 @@ version = "0.1.0" dependencies = [ "auths-model", "auths-profile-api", - "auths-sdk", + "auths-proof-sdk", "auths-stripe", "auths-stripe-payment-demo-common", "axum", @@ -1605,7 +1605,7 @@ version = "0.1.0" dependencies = [ "auths-model", "auths-profile-api", - "auths-sdk", + "auths-proof-sdk", "auths-stripe", "auths-stripe-payment-demo-common", "axum", diff --git a/Cargo.toml b/Cargo.toml index 04d8342..9c1338a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -152,7 +152,7 @@ auths-stores = { version = "0.1.0", path = "product/stores/auths-stores" } auths-config = { version = "0.1.0", path = "product/config/auths-config" } auths-cache = { version = "0.1.0", path = "product/cache/auths-cache" } auths-operations = { version = "0.1.0", path = "product/operations/auths-operations" } -auths-sdk = { version = "0.1.0", path = "product/sdk/auths-sdk" } +auths-sdk = { package = "auths-proof-sdk", version = "0.1.0", path = "product/sdk/auths-sdk" } auths-profile-kit = { version = "0.1.0", path = "product/sdk/auths-profile-kit" } auths-bounded-policy = { version = "0.1.0", path = "product/policy/auths-bounded-policy", default-features = false } auths-enforcement = { version = "0.1.0", path = "product/integrations/auths-enforcement" } diff --git a/architecture.toml b/architecture.toml index 41a5e7c..a924759 100644 --- a/architecture.toml +++ b/architecture.toml @@ -169,7 +169,7 @@ auths-receipts = "product" auths-registries = "core" auths-resolver-did-web = "product" auths-runtime = "product" -auths-sdk = "product" +auths-proof-sdk = "product" auths-signature = "core" auths-spiffe-x509 = "core" auths-stores = "product" diff --git a/architecture/dependency-graph.dot b/architecture/dependency-graph.dot index 78c0f98..576e810 100644 --- a/architecture/dependency-graph.dot +++ b/architecture/dependency-graph.dot @@ -63,6 +63,7 @@ digraph auths_architecture { "auths-proof-fuzz" [group="core"]; "auths-proof-offline-example" [group="demos"]; "auths-proof-python" [group="bindings"]; + "auths-proof-sdk" [group="product"]; "auths-proof-wasm" [group="bindings"]; "auths-radicle" [group="product"]; "auths-radicle-demo" [group="demos"]; @@ -73,7 +74,6 @@ digraph auths_architecture { "auths-registries" [group="core"]; "auths-resolver-did-web" [group="product"]; "auths-runtime" [group="product"]; - "auths-sdk" [group="product"]; "auths-signature" [group="core"]; "auths-spiffe-x509" [group="core"]; "auths-stores" [group="product"]; @@ -107,11 +107,11 @@ digraph auths_architecture { "auths-apps-testkit" -> "auths-proof-exchange-memory" [label="normal"]; "auths-apps-testkit" -> "auths-proof-exchange-model" [label="normal"]; "auths-apps-testkit" -> "auths-proof-exchange-port" [label="normal"]; + "auths-apps-testkit" -> "auths-proof-sdk" [label="normal"]; "auths-apps-testkit" -> "auths-raw-key" [label="normal"]; "auths-apps-testkit" -> "auths-receipts" [label="normal"]; "auths-apps-testkit" -> "auths-registries" [label="normal"]; "auths-apps-testkit" -> "auths-runtime" [label="normal"]; - "auths-apps-testkit" -> "auths-sdk" [label="normal"]; "auths-apps-testkit" -> "auths-signature" [label="normal"]; "auths-assurance" -> "auths-model" [label="normal"]; "auths-author" -> "auths-authority" [label="normal"]; @@ -149,7 +149,7 @@ digraph auths_architecture { "auths-custody" -> "auths-author" [label="normal"]; "auths-custody" -> "auths-model" [label="normal"]; "auths-deployment" -> "auths-enforcement" [label="normal"]; - "auths-deployment" -> "auths-sdk" [label="normal"]; + "auths-deployment" -> "auths-proof-sdk" [label="normal"]; "auths-did-keri" -> "auths-codec" [label="dev"]; "auths-did-keri" -> "auths-model" [label="normal"]; "auths-did-keri" -> "auths-ports" [label="normal"]; @@ -162,7 +162,7 @@ digraph auths_architecture { "auths-did-web" -> "auths-multikey" [label="normal"]; "auths-did-web" -> "auths-ports" [label="normal"]; "auths-enforcement" -> "auths-profile-api" [label="normal"]; - "auths-enforcement" -> "auths-sdk" [label="normal"]; + "auths-enforcement" -> "auths-proof-sdk" [label="normal"]; "auths-evidence-assemblers" -> "auths-codec" [label="normal"]; "auths-evidence-assemblers" -> "auths-hsm-attested" [label="normal"]; "auths-evidence-assemblers" -> "auths-model" [label="normal"]; @@ -190,7 +190,7 @@ digraph auths_architecture { "auths-github" -> "auths-lifecycle" [label="normal"]; "auths-github" -> "auths-model" [label="normal"]; "auths-github" -> "auths-profile-api" [label="normal"]; - "auths-github" -> "auths-sdk" [label="normal"]; + "auths-github" -> "auths-proof-sdk" [label="normal"]; "auths-github-demo" -> "auths-author" [label="normal"]; "auths-github-demo" -> "auths-codec" [label="normal"]; "auths-github-demo" -> "auths-github" [label="normal"]; @@ -198,10 +198,10 @@ digraph auths_architecture { "auths-github-demo" -> "auths-model" [label="normal"]; "auths-github-demo" -> "auths-ports" [label="normal"]; "auths-github-demo" -> "auths-profile-api" [label="normal"]; + "auths-github-demo" -> "auths-proof-sdk" [label="normal"]; "auths-github-demo" -> "auths-raw-key" [label="normal"]; "auths-github-demo" -> "auths-registries" [label="normal"]; "auths-github-demo" -> "auths-runtime" [label="normal"]; - "auths-github-demo" -> "auths-sdk" [label="normal"]; "auths-github-demo" -> "auths-signature" [label="normal"]; "auths-github-demo" -> "auths-stores" [label="normal"]; "auths-hsm-attested" -> "auths-model" [label="normal"]; @@ -210,7 +210,7 @@ digraph auths_architecture { "auths-kubernetes" -> "auths-lifecycle" [label="normal"]; "auths-kubernetes" -> "auths-model" [label="normal"]; "auths-kubernetes" -> "auths-profile-api" [label="normal"]; - "auths-kubernetes" -> "auths-sdk" [label="normal"]; + "auths-kubernetes" -> "auths-proof-sdk" [label="normal"]; "auths-kubernetes" -> "auths-stores" [label="dev"]; "auths-kubernetes-demo" -> "auths-author" [label="normal"]; "auths-kubernetes-demo" -> "auths-codec" [label="normal"]; @@ -219,10 +219,10 @@ digraph auths_architecture { "auths-kubernetes-demo" -> "auths-model" [label="normal"]; "auths-kubernetes-demo" -> "auths-ports" [label="normal"]; "auths-kubernetes-demo" -> "auths-profile-api" [label="normal"]; + "auths-kubernetes-demo" -> "auths-proof-sdk" [label="normal"]; "auths-kubernetes-demo" -> "auths-raw-key" [label="normal"]; "auths-kubernetes-demo" -> "auths-registries" [label="normal"]; "auths-kubernetes-demo" -> "auths-runtime" [label="normal"]; - "auths-kubernetes-demo" -> "auths-sdk" [label="normal"]; "auths-kubernetes-demo" -> "auths-signature" [label="normal"]; "auths-kubernetes-demo" -> "auths-stores" [label="normal"]; "auths-lab-wasm-bench" -> "auths-codec" [label="normal"]; @@ -248,14 +248,14 @@ digraph auths_architecture { "auths-opentofu" -> "auths-lifecycle" [label="normal"]; "auths-opentofu" -> "auths-model" [label="normal"]; "auths-opentofu" -> "auths-profile-api" [label="normal"]; - "auths-opentofu" -> "auths-sdk" [label="normal"]; + "auths-opentofu" -> "auths-proof-sdk" [label="normal"]; "auths-opentofu" -> "auths-stores" [label="dev"]; "auths-opentofu-demo" -> "auths-apps-testkit" [label="normal"]; "auths-opentofu-demo" -> "auths-lifecycle" [label="normal"]; "auths-opentofu-demo" -> "auths-model" [label="normal"]; "auths-opentofu-demo" -> "auths-opentofu" [label="normal"]; "auths-opentofu-demo" -> "auths-profile-api" [label="normal"]; - "auths-opentofu-demo" -> "auths-sdk" [label="normal"]; + "auths-opentofu-demo" -> "auths-proof-sdk" [label="normal"]; "auths-opentofu-demo" -> "auths-stores" [label="normal"]; "auths-operations" -> "auths-codec" [label="dev"]; "auths-operations" -> "auths-codec" [label="normal"]; @@ -268,14 +268,14 @@ digraph auths_architecture { "auths-postgresql" -> "auths-lifecycle" [label="normal"]; "auths-postgresql" -> "auths-model" [label="normal"]; "auths-postgresql" -> "auths-profile-api" [label="normal"]; - "auths-postgresql" -> "auths-sdk" [label="normal"]; + "auths-postgresql" -> "auths-proof-sdk" [label="normal"]; "auths-postgresql" -> "auths-stores" [label="dev"]; "auths-postgresql-demo" -> "auths-apps-testkit" [label="normal"]; "auths-postgresql-demo" -> "auths-lifecycle" [label="normal"]; "auths-postgresql-demo" -> "auths-model" [label="normal"]; "auths-postgresql-demo" -> "auths-postgresql" [label="normal"]; "auths-postgresql-demo" -> "auths-profile-api" [label="normal"]; - "auths-postgresql-demo" -> "auths-sdk" [label="normal"]; + "auths-postgresql-demo" -> "auths-proof-sdk" [label="normal"]; "auths-postgresql-demo" -> "auths-stores" [label="normal"]; "auths-profile-api" -> "auths-model" [label="normal"]; "auths-profile-api" -> "auths-verifier" [label="normal"]; @@ -356,6 +356,22 @@ digraph auths_architecture { "auths-proof-offline-example" -> "auths-registries" [label="normal"]; "auths-proof-offline-example" -> "auths-signature" [label="normal"]; "auths-proof-python" -> "auths-proof-wasm" [label="normal"]; + "auths-proof-sdk" -> "auths-author" [label="normal"]; + "auths-proof-sdk" -> "auths-codec" [label="dev"]; + "auths-proof-sdk" -> "auths-custody" [label="normal"]; + "auths-proof-sdk" -> "auths-did-keri" [label="normal"]; + "auths-proof-sdk" -> "auths-did-key" [label="normal"]; + "auths-proof-sdk" -> "auths-model" [label="normal"]; + "auths-proof-sdk" -> "auths-ports" [label="normal"]; + "auths-proof-sdk" -> "auths-profile-api" [label="normal"]; + "auths-proof-sdk" -> "auths-profile-domains" [label="normal"]; + "auths-proof-sdk" -> "auths-profile-mcp" [label="normal"]; + "auths-proof-sdk" -> "auths-raw-key" [label="normal"]; + "auths-proof-sdk" -> "auths-registries" [label="normal"]; + "auths-proof-sdk" -> "auths-runtime" [label="normal"]; + "auths-proof-sdk" -> "auths-signature" [label="normal"]; + "auths-proof-sdk" -> "auths-testkit" [label="dev"]; + "auths-proof-sdk" -> "auths-verifier" [label="normal"]; "auths-proof-wasm" -> "auths-codec" [label="normal"]; "auths-proof-wasm" -> "auths-did-keri" [label="normal"]; "auths-proof-wasm" -> "auths-did-key" [label="normal"]; @@ -372,10 +388,10 @@ digraph auths_architecture { "auths-radicle" -> "auths-lifecycle" [label="normal"]; "auths-radicle" -> "auths-model" [label="normal"]; "auths-radicle" -> "auths-profile-api" [label="normal"]; + "auths-radicle" -> "auths-proof-sdk" [label="normal"]; "auths-radicle" -> "auths-raw-key" [label="dev"]; "auths-radicle" -> "auths-receipts" [label="normal"]; "auths-radicle" -> "auths-registries" [label="dev"]; - "auths-radicle" -> "auths-sdk" [label="normal"]; "auths-radicle" -> "auths-signature" [label="dev"]; "auths-radicle" -> "auths-stores" [label="dev"]; "auths-radicle" -> "auths-verifier" [label="normal"]; @@ -385,11 +401,11 @@ digraph auths_architecture { "auths-radicle-demo" -> "auths-model" [label="normal"]; "auths-radicle-demo" -> "auths-ports" [label="normal"]; "auths-radicle-demo" -> "auths-profile-api" [label="normal"]; + "auths-radicle-demo" -> "auths-proof-sdk" [label="normal"]; "auths-radicle-demo" -> "auths-radicle" [label="normal"]; "auths-radicle-demo" -> "auths-raw-key" [label="normal"]; "auths-radicle-demo" -> "auths-registries" [label="normal"]; "auths-radicle-demo" -> "auths-runtime" [label="normal"]; - "auths-radicle-demo" -> "auths-sdk" [label="normal"]; "auths-radicle-demo" -> "auths-signature" [label="normal"]; "auths-radicle-demo" -> "auths-stores" [label="normal"]; "auths-raw-key" -> "auths-model" [label="normal"]; @@ -400,7 +416,7 @@ digraph auths_architecture { "auths-records-api" -> "auths-lifecycle" [label="normal"]; "auths-records-api" -> "auths-model" [label="normal"]; "auths-records-api" -> "auths-profile-api" [label="normal"]; - "auths-records-api" -> "auths-sdk" [label="normal"]; + "auths-records-api" -> "auths-proof-sdk" [label="normal"]; "auths-records-api" -> "auths-stores" [label="dev"]; "auths-records-demo" -> "auths-author" [label="normal"]; "auths-records-demo" -> "auths-bounded-policy" [label="normal"]; @@ -412,11 +428,11 @@ digraph auths_architecture { "auths-records-demo" -> "auths-proof-exchange-iroh" [label="normal"]; "auths-records-demo" -> "auths-proof-exchange-model" [label="normal"]; "auths-records-demo" -> "auths-proof-exchange-port" [label="normal"]; + "auths-records-demo" -> "auths-proof-sdk" [label="normal"]; "auths-records-demo" -> "auths-raw-key" [label="normal"]; "auths-records-demo" -> "auths-records-api" [label="normal"]; "auths-records-demo" -> "auths-registries" [label="normal"]; "auths-records-demo" -> "auths-runtime" [label="normal"]; - "auths-records-demo" -> "auths-sdk" [label="normal"]; "auths-records-demo" -> "auths-signature" [label="normal"]; "auths-records-demo" -> "auths-stores" [label="normal"]; "auths-registries" -> "auths-model" [label="normal"]; @@ -435,22 +451,6 @@ digraph auths_architecture { "auths-runtime" -> "auths-receipts" [label="normal"]; "auths-runtime" -> "auths-registries" [label="normal"]; "auths-runtime" -> "auths-verifier" [label="normal"]; - "auths-sdk" -> "auths-author" [label="normal"]; - "auths-sdk" -> "auths-codec" [label="dev"]; - "auths-sdk" -> "auths-custody" [label="normal"]; - "auths-sdk" -> "auths-did-keri" [label="normal"]; - "auths-sdk" -> "auths-did-key" [label="normal"]; - "auths-sdk" -> "auths-model" [label="normal"]; - "auths-sdk" -> "auths-ports" [label="normal"]; - "auths-sdk" -> "auths-profile-api" [label="normal"]; - "auths-sdk" -> "auths-profile-domains" [label="normal"]; - "auths-sdk" -> "auths-profile-mcp" [label="normal"]; - "auths-sdk" -> "auths-raw-key" [label="normal"]; - "auths-sdk" -> "auths-registries" [label="normal"]; - "auths-sdk" -> "auths-runtime" [label="normal"]; - "auths-sdk" -> "auths-signature" [label="normal"]; - "auths-sdk" -> "auths-testkit" [label="dev"]; - "auths-sdk" -> "auths-verifier" [label="normal"]; "auths-signature" -> "auths-model" [label="normal"]; "auths-signature" -> "auths-ports" [label="normal"]; "auths-spiffe-x509" -> "auths-model" [label="normal"]; @@ -469,10 +469,10 @@ digraph auths_architecture { "auths-stripe" -> "auths-model" [label="normal"]; "auths-stripe" -> "auths-ports" [label="dev"]; "auths-stripe" -> "auths-profile-api" [label="normal"]; + "auths-stripe" -> "auths-proof-sdk" [label="normal"]; "auths-stripe" -> "auths-raw-key" [label="dev"]; "auths-stripe" -> "auths-registries" [label="dev"]; "auths-stripe" -> "auths-runtime" [label="dev"]; - "auths-stripe" -> "auths-sdk" [label="normal"]; "auths-stripe" -> "auths-signature" [label="dev"]; "auths-stripe-connect-transfer-demo" -> "auths-stripe" [label="normal"]; "auths-stripe-demo" -> "auths-author" [label="normal"]; @@ -480,57 +480,57 @@ digraph auths_architecture { "auths-stripe-demo" -> "auths-model" [label="normal"]; "auths-stripe-demo" -> "auths-ports" [label="normal"]; "auths-stripe-demo" -> "auths-profile-api" [label="normal"]; + "auths-stripe-demo" -> "auths-proof-sdk" [label="normal"]; "auths-stripe-demo" -> "auths-raw-key" [label="normal"]; "auths-stripe-demo" -> "auths-registries" [label="normal"]; "auths-stripe-demo" -> "auths-runtime" [label="normal"]; - "auths-stripe-demo" -> "auths-sdk" [label="normal"]; "auths-stripe-demo" -> "auths-signature" [label="normal"]; "auths-stripe-demo" -> "auths-stripe" [label="normal"]; "auths-stripe-payment-authorize-demo" -> "auths-profile-api" [label="normal"]; - "auths-stripe-payment-authorize-demo" -> "auths-sdk" [label="normal"]; + "auths-stripe-payment-authorize-demo" -> "auths-proof-sdk" [label="normal"]; "auths-stripe-payment-authorize-demo" -> "auths-stripe" [label="normal"]; "auths-stripe-payment-authorize-demo" -> "auths-stripe-payment-demo-common" [label="normal"]; "auths-stripe-payment-cancel-demo" -> "auths-profile-api" [label="normal"]; - "auths-stripe-payment-cancel-demo" -> "auths-sdk" [label="normal"]; + "auths-stripe-payment-cancel-demo" -> "auths-proof-sdk" [label="normal"]; "auths-stripe-payment-cancel-demo" -> "auths-stripe" [label="normal"]; "auths-stripe-payment-cancel-demo" -> "auths-stripe-payment-demo-common" [label="normal"]; "auths-stripe-payment-capture-demo" -> "auths-profile-api" [label="normal"]; - "auths-stripe-payment-capture-demo" -> "auths-sdk" [label="normal"]; + "auths-stripe-payment-capture-demo" -> "auths-proof-sdk" [label="normal"]; "auths-stripe-payment-capture-demo" -> "auths-stripe" [label="normal"]; "auths-stripe-payment-capture-demo" -> "auths-stripe-payment-demo-common" [label="normal"]; "auths-stripe-payment-collect-demo" -> "auths-profile-api" [label="normal"]; - "auths-stripe-payment-collect-demo" -> "auths-sdk" [label="normal"]; + "auths-stripe-payment-collect-demo" -> "auths-proof-sdk" [label="normal"]; "auths-stripe-payment-collect-demo" -> "auths-stripe" [label="normal"]; "auths-stripe-payment-collect-demo" -> "auths-stripe-payment-demo-common" [label="normal"]; "auths-stripe-payment-demo-common" -> "auths-author" [label="normal"]; "auths-stripe-payment-demo-common" -> "auths-codec" [label="normal"]; "auths-stripe-payment-demo-common" -> "auths-model" [label="normal"]; "auths-stripe-payment-demo-common" -> "auths-ports" [label="normal"]; + "auths-stripe-payment-demo-common" -> "auths-proof-sdk" [label="normal"]; "auths-stripe-payment-demo-common" -> "auths-raw-key" [label="normal"]; "auths-stripe-payment-demo-common" -> "auths-registries" [label="normal"]; "auths-stripe-payment-demo-common" -> "auths-runtime" [label="normal"]; - "auths-stripe-payment-demo-common" -> "auths-sdk" [label="normal"]; "auths-stripe-payment-demo-common" -> "auths-signature" [label="normal"]; "auths-stripe-payment-demo-common" -> "auths-stripe" [label="normal"]; "auths-stripe-payment-mandate-demo" -> "auths-profile-api" [label="normal"]; - "auths-stripe-payment-mandate-demo" -> "auths-sdk" [label="normal"]; + "auths-stripe-payment-mandate-demo" -> "auths-proof-sdk" [label="normal"]; "auths-stripe-payment-mandate-demo" -> "auths-stripe" [label="normal"]; "auths-stripe-payment-mandate-demo" -> "auths-stripe-payment-demo-common" [label="normal"]; "auths-stripe-payout-demo" -> "auths-stripe" [label="normal"]; "auths-stripe-purchase-authorization-demo" -> "auths-model" [label="normal"]; "auths-stripe-purchase-authorization-demo" -> "auths-profile-api" [label="normal"]; - "auths-stripe-purchase-authorization-demo" -> "auths-sdk" [label="normal"]; + "auths-stripe-purchase-authorization-demo" -> "auths-proof-sdk" [label="normal"]; "auths-stripe-purchase-authorization-demo" -> "auths-stripe" [label="normal"]; "auths-stripe-purchase-authorization-demo" -> "auths-stripe-payment-demo-common" [label="normal"]; "auths-stripe-subscription-cancel-demo" -> "auths-stripe" [label="normal"]; "auths-stripe-subscription-create-demo" -> "auths-model" [label="normal"]; "auths-stripe-subscription-create-demo" -> "auths-profile-api" [label="normal"]; - "auths-stripe-subscription-create-demo" -> "auths-sdk" [label="normal"]; + "auths-stripe-subscription-create-demo" -> "auths-proof-sdk" [label="normal"]; "auths-stripe-subscription-create-demo" -> "auths-stripe" [label="normal"]; "auths-stripe-subscription-create-demo" -> "auths-stripe-payment-demo-common" [label="normal"]; "auths-stripe-subscription-modify-demo" -> "auths-model" [label="normal"]; "auths-stripe-subscription-modify-demo" -> "auths-profile-api" [label="normal"]; - "auths-stripe-subscription-modify-demo" -> "auths-sdk" [label="normal"]; + "auths-stripe-subscription-modify-demo" -> "auths-proof-sdk" [label="normal"]; "auths-stripe-subscription-modify-demo" -> "auths-stripe" [label="normal"]; "auths-stripe-subscription-modify-demo" -> "auths-stripe-payment-demo-common" [label="normal"]; "auths-testkit" -> "auths-author" [label="normal"]; diff --git a/architecture/dependency-graph.json b/architecture/dependency-graph.json index bc76a2c..9c1d643 100644 --- a/architecture/dependency-graph.json +++ b/architecture/dependency-graph.json @@ -316,6 +316,11 @@ "layer": "bindings", "path": "bindings/python" }, + { + "name": "auths-proof-sdk", + "layer": "product", + "path": "product/sdk/auths-sdk" + }, { "name": "auths-proof-wasm", "layer": "bindings", @@ -366,11 +371,6 @@ "layer": "product", "path": "product/runtime/auths-runtime" }, - { - "name": "auths-sdk", - "layer": "product", - "path": "product/sdk/auths-sdk" - }, { "name": "auths-signature", "layer": "core", @@ -634,6 +634,18 @@ "default_features": true, "features": [] }, + { + "source": "auths-apps-testkit", + "source_layer": "demos", + "target": "auths-proof-sdk", + "target_layer": "product", + "scope": "internal", + "kind": "normal", + "target_condition": null, + "optional": false, + "default_features": true, + "features": [] + }, { "source": "auths-apps-testkit", "source_layer": "demos", @@ -682,18 +694,6 @@ "default_features": true, "features": [] }, - { - "source": "auths-apps-testkit", - "source_layer": "demos", - "target": "auths-sdk", - "target_layer": "product", - "scope": "internal", - "kind": "normal", - "target_condition": null, - "optional": false, - "default_features": true, - "features": [] - }, { "source": "auths-apps-testkit", "source_layer": "demos", @@ -1594,7 +1594,7 @@ { "source": "auths-deployment", "source_layer": "product", - "target": "auths-sdk", + "target": "auths-proof-sdk", "target_layer": "product", "scope": "internal", "kind": "normal", @@ -1911,7 +1911,7 @@ { "source": "auths-enforcement", "source_layer": "product", - "target": "auths-sdk", + "target": "auths-proof-sdk", "target_layer": "product", "scope": "internal", "kind": "normal", @@ -2351,7 +2351,7 @@ { "source": "auths-github", "source_layer": "product", - "target": "auths-sdk", + "target": "auths-proof-sdk", "target_layer": "product", "scope": "internal", "kind": "normal", @@ -2605,19 +2605,19 @@ { "source": "auths-github-demo", "source_layer": "demos", - "target": "auths-raw-key", - "target_layer": "core", + "target": "auths-proof-sdk", + "target_layer": "product", "scope": "internal", "kind": "normal", "target_condition": null, "optional": false, - "default_features": false, + "default_features": true, "features": [] }, { "source": "auths-github-demo", "source_layer": "demos", - "target": "auths-registries", + "target": "auths-raw-key", "target_layer": "core", "scope": "internal", "kind": "normal", @@ -2629,19 +2629,19 @@ { "source": "auths-github-demo", "source_layer": "demos", - "target": "auths-runtime", - "target_layer": "product", + "target": "auths-registries", + "target_layer": "core", "scope": "internal", "kind": "normal", "target_condition": null, "optional": false, - "default_features": true, + "default_features": false, "features": [] }, { "source": "auths-github-demo", "source_layer": "demos", - "target": "auths-sdk", + "target": "auths-runtime", "target_layer": "product", "scope": "internal", "kind": "normal", @@ -2942,7 +2942,7 @@ { "source": "auths-kubernetes", "source_layer": "product", - "target": "auths-sdk", + "target": "auths-proof-sdk", "target_layer": "product", "scope": "internal", "kind": "normal", @@ -3152,19 +3152,19 @@ { "source": "auths-kubernetes-demo", "source_layer": "demos", - "target": "auths-raw-key", - "target_layer": "core", + "target": "auths-proof-sdk", + "target_layer": "product", "scope": "internal", "kind": "normal", "target_condition": null, "optional": false, - "default_features": false, + "default_features": true, "features": [] }, { "source": "auths-kubernetes-demo", "source_layer": "demos", - "target": "auths-registries", + "target": "auths-raw-key", "target_layer": "core", "scope": "internal", "kind": "normal", @@ -3176,19 +3176,19 @@ { "source": "auths-kubernetes-demo", "source_layer": "demos", - "target": "auths-runtime", - "target_layer": "product", + "target": "auths-registries", + "target_layer": "core", "scope": "internal", "kind": "normal", "target_condition": null, "optional": false, - "default_features": true, + "default_features": false, "features": [] }, { "source": "auths-kubernetes-demo", "source_layer": "demos", - "target": "auths-sdk", + "target": "auths-runtime", "target_layer": "product", "scope": "internal", "kind": "normal", @@ -4109,7 +4109,7 @@ { "source": "auths-opentofu", "source_layer": "product", - "target": "auths-sdk", + "target": "auths-proof-sdk", "target_layer": "product", "scope": "internal", "kind": "normal", @@ -4295,7 +4295,7 @@ { "source": "auths-opentofu-demo", "source_layer": "demos", - "target": "auths-sdk", + "target": "auths-proof-sdk", "target_layer": "product", "scope": "internal", "kind": "normal", @@ -4680,7 +4680,7 @@ { "source": "auths-postgresql", "source_layer": "product", - "target": "auths-sdk", + "target": "auths-proof-sdk", "target_layer": "product", "scope": "internal", "kind": "normal", @@ -4904,7 +4904,7 @@ { "source": "auths-postgresql-demo", "source_layer": "demos", - "target": "auths-sdk", + "target": "auths-proof-sdk", "target_layer": "product", "scope": "internal", "kind": "normal", @@ -6685,6 +6685,212 @@ "abi3-py39" ] }, + { + "source": "auths-proof-sdk", + "source_layer": "product", + "target": "auths-author", + "target_layer": "core", + "scope": "internal", + "kind": "normal", + "target_condition": null, + "optional": false, + "default_features": false, + "features": [] + }, + { + "source": "auths-proof-sdk", + "source_layer": "product", + "target": "auths-codec", + "target_layer": "core", + "scope": "internal", + "kind": "dev", + "target_condition": null, + "optional": false, + "default_features": false, + "features": [] + }, + { + "source": "auths-proof-sdk", + "source_layer": "product", + "target": "auths-custody", + "target_layer": "product", + "scope": "internal", + "kind": "normal", + "target_condition": null, + "optional": false, + "default_features": true, + "features": [] + }, + { + "source": "auths-proof-sdk", + "source_layer": "product", + "target": "auths-did-keri", + "target_layer": "core", + "scope": "internal", + "kind": "normal", + "target_condition": null, + "optional": false, + "default_features": false, + "features": [ + "std" + ] + }, + { + "source": "auths-proof-sdk", + "source_layer": "product", + "target": "auths-did-key", + "target_layer": "core", + "scope": "internal", + "kind": "normal", + "target_condition": null, + "optional": false, + "default_features": false, + "features": [] + }, + { + "source": "auths-proof-sdk", + "source_layer": "product", + "target": "auths-model", + "target_layer": "core", + "scope": "internal", + "kind": "normal", + "target_condition": null, + "optional": false, + "default_features": false, + "features": [] + }, + { + "source": "auths-proof-sdk", + "source_layer": "product", + "target": "auths-ports", + "target_layer": "core", + "scope": "internal", + "kind": "normal", + "target_condition": null, + "optional": false, + "default_features": false, + "features": [] + }, + { + "source": "auths-proof-sdk", + "source_layer": "product", + "target": "auths-profile-api", + "target_layer": "product", + "scope": "internal", + "kind": "normal", + "target_condition": null, + "optional": false, + "default_features": true, + "features": [] + }, + { + "source": "auths-proof-sdk", + "source_layer": "product", + "target": "auths-profile-domains", + "target_layer": "product", + "scope": "internal", + "kind": "normal", + "target_condition": null, + "optional": false, + "default_features": true, + "features": [] + }, + { + "source": "auths-proof-sdk", + "source_layer": "product", + "target": "auths-profile-mcp", + "target_layer": "product", + "scope": "internal", + "kind": "normal", + "target_condition": null, + "optional": false, + "default_features": true, + "features": [] + }, + { + "source": "auths-proof-sdk", + "source_layer": "product", + "target": "auths-raw-key", + "target_layer": "core", + "scope": "internal", + "kind": "normal", + "target_condition": null, + "optional": false, + "default_features": false, + "features": [] + }, + { + "source": "auths-proof-sdk", + "source_layer": "product", + "target": "auths-registries", + "target_layer": "core", + "scope": "internal", + "kind": "normal", + "target_condition": null, + "optional": false, + "default_features": false, + "features": [] + }, + { + "source": "auths-proof-sdk", + "source_layer": "product", + "target": "auths-runtime", + "target_layer": "product", + "scope": "internal", + "kind": "normal", + "target_condition": null, + "optional": false, + "default_features": true, + "features": [] + }, + { + "source": "auths-proof-sdk", + "source_layer": "product", + "target": "auths-signature", + "target_layer": "core", + "scope": "internal", + "kind": "normal", + "target_condition": null, + "optional": false, + "default_features": false, + "features": [] + }, + { + "source": "auths-proof-sdk", + "source_layer": "product", + "target": "auths-testkit", + "target_layer": "core", + "scope": "internal", + "kind": "dev", + "target_condition": null, + "optional": false, + "default_features": true, + "features": [] + }, + { + "source": "auths-proof-sdk", + "source_layer": "product", + "target": "auths-verifier", + "target_layer": "core", + "scope": "internal", + "kind": "normal", + "target_condition": null, + "optional": false, + "default_features": false, + "features": [] + }, + { + "source": "auths-proof-sdk", + "source_layer": "product", + "target": "thiserror", + "target_layer": null, + "scope": "external", + "kind": "normal", + "target_condition": null, + "optional": false, + "default_features": false, + "features": [] + }, { "source": "auths-proof-wasm", "source_layer": "bindings", @@ -6892,49 +7098,49 @@ { "source": "auths-radicle", "source_layer": "product", - "target": "auths-raw-key", - "target_layer": "core", + "target": "auths-proof-sdk", + "target_layer": "product", "scope": "internal", - "kind": "dev", + "kind": "normal", "target_condition": null, "optional": false, - "default_features": false, + "default_features": true, "features": [] }, { "source": "auths-radicle", "source_layer": "product", - "target": "auths-receipts", - "target_layer": "product", + "target": "auths-raw-key", + "target_layer": "core", "scope": "internal", - "kind": "normal", + "kind": "dev", "target_condition": null, "optional": false, - "default_features": true, + "default_features": false, "features": [] }, { "source": "auths-radicle", "source_layer": "product", - "target": "auths-registries", - "target_layer": "core", + "target": "auths-receipts", + "target_layer": "product", "scope": "internal", - "kind": "dev", + "kind": "normal", "target_condition": null, "optional": false, - "default_features": false, + "default_features": true, "features": [] }, { "source": "auths-radicle", "source_layer": "product", - "target": "auths-sdk", - "target_layer": "product", + "target": "auths-registries", + "target_layer": "core", "scope": "internal", - "kind": "normal", + "kind": "dev", "target_condition": null, "optional": false, - "default_features": true, + "default_features": false, "features": [] }, { @@ -7164,7 +7370,7 @@ { "source": "auths-radicle-demo", "source_layer": "demos", - "target": "auths-radicle", + "target": "auths-proof-sdk", "target_layer": "product", "scope": "internal", "kind": "normal", @@ -7176,19 +7382,19 @@ { "source": "auths-radicle-demo", "source_layer": "demos", - "target": "auths-raw-key", - "target_layer": "core", + "target": "auths-radicle", + "target_layer": "product", "scope": "internal", "kind": "normal", "target_condition": null, "optional": false, - "default_features": false, + "default_features": true, "features": [] }, { "source": "auths-radicle-demo", "source_layer": "demos", - "target": "auths-registries", + "target": "auths-raw-key", "target_layer": "core", "scope": "internal", "kind": "normal", @@ -7200,19 +7406,19 @@ { "source": "auths-radicle-demo", "source_layer": "demos", - "target": "auths-runtime", - "target_layer": "product", + "target": "auths-registries", + "target_layer": "core", "scope": "internal", "kind": "normal", "target_condition": null, "optional": false, - "default_features": true, + "default_features": false, "features": [] }, { "source": "auths-radicle-demo", "source_layer": "demos", - "target": "auths-sdk", + "target": "auths-runtime", "target_layer": "product", "scope": "internal", "kind": "normal", @@ -7603,7 +7809,7 @@ { "source": "auths-records-api", "source_layer": "product", - "target": "auths-sdk", + "target": "auths-proof-sdk", "target_layer": "product", "scope": "internal", "kind": "normal", @@ -7884,6 +8090,18 @@ "default_features": true, "features": [] }, + { + "source": "auths-records-demo", + "source_layer": "demos", + "target": "auths-proof-sdk", + "target_layer": "product", + "scope": "internal", + "kind": "normal", + "target_condition": null, + "optional": false, + "default_features": true, + "features": [] + }, { "source": "auths-records-demo", "source_layer": "demos", @@ -7932,18 +8150,6 @@ "default_features": true, "features": [] }, - { - "source": "auths-records-demo", - "source_layer": "demos", - "target": "auths-sdk", - "target_layer": "product", - "scope": "internal", - "kind": "normal", - "target_condition": null, - "optional": false, - "default_features": true, - "features": [] - }, { "source": "auths-records-demo", "source_layer": "demos", @@ -8468,212 +8674,6 @@ "default_features": false, "features": [] }, - { - "source": "auths-sdk", - "source_layer": "product", - "target": "auths-author", - "target_layer": "core", - "scope": "internal", - "kind": "normal", - "target_condition": null, - "optional": false, - "default_features": false, - "features": [] - }, - { - "source": "auths-sdk", - "source_layer": "product", - "target": "auths-codec", - "target_layer": "core", - "scope": "internal", - "kind": "dev", - "target_condition": null, - "optional": false, - "default_features": false, - "features": [] - }, - { - "source": "auths-sdk", - "source_layer": "product", - "target": "auths-custody", - "target_layer": "product", - "scope": "internal", - "kind": "normal", - "target_condition": null, - "optional": false, - "default_features": true, - "features": [] - }, - { - "source": "auths-sdk", - "source_layer": "product", - "target": "auths-did-keri", - "target_layer": "core", - "scope": "internal", - "kind": "normal", - "target_condition": null, - "optional": false, - "default_features": false, - "features": [ - "std" - ] - }, - { - "source": "auths-sdk", - "source_layer": "product", - "target": "auths-did-key", - "target_layer": "core", - "scope": "internal", - "kind": "normal", - "target_condition": null, - "optional": false, - "default_features": false, - "features": [] - }, - { - "source": "auths-sdk", - "source_layer": "product", - "target": "auths-model", - "target_layer": "core", - "scope": "internal", - "kind": "normal", - "target_condition": null, - "optional": false, - "default_features": false, - "features": [] - }, - { - "source": "auths-sdk", - "source_layer": "product", - "target": "auths-ports", - "target_layer": "core", - "scope": "internal", - "kind": "normal", - "target_condition": null, - "optional": false, - "default_features": false, - "features": [] - }, - { - "source": "auths-sdk", - "source_layer": "product", - "target": "auths-profile-api", - "target_layer": "product", - "scope": "internal", - "kind": "normal", - "target_condition": null, - "optional": false, - "default_features": true, - "features": [] - }, - { - "source": "auths-sdk", - "source_layer": "product", - "target": "auths-profile-domains", - "target_layer": "product", - "scope": "internal", - "kind": "normal", - "target_condition": null, - "optional": false, - "default_features": true, - "features": [] - }, - { - "source": "auths-sdk", - "source_layer": "product", - "target": "auths-profile-mcp", - "target_layer": "product", - "scope": "internal", - "kind": "normal", - "target_condition": null, - "optional": false, - "default_features": true, - "features": [] - }, - { - "source": "auths-sdk", - "source_layer": "product", - "target": "auths-raw-key", - "target_layer": "core", - "scope": "internal", - "kind": "normal", - "target_condition": null, - "optional": false, - "default_features": false, - "features": [] - }, - { - "source": "auths-sdk", - "source_layer": "product", - "target": "auths-registries", - "target_layer": "core", - "scope": "internal", - "kind": "normal", - "target_condition": null, - "optional": false, - "default_features": false, - "features": [] - }, - { - "source": "auths-sdk", - "source_layer": "product", - "target": "auths-runtime", - "target_layer": "product", - "scope": "internal", - "kind": "normal", - "target_condition": null, - "optional": false, - "default_features": true, - "features": [] - }, - { - "source": "auths-sdk", - "source_layer": "product", - "target": "auths-signature", - "target_layer": "core", - "scope": "internal", - "kind": "normal", - "target_condition": null, - "optional": false, - "default_features": false, - "features": [] - }, - { - "source": "auths-sdk", - "source_layer": "product", - "target": "auths-testkit", - "target_layer": "core", - "scope": "internal", - "kind": "dev", - "target_condition": null, - "optional": false, - "default_features": true, - "features": [] - }, - { - "source": "auths-sdk", - "source_layer": "product", - "target": "auths-verifier", - "target_layer": "core", - "scope": "internal", - "kind": "normal", - "target_condition": null, - "optional": false, - "default_features": false, - "features": [] - }, - { - "source": "auths-sdk", - "source_layer": "product", - "target": "thiserror", - "target_layer": null, - "scope": "external", - "kind": "normal", - "target_condition": null, - "optional": false, - "default_features": false, - "features": [] - }, { "source": "auths-signature", "source_layer": "core", @@ -9092,19 +9092,19 @@ { "source": "auths-stripe", "source_layer": "product", - "target": "auths-raw-key", - "target_layer": "core", + "target": "auths-proof-sdk", + "target_layer": "product", "scope": "internal", - "kind": "dev", + "kind": "normal", "target_condition": null, "optional": false, - "default_features": false, + "default_features": true, "features": [] }, { "source": "auths-stripe", "source_layer": "product", - "target": "auths-registries", + "target": "auths-raw-key", "target_layer": "core", "scope": "internal", "kind": "dev", @@ -9116,22 +9116,22 @@ { "source": "auths-stripe", "source_layer": "product", - "target": "auths-runtime", - "target_layer": "product", + "target": "auths-registries", + "target_layer": "core", "scope": "internal", "kind": "dev", "target_condition": null, "optional": false, - "default_features": true, + "default_features": false, "features": [] }, { "source": "auths-stripe", "source_layer": "product", - "target": "auths-sdk", + "target": "auths-runtime", "target_layer": "product", "scope": "internal", - "kind": "normal", + "kind": "dev", "target_condition": null, "optional": false, "default_features": true, @@ -9467,19 +9467,19 @@ { "source": "auths-stripe-demo", "source_layer": "demos", - "target": "auths-raw-key", - "target_layer": "core", + "target": "auths-proof-sdk", + "target_layer": "product", "scope": "internal", "kind": "normal", "target_condition": null, "optional": false, - "default_features": false, + "default_features": true, "features": [] }, { "source": "auths-stripe-demo", "source_layer": "demos", - "target": "auths-registries", + "target": "auths-raw-key", "target_layer": "core", "scope": "internal", "kind": "normal", @@ -9491,19 +9491,19 @@ { "source": "auths-stripe-demo", "source_layer": "demos", - "target": "auths-runtime", - "target_layer": "product", + "target": "auths-registries", + "target_layer": "core", "scope": "internal", "kind": "normal", "target_condition": null, "optional": false, - "default_features": true, + "default_features": false, "features": [] }, { "source": "auths-stripe-demo", "source_layer": "demos", - "target": "auths-sdk", + "target": "auths-runtime", "target_layer": "product", "scope": "internal", "kind": "normal", @@ -9756,7 +9756,7 @@ { "source": "auths-stripe-payment-authorize-demo", "source_layer": "demos", - "target": "auths-sdk", + "target": "auths-proof-sdk", "target_layer": "product", "scope": "internal", "kind": "normal", @@ -9959,7 +9959,7 @@ { "source": "auths-stripe-payment-cancel-demo", "source_layer": "demos", - "target": "auths-sdk", + "target": "auths-proof-sdk", "target_layer": "product", "scope": "internal", "kind": "normal", @@ -10162,7 +10162,7 @@ { "source": "auths-stripe-payment-capture-demo", "source_layer": "demos", - "target": "auths-sdk", + "target": "auths-proof-sdk", "target_layer": "product", "scope": "internal", "kind": "normal", @@ -10365,7 +10365,7 @@ { "source": "auths-stripe-payment-collect-demo", "source_layer": "demos", - "target": "auths-sdk", + "target": "auths-proof-sdk", "target_layer": "product", "scope": "internal", "kind": "normal", @@ -10604,19 +10604,19 @@ { "source": "auths-stripe-payment-demo-common", "source_layer": "demos", - "target": "auths-raw-key", - "target_layer": "core", + "target": "auths-proof-sdk", + "target_layer": "product", "scope": "internal", "kind": "normal", "target_condition": null, "optional": false, - "default_features": false, + "default_features": true, "features": [] }, { "source": "auths-stripe-payment-demo-common", "source_layer": "demos", - "target": "auths-registries", + "target": "auths-raw-key", "target_layer": "core", "scope": "internal", "kind": "normal", @@ -10628,19 +10628,19 @@ { "source": "auths-stripe-payment-demo-common", "source_layer": "demos", - "target": "auths-runtime", - "target_layer": "product", + "target": "auths-registries", + "target_layer": "core", "scope": "internal", "kind": "normal", "target_condition": null, "optional": false, - "default_features": true, + "default_features": false, "features": [] }, { "source": "auths-stripe-payment-demo-common", "source_layer": "demos", - "target": "auths-sdk", + "target": "auths-runtime", "target_layer": "product", "scope": "internal", "kind": "normal", @@ -10760,7 +10760,7 @@ { "source": "auths-stripe-payment-mandate-demo", "source_layer": "demos", - "target": "auths-sdk", + "target": "auths-proof-sdk", "target_layer": "product", "scope": "internal", "kind": "normal", @@ -11102,7 +11102,7 @@ { "source": "auths-stripe-purchase-authorization-demo", "source_layer": "demos", - "target": "auths-sdk", + "target": "auths-proof-sdk", "target_layer": "product", "scope": "internal", "kind": "normal", @@ -11452,7 +11452,7 @@ { "source": "auths-stripe-subscription-create-demo", "source_layer": "demos", - "target": "auths-sdk", + "target": "auths-proof-sdk", "target_layer": "product", "scope": "internal", "kind": "normal", @@ -11651,7 +11651,7 @@ { "source": "auths-stripe-subscription-modify-demo", "source_layer": "demos", - "target": "auths-sdk", + "target": "auths-proof-sdk", "target_layer": "product", "scope": "internal", "kind": "normal", diff --git a/bindings/python/Cargo.toml b/bindings/python/Cargo.toml index 624db7b..514ba65 100644 --- a/bindings/python/Cargo.toml +++ b/bindings/python/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +publish = false description = "Prebuilt Python binding for Auths Proof Protocol V1" [lib] diff --git a/bindings/wasm/auths-proof-wasm/Cargo.toml b/bindings/wasm/auths-proof-wasm/Cargo.toml index 2b2a9d3..0a3804d 100644 --- a/bindings/wasm/auths-proof-wasm/Cargo.toml +++ b/bindings/wasm/auths-proof-wasm/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +publish = false repository.workspace = true homepage.workspace = true description = "Prebuildable WebAssembly boundary for Auths Proof Protocol V1" diff --git a/compliance.toml b/compliance.toml index f07b994..93cb4c8 100644 --- a/compliance.toml +++ b/compliance.toml @@ -1189,7 +1189,7 @@ receipt-producer-consumer = ["demos/testkit/auths-apps-testkit/src/lib.rs#target runtime-enforcement-boundary = ["demos/testkit/auths-apps-testkit/src/lib.rs#authenticated_transport_does_not_upgrade_bad_proof"] stateful-replay-budget-component = ["demos/testkit/auths-apps-testkit/src/lib.rs#concurrent_duplicate_executes_exactly_once"] -[packages.auths-sdk] +[packages.auths-proof-sdk] kind = "cargo" layer = "product" path = "product/sdk/auths-sdk" @@ -1204,7 +1204,7 @@ transports = [] configuration_inputs = ["assurance-policy", "composition-requirement", "executed-verifier-configuration", "required-verifier-configuration", "trust-anchors", "verifier-limits"] security_state = [] -[packages.auths-sdk.claims] +[packages.auths-proof-sdk.claims] core-api-consumer = ["demos/testkit/auths-apps-testkit/src/lib.rs#target_flow_is_transport_independent_and_replay_safe"] runtime-enforcement-boundary = ["demos/testkit/auths-apps-testkit/src/lib.rs#signed_permission_must_match_tool"] diff --git a/core/adapters/auths-did-web/Cargo.toml b/core/adapters/auths-did-web/Cargo.toml index 13d1d2b..cb2e9d0 100644 --- a/core/adapters/auths-did-web/Cargo.toml +++ b/core/adapters/auths-did-web/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +publish = false repository.workspace = true homepage.workspace = true description = "Pure bundled did:web principal-control method for Auths target V1" diff --git a/core/adapters/auths-hsm-attested/Cargo.toml b/core/adapters/auths-hsm-attested/Cargo.toml index d1acde2..6a0ad06 100644 --- a/core/adapters/auths-hsm-attested/Cargo.toml +++ b/core/adapters/auths-hsm-attested/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +publish = false repository.workspace = true homepage.workspace = true description = "Pure verifier-local HSM attestation profiles for Auths target V1" diff --git a/core/adapters/auths-spiffe-x509/Cargo.toml b/core/adapters/auths-spiffe-x509/Cargo.toml index fc993e1..5b38ba1 100644 --- a/core/adapters/auths-spiffe-x509/Cargo.toml +++ b/core/adapters/auths-spiffe-x509/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +publish = false repository.workspace = true homepage.workspace = true description = "Pure SPIFFE X.509-SVID principal-control method for Auths target V1" diff --git a/core/adapters/auths-webauthn/Cargo.toml b/core/adapters/auths-webauthn/Cargo.toml index 69218ea..1b695ae 100644 --- a/core/adapters/auths-webauthn/Cargo.toml +++ b/core/adapters/auths-webauthn/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +publish = false repository.workspace = true homepage.workspace = true description = "Pure WebAuthn assertion principal-control method for Auths target V1" diff --git a/core/crates/auths-proof/Cargo.toml b/core/crates/auths-proof/Cargo.toml index 61eb93c..00508ea 100644 --- a/core/crates/auths-proof/Cargo.toml +++ b/core/crates/auths-proof/Cargo.toml @@ -27,7 +27,7 @@ auths-verifier.workspace = true auths-ports = { workspace = true, features = ["std"] } auths-raw-key = { workspace = true, features = ["std"] } auths-signature = { workspace = true, features = ["std"] } -auths-testkit.workspace = true +auths-testkit = { path = "../../testkit/auths-testkit" } [lints] workspace = true diff --git a/core/crates/auths-verifier/Cargo.toml b/core/crates/auths-verifier/Cargo.toml index 24322ae..677730a 100644 --- a/core/crates/auths-verifier/Cargo.toml +++ b/core/crates/auths-verifier/Cargo.toml @@ -32,13 +32,13 @@ auths-registries.workspace = true [dev-dependencies] auths-did-key = { workspace = true, features = ["std"] } auths-did-keri = { workspace = true, features = ["std"] } -auths-did-web = { workspace = true, features = ["std"] } -auths-hsm-attested = { workspace = true, features = ["std"] } +auths-did-web = { path = "../../adapters/auths-did-web", default-features = false, features = ["std"] } +auths-hsm-attested = { path = "../../adapters/auths-hsm-attested", default-features = false, features = ["std"] } auths-raw-key = { workspace = true, features = ["std"] } auths-signature = { workspace = true, features = ["std"] } -auths-spiffe-x509 = { workspace = true, features = ["std"] } -auths-testkit.workspace = true -auths-webauthn = { workspace = true, features = ["std"] } +auths-spiffe-x509 = { path = "../../adapters/auths-spiffe-x509", default-features = false, features = ["std"] } +auths-testkit = { path = "../../testkit/auths-testkit" } +auths-webauthn = { path = "../../adapters/auths-webauthn", default-features = false, features = ["std"] } ed25519-dalek.workspace = true [lints] diff --git a/core/testkit/auths-testkit/Cargo.toml b/core/testkit/auths-testkit/Cargo.toml index c9493df..84f0ab6 100644 --- a/core/testkit/auths-testkit/Cargo.toml +++ b/core/testkit/auths-testkit/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +publish = false repository.workspace = true homepage.workspace = true description = "Canonical conformance fixtures and adapter test support for Auths Proof Protocol V1" diff --git a/demos/github-issue/docs/architecture.md b/demos/github-issue/docs/architecture.md index c21dbe7..b3e73a3 100644 --- a/demos/github-issue/docs/architecture.md +++ b/demos/github-issue/docs/architecture.md @@ -12,7 +12,7 @@ flowchart LR Model["auths-model
proof vocabulary"] Author["auths-author
grant/action preparation"] Codec["auths-codec
canonical IDs and bundles"] - Kernel["auths-runtime + auths-sdk
AuthsKernel / Verifier"] + Kernel["auths-runtime + auths-proof-sdk
AuthsKernel / Verifier"] Crypto["auths-raw-key + auths-signature
identity and Ed25519"] Registries["auths-registries + auths-ports
accepted mechanisms"] end @@ -87,7 +87,7 @@ Auths core never imports the demo or GitHub integration. | `auths-codec` | Produces canonical identifiers and proof-bundle bytes. | `fixture.rs` derives action, evidence, grant, and plan identifiers and encodes the proof bundle. | | `auths-profile-api` | Lets a domain define canonical action bytes, permissions, resources, and budgets. | `auths-github::GitHubIssueProfile` maps a sealed GitHub action into the generic Auths verification interface. | | `auths-runtime` | Runs the configured Auths kernel. | `fixture.rs` builds the `AuthsKernel` from accepted registries and trusted adapters. | -| `auths-sdk` | Exposes the verifier and the closed authorized/denied/indeterminate result. | `EphemeralAuthsAuthorizer` calls `Verifier::verify` over the real proof and exact canonical GitHub action. | +| `auths-proof-sdk` | Exposes the verifier and the closed authorized/denied/indeterminate result. | `EphemeralAuthsAuthorizer` calls `Verifier::verify` over the real proof and exact canonical GitHub action. | | `auths-ports` | Defines trusted extension boundaries. | Raw-key principal resolution and Ed25519 signature verification are installed through core ports. | | `auths-registries` | Pins accepted mechanism registries. | The demo loads the target registry manifest into the verifier context. | | `auths-raw-key` | Supplies the demo's self-certifying identity method. | Human, workflow, and agent identities use raw Ed25519 public-key descriptors. | @@ -247,4 +247,3 @@ All request bodies have a hard size limit. CORS allows only the configured Verce - The agent/candidate sandbox never receives a GitHub credential. The Content Security Policy permits the frontend to connect only to itself and the configured Fly service. Vercel rewrites `/receipts/:workflow` to the dedicated receipt document so links work when opened directly. - diff --git a/demos/rest-api-authorization/docs/architecture.md b/demos/rest-api-authorization/docs/architecture.md index 0fb81cb..65b543b 100644 --- a/demos/rest-api-authorization/docs/architecture.md +++ b/demos/rest-api-authorization/docs/architecture.md @@ -8,7 +8,7 @@ flowchart LR Iroh --> Envelope Envelope --> Create["CreateRecordProfile + create evaluator"] Envelope --> Read["ReadRecordProfile + read evaluator"] - Create --> Kernel["auths-sdk / AuthsKernel"] + Create --> Kernel["auths-proof-sdk / AuthsKernel"] Read --> Kernel Kernel --> Projection["Records-owned shared commitment projection"] Projection --> Lifecycle["Shared durable lifecycle + additive capacity"] diff --git a/deny.toml b/deny.toml index a799775..6ee3266 100644 --- a/deny.toml +++ b/deny.toml @@ -30,6 +30,10 @@ allow = [ [bans] multiple-versions = "warn" wildcards = "deny" +# Public crates may use path-only dev-dependencies on private workspace +# testkits/adapters. Cargo permits this for dev-dependencies, and their paths +# are repository-local; published dependency surfaces remain version-pinned. +allow-wildcard-paths = true highlight = "all" [sources] diff --git a/exchange/adapters/auths-proof-exchange-file/Cargo.toml b/exchange/adapters/auths-proof-exchange-file/Cargo.toml index 1386d57..7be3907 100644 --- a/exchange/adapters/auths-proof-exchange-file/Cargo.toml +++ b/exchange/adapters/auths-proof-exchange-file/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +publish = false [dependencies] auths-proof-exchange-codec.workspace = true diff --git a/exchange/adapters/auths-proof-exchange-https/Cargo.toml b/exchange/adapters/auths-proof-exchange-https/Cargo.toml index 72ac047..54ee4d9 100644 --- a/exchange/adapters/auths-proof-exchange-https/Cargo.toml +++ b/exchange/adapters/auths-proof-exchange-https/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +publish = false [dependencies] async-trait.workspace = true diff --git a/exchange/adapters/auths-proof-exchange-iroh/Cargo.toml b/exchange/adapters/auths-proof-exchange-iroh/Cargo.toml index a6e0995..c833ea1 100644 --- a/exchange/adapters/auths-proof-exchange-iroh/Cargo.toml +++ b/exchange/adapters/auths-proof-exchange-iroh/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +publish = false description = "Iroh transport adapter for Auths proof exchange" [dependencies] @@ -16,4 +17,3 @@ tokio.workspace = true [lints] workspace = true - diff --git a/exchange/adapters/auths-proof-exchange-memory/Cargo.toml b/exchange/adapters/auths-proof-exchange-memory/Cargo.toml index 6a1627d..c9c6b47 100644 --- a/exchange/adapters/auths-proof-exchange-memory/Cargo.toml +++ b/exchange/adapters/auths-proof-exchange-memory/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +publish = false description = "In-memory conformance adapter for Auths proof exchange" [dependencies] @@ -14,4 +15,3 @@ tokio.workspace = true [lints] workspace = true - diff --git a/exchange/adapters/auths-proof-exchange-tcp/Cargo.toml b/exchange/adapters/auths-proof-exchange-tcp/Cargo.toml index 334aca7..d01e68a 100644 --- a/exchange/adapters/auths-proof-exchange-tcp/Cargo.toml +++ b/exchange/adapters/auths-proof-exchange-tcp/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +publish = false [dependencies] auths-proof-exchange-framing.workspace = true diff --git a/exchange/adapters/auths-proof-exchange-unix/Cargo.toml b/exchange/adapters/auths-proof-exchange-unix/Cargo.toml index f343641..c27bfd9 100644 --- a/exchange/adapters/auths-proof-exchange-unix/Cargo.toml +++ b/exchange/adapters/auths-proof-exchange-unix/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +publish = false [dependencies] auths-proof-exchange-framing.workspace = true diff --git a/exchange/crates/auths-proof-exchange-codec/Cargo.toml b/exchange/crates/auths-proof-exchange-codec/Cargo.toml index 18966ab..54ae9a3 100644 --- a/exchange/crates/auths-proof-exchange-codec/Cargo.toml +++ b/exchange/crates/auths-proof-exchange-codec/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +publish = false description = "Deterministic bounded CBOR codec for Auths proof exchange" [dependencies] diff --git a/exchange/crates/auths-proof-exchange-framing/Cargo.toml b/exchange/crates/auths-proof-exchange-framing/Cargo.toml index 4bd9e78..7275e48 100644 --- a/exchange/crates/auths-proof-exchange-framing/Cargo.toml +++ b/exchange/crates/auths-proof-exchange-framing/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +publish = false [dependencies] async-trait.workspace = true diff --git a/exchange/crates/auths-proof-exchange-model/Cargo.toml b/exchange/crates/auths-proof-exchange-model/Cargo.toml index 102e1b7..32eedba 100644 --- a/exchange/crates/auths-proof-exchange-model/Cargo.toml +++ b/exchange/crates/auths-proof-exchange-model/Cargo.toml @@ -4,6 +4,8 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +repository.workspace = true +homepage.workspace = true description = "Validated semantic types for Auths proof exchange" [features] @@ -12,4 +14,3 @@ std = [] [lints] workspace = true - diff --git a/exchange/crates/auths-proof-exchange-port/Cargo.toml b/exchange/crates/auths-proof-exchange-port/Cargo.toml index f5dfae9..bd4be73 100644 --- a/exchange/crates/auths-proof-exchange-port/Cargo.toml +++ b/exchange/crates/auths-proof-exchange-port/Cargo.toml @@ -4,6 +4,8 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +repository.workspace = true +homepage.workspace = true description = "Semantic proof-exchange port and single-use V1 state machine" [dependencies] @@ -12,4 +14,3 @@ async-trait.workspace = true [lints] workspace = true - diff --git a/exchange/crates/auths-proof-exchange/Cargo.toml b/exchange/crates/auths-proof-exchange/Cargo.toml index 03203d8..a1cb05e 100644 --- a/exchange/crates/auths-proof-exchange/Cargo.toml +++ b/exchange/crates/auths-proof-exchange/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +publish = false description = "Supported proof-exchange facade for Auths Proof Protocol V1" [features] diff --git a/exchange/testkit/auths-proof-exchange-testkit/Cargo.toml b/exchange/testkit/auths-proof-exchange-testkit/Cargo.toml index 544fc9c..38f4c46 100644 --- a/exchange/testkit/auths-proof-exchange-testkit/Cargo.toml +++ b/exchange/testkit/auths-proof-exchange-testkit/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +publish = false description = "Shared conformance suite for Auths proof-exchange transports" [dependencies] diff --git a/formal/qualification/aeneas/source-closure.json b/formal/qualification/aeneas/source-closure.json index 28f136c..e756b99 100644 --- a/formal/qualification/aeneas/source-closure.json +++ b/formal/qualification/aeneas/source-closure.json @@ -1,6 +1,6 @@ { "schema": "auths-proof-translation-source-closure/v2", - "digest": "6d1b2c5ce0183e9be561e0dc6dbfcb8375d1c5f2c1b2341cae2c80a24a2fc229", + "digest": "c5f185d14eb2afa12eb39d424fab17d3b943f16fd070f60c0b8df8da40785542", "files": [ { "path": "Cargo.lock", @@ -54,7 +54,7 @@ }, { "path": "product/policy/auths-bounded-policy/Cargo.toml", - "sha256": "b177a4925578c55029c28d65f6686852abb2da4c7bbb26e4823600c601f754f2" + "sha256": "27c28805b49d49c7dd3441f1547dcf0ebe32ab5721d63003a8b464861461b00f" }, { "path": "product/policy/auths-bounded-policy/src/kernel.rs", @@ -66,7 +66,7 @@ }, { "path": "product/runtime/auths-lifecycle/Cargo.toml", - "sha256": "2fc3bcb7b95ce7afe1bcf130ae7ebd758a42002e071c8dcf0ad2ab2c945e8c79" + "sha256": "4c824075df014e28b2e7365a6604c8c33bccde645a8fd3aebe71d5daecde7199" }, { "path": "product/runtime/auths-lifecycle/src/kernel.rs", diff --git a/product/README.md b/product/README.md index ec046b6..9ce4939 100644 --- a/product/README.md +++ b/product/README.md @@ -42,9 +42,11 @@ Implemented profile contracts: - `auths.supply-chain/1`; - `auths.edge/1`. -Supported developer surfaces: +Implemented developer surfaces (only the semantic-freeze inventory determines +the release-candidate publication set): -- `auths-sdk`: trusted-context, verification, issuance, and custody facade; +- `auths-proof-sdk`: trusted-context, verification, issuance, and custody + facade selected for the first public Rust surface; - `auths-enforcement`: HTTP, gRPC, CI, MCP, and service-local enforcement entry points; - `auths-deployment`: replay- and blast-radius-safe deployment execution; diff --git a/product/cache/auths-cache/Cargo.toml b/product/cache/auths-cache/Cargo.toml index 5825c29..a04192d 100644 --- a/product/cache/auths-cache/Cargo.toml +++ b/product/cache/auths-cache/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +publish = false description = "Context-keyed bounded verification cache for Auths applications" [dependencies] diff --git a/product/config/auths-config/Cargo.toml b/product/config/auths-config/Cargo.toml index 4f8fbf4..3c7aa40 100644 --- a/product/config/auths-config/Cargo.toml +++ b/product/config/auths-config/Cargo.toml @@ -4,6 +4,8 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +repository.workspace = true +homepage.workspace = true description = "Strict target V1 application configuration" [dependencies] diff --git a/product/docs/developer-integration.md b/product/docs/developer-integration.md index 73f8848..e2b81fa 100644 --- a/product/docs/developer-integration.md +++ b/product/docs/developer-integration.md @@ -19,8 +19,9 @@ than reuse the original request. ### Rust service integration -Install `auths-sdk` and `auths-enforcement`. Configure immutable trust once, -then supply audience, challenge, and evaluation time explicitly per request: +Install `auths-proof-sdk`. The first release-candidate surface keeps the +enforcement boundary inside that SDK; configure immutable trust once, then +supply audience, challenge, and evaluation time explicitly per request: ```rust let context = TrustedContextBuilder::new(trust_anchors, assurance_policy)? @@ -47,8 +48,8 @@ runtime supplies the same invariant with challenge exchange, receipts, and transport bindings. Safe grant planning and external key custody are available from the same -package as `auths_sdk::authority` and `auths_sdk::custody`. The planner rejects -delegation widening before any signing provider is invoked. +package as `auths_proof_sdk::authority` and `auths_proof_sdk::custody`. The +planner rejects delegation widening before any signing provider is invoked. ### TypeScript diff --git a/product/integrations/auths-custody/Cargo.toml b/product/integrations/auths-custody/Cargo.toml index 0a304d7..6f7f302 100644 --- a/product/integrations/auths-custody/Cargo.toml +++ b/product/integrations/auths-custody/Cargo.toml @@ -4,6 +4,8 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +repository.workspace = true +homepage.workspace = true description = "External WebAuthn, workload, KMS, HSM, and PKCS#11 signing boundary" [dependencies] diff --git a/product/integrations/auths-deployment/Cargo.toml b/product/integrations/auths-deployment/Cargo.toml index a202aec..8b36155 100644 --- a/product/integrations/auths-deployment/Cargo.toml +++ b/product/integrations/auths-deployment/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +publish = false description = "Replay-safe Auths V1 internal deployment enforcement" [dependencies] diff --git a/product/integrations/auths-enforcement/Cargo.toml b/product/integrations/auths-enforcement/Cargo.toml index a708adc..4cf0f86 100644 --- a/product/integrations/auths-enforcement/Cargo.toml +++ b/product/integrations/auths-enforcement/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +publish = false description = "Transport-neutral in-process enforcement kit for Auths V1" [dependencies] diff --git a/product/integrations/auths-evidence-assemblers/Cargo.toml b/product/integrations/auths-evidence-assemblers/Cargo.toml index 5321046..053241e 100644 --- a/product/integrations/auths-evidence-assemblers/Cargo.toml +++ b/product/integrations/auths-evidence-assemblers/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +publish = false description = "Effect-boundary assemblers for target Auths principal evidence" [dependencies] diff --git a/product/integrations/auths-github/Cargo.toml b/product/integrations/auths-github/Cargo.toml index 7f36367..0fd6392 100644 --- a/product/integrations/auths-github/Cargo.toml +++ b/product/integrations/auths-github/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +publish = false description = "Exact Auths authorization and replay-safe execution for GitHub issue workflows" [features] diff --git a/product/integrations/auths-kubernetes/Cargo.toml b/product/integrations/auths-kubernetes/Cargo.toml index f4b57c1..479dbc9 100644 --- a/product/integrations/auths-kubernetes/Cargo.toml +++ b/product/integrations/auths-kubernetes/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +publish = false description = "Exact, replay-safe Auths authorization for Kubernetes workload rollouts" repository.workspace = true homepage.workspace = true diff --git a/product/integrations/auths-opentofu/Cargo.toml b/product/integrations/auths-opentofu/Cargo.toml index aaa1619..268db44 100644 --- a/product/integrations/auths-opentofu/Cargo.toml +++ b/product/integrations/auths-opentofu/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +publish = false description = "Exact, replay-safe Auths authorization for OpenTofu saved-plan application" repository.workspace = true homepage.workspace = true diff --git a/product/integrations/auths-postgresql/Cargo.toml b/product/integrations/auths-postgresql/Cargo.toml index c3862c5..a3a16e5 100644 --- a/product/integrations/auths-postgresql/Cargo.toml +++ b/product/integrations/auths-postgresql/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +publish = false description = "Typed, bounded, replay-safe Auths authorization for PostgreSQL updates" repository.workspace = true homepage.workspace = true diff --git a/product/integrations/auths-radicle/Cargo.toml b/product/integrations/auths-radicle/Cargo.toml index 91a84c5..f0ea9ed 100644 --- a/product/integrations/auths-radicle/Cargo.toml +++ b/product/integrations/auths-radicle/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +publish = false description = "Exact Auths authorization and sealed execution for Radicle issue patches" [features] diff --git a/product/integrations/auths-records-api/Cargo.toml b/product/integrations/auths-records-api/Cargo.toml index 9c49775..8bd59c4 100644 --- a/product/integrations/auths-records-api/Cargo.toml +++ b/product/integrations/auths-records-api/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +publish = false description = "Transport-neutral, bounded Auths authorization for a typed records API" repository.workspace = true homepage.workspace = true diff --git a/product/integrations/auths-resolver-did-web/Cargo.toml b/product/integrations/auths-resolver-did-web/Cargo.toml index 1801d98..d491109 100644 --- a/product/integrations/auths-resolver-did-web/Cargo.toml +++ b/product/integrations/auths-resolver-did-web/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +publish = false description = "Policy-constrained live did:web evidence acquisition for Auths applications" [dependencies] diff --git a/product/integrations/auths-stripe/Cargo.toml b/product/integrations/auths-stripe/Cargo.toml index d85b620..bc51f37 100644 --- a/product/integrations/auths-stripe/Cargo.toml +++ b/product/integrations/auths-stripe/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +publish = false description = "Exact, replay-safe Auths authorization for Stripe domain effects" [features] diff --git a/product/operations/auths-operations/Cargo.toml b/product/operations/auths-operations/Cargo.toml index f301e5d..2f013f7 100644 --- a/product/operations/auths-operations/Cargo.toml +++ b/product/operations/auths-operations/Cargo.toml @@ -4,6 +4,8 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +repository.workspace = true +homepage.workspace = true description = "Readiness, stable metrics, and privacy-preserving diagnostics for Auths applications" [dependencies] diff --git a/product/policy/auths-bounded-policy/Cargo.toml b/product/policy/auths-bounded-policy/Cargo.toml index a2b0023..e7574e8 100644 --- a/product/policy/auths-bounded-policy/Cargo.toml +++ b/product/policy/auths-bounded-policy/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +publish = false description = "Pure, closed bounded-authorization commitments and eligibility semantics" [features] diff --git a/product/profiles/auths-profile-api/Cargo.toml b/product/profiles/auths-profile-api/Cargo.toml index 83460f7..5c1b640 100644 --- a/product/profiles/auths-profile-api/Cargo.toml +++ b/product/profiles/auths-profile-api/Cargo.toml @@ -4,6 +4,8 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +repository.workspace = true +homepage.workspace = true description = "Sealed verified-action profile boundary for Auths applications" [dependencies] diff --git a/product/profiles/auths-profile-domains/Cargo.toml b/product/profiles/auths-profile-domains/Cargo.toml index 8b463c9..f7ccd67 100644 --- a/product/profiles/auths-profile-domains/Cargo.toml +++ b/product/profiles/auths-profile-domains/Cargo.toml @@ -4,6 +4,8 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +repository.workspace = true +homepage.workspace = true description = "Target V1 HTTP, Git, deployment, supply-chain, and edge action profiles" [dependencies] diff --git a/product/profiles/auths-profile-mcp/Cargo.toml b/product/profiles/auths-profile-mcp/Cargo.toml index bb8d802..1431e80 100644 --- a/product/profiles/auths-profile-mcp/Cargo.toml +++ b/product/profiles/auths-profile-mcp/Cargo.toml @@ -4,6 +4,8 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +repository.workspace = true +homepage.workspace = true description = "Canonical Auths action profile for exact MCP tool calls" [dependencies] diff --git a/product/receipts/auths-receipts/Cargo.toml b/product/receipts/auths-receipts/Cargo.toml index b11e821..c4988de 100644 --- a/product/receipts/auths-receipts/Cargo.toml +++ b/product/receipts/auths-receipts/Cargo.toml @@ -4,6 +4,8 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +repository.workspace = true +homepage.workspace = true description = "Canonical offline-verifiable Auths decision and execution receipts" [dependencies] diff --git a/product/runtime/auths-lifecycle/Cargo.toml b/product/runtime/auths-lifecycle/Cargo.toml index a5e406b..a110b68 100644 --- a/product/runtime/auths-lifecycle/Cargo.toml +++ b/product/runtime/auths-lifecycle/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +publish = false description = "Pure reservation and execution lifecycle semantics for bounded Auths actions" [features] diff --git a/product/runtime/auths-runtime/Cargo.toml b/product/runtime/auths-runtime/Cargo.toml index cc8b7c6..8fc881a 100644 --- a/product/runtime/auths-runtime/Cargo.toml +++ b/product/runtime/auths-runtime/Cargo.toml @@ -4,6 +4,8 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +repository.workspace = true +homepage.workspace = true description = "Authorization-before-execution service for Auths-protected MCP tools" [dependencies] diff --git a/product/sdk/auths-profile-kit/Cargo.toml b/product/sdk/auths-profile-kit/Cargo.toml index e4bb92b..ea7d77f 100644 --- a/product/sdk/auths-profile-kit/Cargo.toml +++ b/product/sdk/auths-profile-kit/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +publish = false description = "Conformance and fixture kit for Auths V1 application profiles" [dependencies] diff --git a/product/sdk/auths-sdk/Cargo.toml b/product/sdk/auths-sdk/Cargo.toml index 129bce6..b0f8e93 100644 --- a/product/sdk/auths-sdk/Cargo.toml +++ b/product/sdk/auths-sdk/Cargo.toml @@ -1,9 +1,11 @@ [package] -name = "auths-sdk" +name = "auths-proof-sdk" version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +repository.workspace = true +homepage.workspace = true description = "Idiomatic embedded Auths enforcement SDK" [dependencies] @@ -25,7 +27,7 @@ thiserror.workspace = true [dev-dependencies] auths-codec.workspace = true -auths-testkit.workspace = true +auths-testkit = { path = "../../../core/testkit/auths-testkit" } [lints] workspace = true diff --git a/product/stores/auths-stores/Cargo.toml b/product/stores/auths-stores/Cargo.toml index 3ba95d5..bdc1aa9 100644 --- a/product/stores/auths-stores/Cargo.toml +++ b/product/stores/auths-stores/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true +publish = false description = "Concrete replay-adjacent budget and canonical receipt stores for Auths applications" [dependencies] diff --git a/release/semantic-freeze.json b/release/semantic-freeze.json new file mode 100644 index 0000000..a744de3 --- /dev/null +++ b/release/semantic-freeze.json @@ -0,0 +1,646 @@ +{ + "schema": "auths.semantic-freeze/1", + "freezeVersion": 1, + "publicSurface": { + "rustRoots": [ + "auths-proof", + "auths-proof-sdk" + ], + "rustPublishableClosure": [ + "auths-algebra-kernel", + "auths-assurance", + "auths-author", + "auths-authority", + "auths-codec", + "auths-composition", + "auths-config", + "auths-custody", + "auths-did-keri", + "auths-did-key", + "auths-model", + "auths-multikey", + "auths-operations", + "auths-ports", + "auths-profile-api", + "auths-profile-domains", + "auths-profile-mcp", + "auths-proof", + "auths-proof-exchange-model", + "auths-proof-exchange-port", + "auths-proof-sdk", + "auths-raw-key", + "auths-receipts", + "auths-registries", + "auths-runtime", + "auths-signature", + "auths-verifier" + ], + "releaseArtifactFamilies": [ + "source-archive", + "rust-crates", + "npm:@auths-dev/proof", + "pypi:auths-proof", + "assurance-bundle" + ], + "deferredSurfaceIssue": "https://github.com/auths-dev/auths-proof/issues/51" + }, + "entries": [ + { + "id": "auths.core.protocol", + "version": 1, + "classification": "frozen-meaning", + "categories": [ + "protocol-versions", + "canonicalization", + "decision-codes", + "denial-codes", + "indeterminate-codes" + ], + "owners": [ + "core/crates/auths-codec/src", + "core/crates/auths-model/src", + "core/crates/auths-verifier/src", + "core/spec/v1" + ], + "sha256": "d1c4804a5b20837f5d9760810d1c8740d914c94a8390c26cc7552abf9b5bdb71" + }, + { + "id": "auths.frozen-bytes/architecture/dependency-graph.json", + "version": 1, + "classification": "frozen-bytes", + "categories": [ + "canonical-generated-evidence" + ], + "owners": [ + "architecture/dependency-graph.json" + ], + "sha256": "29d91ceab86672bdb36ce699063fdee15f89bd1227a21cf1d9f227d8e4e9369f" + }, + { + "id": "auths.frozen-bytes/bounded-domains.toml", + "version": 1, + "classification": "frozen-bytes", + "categories": [ + "canonical-generated-evidence" + ], + "owners": [ + "bounded-domains.toml" + ], + "sha256": "ab98e4334825befa277754c61b0aa3981737f94bb4002378e59944c9870a6c0f" + }, + { + "id": "auths.frozen-bytes/core/conformance/v1/manifest.json", + "version": 1, + "classification": "frozen-bytes", + "categories": [ + "canonical-generated-evidence" + ], + "owners": [ + "core/conformance/v1/manifest.json" + ], + "sha256": "b4084b9a0abee6ad937564afccf1ae6745d0ffc8bce11eb1c984b04c01011c1d" + }, + { + "id": "auths.frozen-bytes/core/explanations/v1/fact-inventory.json", + "version": 1, + "classification": "frozen-bytes", + "categories": [ + "canonical-generated-evidence" + ], + "owners": [ + "core/explanations/v1/fact-inventory.json" + ], + "sha256": "9229bee508acde9e58b7932cdedb500586f9171f3f855f3af0eb959f08decb3e" + }, + { + "id": "auths.frozen-bytes/core/fixtures/v1/manifest.json", + "version": 1, + "classification": "frozen-bytes", + "categories": [ + "canonical-generated-evidence" + ], + "owners": [ + "core/fixtures/v1/manifest.json" + ], + "sha256": "4baf2e0edd4580c9fe9bb766e70a118131069e811ab3a7638df0094f3842dba4" + }, + { + "id": "auths.frozen-bytes/core/formal-vectors/v1/manifest.json", + "version": 1, + "classification": "frozen-bytes", + "categories": [ + "canonical-generated-evidence" + ], + "owners": [ + "core/formal-vectors/v1/manifest.json" + ], + "sha256": "810a236c0051d71a40e3e3fb5afd200cd44a3ce93e79121b1c2ed9a0d7a21aa7" + }, + { + "id": "auths.frozen-bytes/demos/benchmarks/profiles/release.toml", + "version": 1, + "classification": "frozen-bytes", + "categories": [ + "canonical-generated-evidence" + ], + "owners": [ + "demos/benchmarks/profiles/release.toml" + ], + "sha256": "b7ffa1d3f31dff132383eb5846ba33596d4df8256e0cca2bb96307bc6c3d8a46" + }, + { + "id": "auths.frozen-bytes/formal/assurance-manifest-v1.toml", + "version": 1, + "classification": "frozen-bytes", + "categories": [ + "canonical-generated-evidence" + ], + "owners": [ + "formal/assurance-manifest-v1.toml" + ], + "sha256": "93a913e2bca5362e59b50a3314abb546ae8ad7dd36691b97a2000af131258d03" + }, + { + "id": "auths.frozen-bytes/formal/qualification/aeneas/generated", + "version": 1, + "classification": "frozen-bytes", + "categories": [ + "canonical-generated-evidence" + ], + "owners": [ + "formal/qualification/aeneas/generated" + ], + "sha256": "1f7a81121e57479f6aaa5ad853d9f1c750e162a8a09ef49d766be821a115d579" + }, + { + "id": "auths.frozen-bytes/formal/qualification/aeneas/qualification.toml", + "version": 1, + "classification": "frozen-bytes", + "categories": [ + "canonical-generated-evidence" + ], + "owners": [ + "formal/qualification/aeneas/qualification.toml" + ], + "sha256": "9b2c4e18a78d57f32c556125bd7afbb0df07e96f14b2476cbb75d94600616820" + }, + { + "id": "auths.frozen-bytes/formal/qualification/aeneas/source-closure.json", + "version": 1, + "classification": "frozen-bytes", + "categories": [ + "canonical-generated-evidence" + ], + "owners": [ + "formal/qualification/aeneas/source-closure.json" + ], + "sha256": "90d29e1ad717faacf3a1108a0a682578be341692fd2ec8a472c136174179fa32" + }, + { + "id": "auths.frozen-bytes/product/fixtures/v1/bounded-policy/manifest.json", + "version": 1, + "classification": "frozen-bytes", + "categories": [ + "canonical-generated-evidence" + ], + "owners": [ + "product/fixtures/v1/bounded-policy/manifest.json" + ], + "sha256": "7ea9054107afccae87c2e0e917f25eb41769f95166b068445d78792824377c6f" + }, + { + "id": "auths.frozen-bytes/product/fixtures/v1/github/manifest.json", + "version": 1, + "classification": "frozen-bytes", + "categories": [ + "canonical-generated-evidence" + ], + "owners": [ + "product/fixtures/v1/github/manifest.json" + ], + "sha256": "d5f73768102f002131c94b9f4f445385b1324e5cacb6d67c93225250b37afce8" + }, + { + "id": "auths.frozen-bytes/product/fixtures/v1/kubernetes/manifest.json", + "version": 1, + "classification": "frozen-bytes", + "categories": [ + "canonical-generated-evidence" + ], + "owners": [ + "product/fixtures/v1/kubernetes/manifest.json" + ], + "sha256": "4a7f6f7a4ff27623ec6ef1cd3a174b5fcdd6b12284c5e1d0bf4838c44422a91a" + }, + { + "id": "auths.frozen-bytes/product/fixtures/v1/lifecycle/manifest.json", + "version": 1, + "classification": "frozen-bytes", + "categories": [ + "canonical-generated-evidence" + ], + "owners": [ + "product/fixtures/v1/lifecycle/manifest.json" + ], + "sha256": "263c24af6e9fbe8c03b447238ca44fc49b445dfc1ed23cbefb34fa42fa158eac" + }, + { + "id": "auths.frozen-bytes/product/fixtures/v1/opentofu/manifest.json", + "version": 1, + "classification": "frozen-bytes", + "categories": [ + "canonical-generated-evidence" + ], + "owners": [ + "product/fixtures/v1/opentofu/manifest.json" + ], + "sha256": "9703c708f4a2369d6ed642e54eb32f91800f06ffe60300d4fb560e01c45b1562" + }, + { + "id": "auths.frozen-bytes/product/fixtures/v1/postgresql/manifest.json", + "version": 1, + "classification": "frozen-bytes", + "categories": [ + "canonical-generated-evidence" + ], + "owners": [ + "product/fixtures/v1/postgresql/manifest.json" + ], + "sha256": "76a17b803ad99e37eee110d956c37b6d94878fac8d08cf36156ab4de3a8794c6" + }, + { + "id": "auths.frozen-bytes/product/fixtures/v1/radicle/manifest.json", + "version": 1, + "classification": "frozen-bytes", + "categories": [ + "canonical-generated-evidence" + ], + "owners": [ + "product/fixtures/v1/radicle/manifest.json" + ], + "sha256": "301c07962e7fe7e8847a8bbe0ca664e6aaeea65221e8eb5093a70d0688078533" + }, + { + "id": "auths.frozen-bytes/product/fixtures/v1/records-api/manifest.json", + "version": 1, + "classification": "frozen-bytes", + "categories": [ + "canonical-generated-evidence" + ], + "owners": [ + "product/fixtures/v1/records-api/manifest.json" + ], + "sha256": "28a95d1a948a0dea0f45b9c387437905cca6ebc7c748652878f528a19a9c109b" + }, + { + "id": "auths.frozen-bytes/product/fixtures/v1/stripe/manifest.json", + "version": 1, + "classification": "frozen-bytes", + "categories": [ + "canonical-generated-evidence" + ], + "owners": [ + "product/fixtures/v1/stripe/manifest.json" + ], + "sha256": "ce6e1f24fab76a208fbffc125d7701b9f0fe30f901565621d4499531f48df848" + }, + { + "id": "auths.frozen-bytes/product/integrations/auths-stripe/fixtures/connect-transfer/v1/manifest.sha256.json", + "version": 1, + "classification": "frozen-bytes", + "categories": [ + "canonical-generated-evidence" + ], + "owners": [ + "product/integrations/auths-stripe/fixtures/connect-transfer/v1/manifest.sha256.json" + ], + "sha256": "f944750f40de9976b975eb60f2c6732045ea601df588e87b39583e57f3fe0f67" + }, + { + "id": "auths.frozen-bytes/product/integrations/auths-stripe/fixtures/merchant-authorize/v1/manifest.sha256.json", + "version": 1, + "classification": "frozen-bytes", + "categories": [ + "canonical-generated-evidence" + ], + "owners": [ + "product/integrations/auths-stripe/fixtures/merchant-authorize/v1/manifest.sha256.json" + ], + "sha256": "eed9269994e703e1df3ff58129628775ecd800530a9efcd22a1cf59e66263f7b" + }, + { + "id": "auths.frozen-bytes/product/integrations/auths-stripe/fixtures/merchant-cancel/v1/manifest.sha256.json", + "version": 1, + "classification": "frozen-bytes", + "categories": [ + "canonical-generated-evidence" + ], + "owners": [ + "product/integrations/auths-stripe/fixtures/merchant-cancel/v1/manifest.sha256.json" + ], + "sha256": "cfc2104216c1a26cc3f0f85ec97bbe3dc575f8584731aeb27910823f1f74d3f9" + }, + { + "id": "auths.frozen-bytes/product/integrations/auths-stripe/fixtures/merchant-capture/v1/manifest.sha256.json", + "version": 1, + "classification": "frozen-bytes", + "categories": [ + "canonical-generated-evidence" + ], + "owners": [ + "product/integrations/auths-stripe/fixtures/merchant-capture/v1/manifest.sha256.json" + ], + "sha256": "ee0e556e3dbf8c4746eac924dc78326b25e76a880f0595bc22ed56c23a475c20" + }, + { + "id": "auths.frozen-bytes/product/integrations/auths-stripe/fixtures/merchant-collect/v1/manifest.sha256.json", + "version": 1, + "classification": "frozen-bytes", + "categories": [ + "canonical-generated-evidence" + ], + "owners": [ + "product/integrations/auths-stripe/fixtures/merchant-collect/v1/manifest.sha256.json" + ], + "sha256": "aa54e81dcb7f860feb6290b3816c2d6713be9592ba0b84e3e456df175f50bff0" + }, + { + "id": "auths.frozen-bytes/product/integrations/auths-stripe/fixtures/payment-mandate/v1/manifest.sha256.json", + "version": 1, + "classification": "frozen-bytes", + "categories": [ + "canonical-generated-evidence" + ], + "owners": [ + "product/integrations/auths-stripe/fixtures/payment-mandate/v1/manifest.sha256.json" + ], + "sha256": "633536298bf7087bd1292ec3f35f835b9b60d5363139903e7f1a984344d17318" + }, + { + "id": "auths.frozen-bytes/product/integrations/auths-stripe/fixtures/payout/v1/manifest.sha256.json", + "version": 1, + "classification": "frozen-bytes", + "categories": [ + "canonical-generated-evidence" + ], + "owners": [ + "product/integrations/auths-stripe/fixtures/payout/v1/manifest.sha256.json" + ], + "sha256": "ba5bc84535b01c5a53ad40ad2cf40eed7a36042e27fb81c1845e0198fb2012c2" + }, + { + "id": "auths.frozen-bytes/product/integrations/auths-stripe/fixtures/purchase-authorization/v1/manifest.sha256.json", + "version": 1, + "classification": "frozen-bytes", + "categories": [ + "canonical-generated-evidence" + ], + "owners": [ + "product/integrations/auths-stripe/fixtures/purchase-authorization/v1/manifest.sha256.json" + ], + "sha256": "1c1dedad5b3acc19d3ec3c4c93301fef2bd9f9260b2373b9b109b54229d9ac58" + }, + { + "id": "auths.frozen-bytes/product/integrations/auths-stripe/fixtures/subscription-cancel/v1/manifest.sha256.json", + "version": 1, + "classification": "frozen-bytes", + "categories": [ + "canonical-generated-evidence" + ], + "owners": [ + "product/integrations/auths-stripe/fixtures/subscription-cancel/v1/manifest.sha256.json" + ], + "sha256": "a75c08a7ce1ca3df7b61e6db6918ed2a98aae7529f7c2a60c2cede9ca6cd1a74" + }, + { + "id": "auths.frozen-bytes/product/integrations/auths-stripe/fixtures/subscription-create/v1/manifest.sha256.json", + "version": 1, + "classification": "frozen-bytes", + "categories": [ + "canonical-generated-evidence" + ], + "owners": [ + "product/integrations/auths-stripe/fixtures/subscription-create/v1/manifest.sha256.json" + ], + "sha256": "fb143c5deea2ec39a7f37f406b3086bb3a448da42449048b5f6505a2a40104c1" + }, + { + "id": "auths.frozen-bytes/product/integrations/auths-stripe/fixtures/subscription-modify/v1/manifest.sha256.json", + "version": 1, + "classification": "frozen-bytes", + "categories": [ + "canonical-generated-evidence" + ], + "owners": [ + "product/integrations/auths-stripe/fixtures/subscription-modify/v1/manifest.sha256.json" + ], + "sha256": "bbc575037f692a674b0d6a134f1f0560e5c55be05d1c6045a1f07f3c50e611f5" + }, + { + "id": "auths.frozen-bytes/product/integrations/auths-stripe/fixtures/v1/manifest.sha256.json", + "version": 1, + "classification": "frozen-bytes", + "categories": [ + "canonical-generated-evidence" + ], + "owners": [ + "product/integrations/auths-stripe/fixtures/v1/manifest.sha256.json" + ], + "sha256": "dde33d6a7078afd172e43b100bfd96871719871562bca0f325c3c8cf229c005f" + }, + { + "id": "auths.portable-abi-bindings", + "version": 1, + "classification": "frozen-meaning", + "categories": [ + "portable-abi", + "binding-contracts" + ], + "owners": [ + "bindings/python/src", + "bindings/typescript/src", + "core/crates/auths-model/src/lib.rs", + "core/spec/v1/auths-proof.cddl" + ], + "sha256": "226bd2a55b50e19abda62e28f393b23f57f2b1a2f78d14ae947c3c252d74178e" + }, + { + "id": "auths.product.bounded-domains", + "version": 1, + "classification": "frozen-meaning", + "categories": [ + "bounded-domain-inventory", + "exact-action-profiles", + "domain-evaluators", + "domain-lifecycle-transitions", + "domain-credential-scopes", + "domain-provider-gateways", + "domain-receipt-meanings" + ], + "owners": [ + "bounded-domains.toml", + "product/integrations/auths-github/src", + "product/integrations/auths-kubernetes/src", + "product/integrations/auths-opentofu/src", + "product/integrations/auths-postgresql/src", + "product/integrations/auths-radicle/src", + "product/integrations/auths-records-api/src", + "product/integrations/auths-stripe/src" + ], + "sha256": "6eaaa15b11d1cd9f4826c91582c1c02f22e596645ac8d1927e3663957199a5c9" + }, + { + "id": "auths.product.bounded-policy", + "version": 1, + "classification": "frozen-meaning", + "categories": [ + "policy-semantic-ids", + "evaluator-semantic-ids", + "optimized-evaluator-semantic-ids" + ], + "owners": [ + "product/fixtures/v1/bounded-policy/registry.toml", + "product/policy/auths-bounded-policy/src" + ], + "sha256": "3c9c768053d86461db1122a3a048c8e882ecbf95c0fd0e2fa46ac5436a422bc6" + }, + { + "id": "auths.product.configuration-commitments", + "version": 1, + "classification": "frozen-meaning", + "categories": [ + "required-configuration-commitments", + "executed-configuration-commitments" + ], + "owners": [ + "product/policy/auths-bounded-policy/src/commitment.rs", + "product/policy/auths-bounded-policy/src/receipt.rs" + ], + "sha256": "04ccf138a489ad9bdffdf2fe31d2c8a2b27166d2580fcd1ec36c7a57b3e2401e" + }, + { + "id": "auths.product.lifecycle", + "version": 1, + "classification": "frozen-meaning", + "categories": [ + "reservation-state", + "claim-state", + "execution-state", + "reconciliation-state", + "lifecycle-codes" + ], + "owners": [ + "product/fixtures/v1/lifecycle/registry.toml", + "product/runtime/auths-lifecycle/src", + "product/stores/auths-stores/migrations/postgres_lifecycle_v1.sql", + "product/stores/auths-stores/src/lifecycle.rs" + ], + "sha256": "9d6eaa653aa1ca363b0c1cf00788812541e1405d72e689d9a723ce24ba49164b" + }, + { + "id": "auths.product.public-sdk-contract", + "version": 1, + "classification": "frozen-meaning", + "categories": [ + "rust-sdk-contract", + "exact-action-profiles", + "custody-boundary", + "runtime-boundary" + ], + "owners": [ + "compliance.toml", + "product/integrations/auths-custody/src", + "product/profiles/auths-profile-api/src", + "product/profiles/auths-profile-domains/src", + "product/profiles/auths-profile-mcp/src", + "product/runtime/auths-runtime/src", + "product/sdk/auths-sdk/src" + ], + "sha256": "cd75175c48f91cb599af0591217a96bd3d0eac54b52389ab01a5f2d54afb0094" + }, + { + "id": "auths.product.receipts", + "version": 1, + "classification": "frozen-meaning", + "categories": [ + "receipt-schemas", + "receipt-commitment-meanings" + ], + "owners": [ + "product/receipts/auths-receipts/src", + "product/spec/v1/receipts.md" + ], + "sha256": "fba4bebc2859a5ddb85bf5622e06f86c72d5d5676508e48cda84a5b608733e84" + }, + { + "id": "auths.release.benchmark-contract", + "version": 1, + "classification": "frozen-meaning", + "categories": [ + "benchmark-definition", + "accepted-baseline" + ], + "owners": [ + "demos/benchmarks/auths-bench-model/src", + "demos/benchmarks/profiles/release.toml", + "docs/research/domains/0004-seven-domain-bounded-authorization-performance-baseline.md", + "xtask/src/benchmark.rs", + "xtask/src/bounded_benchmark.rs" + ], + "sha256": "5ab1724d756feff29bdd2a64c01063dd769aee3fe16a1d0e5ff090c41cac22ba" + }, + { + "id": "auths.release.public-surface", + "version": 1, + "classification": "release-metadata", + "categories": [ + "package-names", + "package-versions", + "publishable-closure", + "binding-names", + "toolchains" + ], + "owners": [ + "Cargo.lock", + "Cargo.toml", + "architecture.toml", + "bindings/python/pyproject.toml", + "bindings/typescript/package-lock.json", + "bindings/typescript/package.json", + "core/adapters/auths-did-keri/Cargo.toml", + "core/adapters/auths-did-key/Cargo.toml", + "core/adapters/auths-raw-key/Cargo.toml", + "core/crates/auths-algebra-kernel/Cargo.toml", + "core/crates/auths-assurance/Cargo.toml", + "core/crates/auths-author/Cargo.toml", + "core/crates/auths-authority/Cargo.toml", + "core/crates/auths-codec/Cargo.toml", + "core/crates/auths-composition/Cargo.toml", + "core/crates/auths-model/Cargo.toml", + "core/crates/auths-multikey/Cargo.toml", + "core/crates/auths-ports/Cargo.toml", + "core/crates/auths-proof/Cargo.toml", + "core/crates/auths-registries/Cargo.toml", + "core/crates/auths-signature/Cargo.toml", + "core/crates/auths-verifier/Cargo.toml", + "docs/plans/PHASE_7_RELEASE_OWNER_DECISIONS.md", + "exchange/crates/auths-proof-exchange-model/Cargo.toml", + "exchange/crates/auths-proof-exchange-port/Cargo.toml", + "product/config/auths-config/Cargo.toml", + "product/integrations/auths-custody/Cargo.toml", + "product/operations/auths-operations/Cargo.toml", + "product/profiles/auths-profile-api/Cargo.toml", + "product/profiles/auths-profile-domains/Cargo.toml", + "product/profiles/auths-profile-mcp/Cargo.toml", + "product/receipts/auths-receipts/Cargo.toml", + "product/runtime/auths-runtime/Cargo.toml", + "product/sdk/auths-sdk/Cargo.toml", + "rust-toolchain.toml", + "xtask/src/architecture.rs", + "xtask/src/fixtures.rs", + "xtask/src/semantic_freeze.rs" + ], + "sha256": "9f90d0025a03e87ff91df60c11e677a94fc602fbc9064c7900e71fadc1814f79" + } + ] +} diff --git a/xtask/src/architecture.rs b/xtask/src/architecture.rs index cee4d46..2113c7d 100644 --- a/xtask/src/architecture.rs +++ b/xtask/src/architecture.rs @@ -629,10 +629,31 @@ pub(crate) fn core_boundary() -> Result<(), String> { .ok_or_else(|| format!("core package {package} has no workspace path"))?; let manifest = fs::read_to_string(package_root.join("Cargo.toml")) .map_err(|error| format!("could not read {package} manifest: {error}"))?; - for line in manifest.lines().filter(|line| line.contains("path")) { - if line.contains("../..") { + let manifest: toml::Value = toml::from_str(&manifest) + .map_err(|error| format!("could not parse {package} manifest: {error}"))?; + let mut dependency_paths = Vec::new(); + collect_dependency_paths(&manifest, &mut dependency_paths); + let core_root = fs::canonicalize(root().join("core")) + .map_err(|error| format!("could not resolve core boundary: {error}"))?; + for dependency_path in dependency_paths { + let dependency_path = Path::new(dependency_path); + if dependency_path.is_absolute() { return Err(format!( - "core manifest {package} has a path escaping core/: {line}" + "core manifest {package} has an absolute dependency path: {}", + dependency_path.display() + )); + } + let resolved = + fs::canonicalize(package_root.join(dependency_path)).map_err(|error| { + format!( + "core manifest {package} has an unresolved dependency path {}: {error}", + dependency_path.display() + ) + })?; + if !resolved.starts_with(&core_root) { + return Err(format!( + "core manifest {package} has a dependency path escaping core/: {}", + dependency_path.display() )); } } @@ -642,6 +663,29 @@ pub(crate) fn core_boundary() -> Result<(), String> { Ok(()) } +fn collect_dependency_paths<'a>(value: &'a toml::Value, paths: &mut Vec<&'a str>) { + let Some(table) = value.as_table() else { + return; + }; + for (key, nested) in table { + if matches!( + key.as_str(), + "dependencies" | "dev-dependencies" | "build-dependencies" + ) { + if let Some(dependencies) = nested.as_table() { + paths.extend(dependencies.values().filter_map(|dependency| { + dependency + .as_table() + .and_then(|specification| specification.get("path")) + .and_then(toml::Value::as_str) + })); + } + } else { + collect_dependency_paths(nested, paths); + } + } +} + pub(crate) fn workspace_package_paths() -> Result, String> { let output = Command::new("cargo") .args(["metadata", "--format-version", "1", "--no-deps"]) @@ -895,3 +939,30 @@ pub(crate) fn files_with_extension( files.sort(); Ok(files) } + +#[cfg(test)] +mod dependency_path_tests { + use super::*; + + #[test] + fn dependency_paths_are_collected_from_top_level_and_target_tables() { + let manifest: toml::Value = toml::from_str( + r#" + [dependencies] + local = { path = "../local" } + registry = "1" + + [target.'cfg(unix)'.dev-dependencies] + support = { path = "../../testkit/support", features = ["std"] } + + [package.metadata.example] + path = "not-a-dependency" + "#, + ) + .unwrap(); + let mut paths = Vec::new(); + collect_dependency_paths(&manifest, &mut paths); + paths.sort(); + assert_eq!(paths, ["../../testkit/support", "../local"]); + } +} diff --git a/xtask/src/checks.rs b/xtask/src/checks.rs index 19e0466..a92b4a8 100644 --- a/xtask/src/checks.rs +++ b/xtask/src/checks.rs @@ -11,6 +11,7 @@ pub(crate) fn ci() -> Result<(), String> { pub(crate) fn ci_authoritative() -> Result<(), String> { format_all()?; arch(false)?; + semantic_freeze(false)?; repository_hygiene()?; cargo(&["check", "--workspace", "--all-targets", "--all-features"])?; cargo(&["test", "--workspace", "--all-features"])?; diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 8811266..b282947 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -15,6 +15,7 @@ mod live_demo; mod prelude; mod process; mod release; +mod semantic_freeze; mod stripe; pub(crate) use architecture::*; @@ -31,9 +32,10 @@ pub(crate) use live_demo::*; pub(crate) use prelude::*; pub(crate) use process::*; pub(crate) use release::*; +pub(crate) use semantic_freeze::*; pub(crate) use stripe::*; -const USAGE: &str = "usage: cargo xtask |--adapter |--case ]|bench |ci [authoritative|formal-translation|compliance]|release-check>"; +const USAGE: &str = "usage: cargo xtask |--adapter |--case ]|bench |ci [authoritative|formal-translation|compliance]|release-check>"; fn main() -> ExitCode { match run() { @@ -67,6 +69,7 @@ fn dispatch(arguments: impl IntoIterator) -> Result<(), String> { } } "arch" => arch(args.any(|arg| arg == "--update")), + "semantic-freeze" => semantic_freeze(args.any(|arg| arg == "--update")), "fmt" => format_all(), "core-boundary" => core_boundary(), "workspace-msrv" | "core-msrv" => workspace_msrv(), @@ -135,7 +138,7 @@ mod tests { fn help_output_is_stable() { assert_eq!( USAGE, - "usage: cargo xtask |--adapter |--case ]|bench |ci [authoritative|formal-translation|compliance]|release-check>" + "usage: cargo xtask |--adapter |--case ]|bench |ci [authoritative|formal-translation|compliance]|release-check>" ); } diff --git a/xtask/src/semantic_freeze.rs b/xtask/src/semantic_freeze.rs new file mode 100644 index 0000000..3015034 --- /dev/null +++ b/xtask/src/semantic_freeze.rs @@ -0,0 +1,919 @@ +#![allow(clippy::too_many_lines)] + +use crate::*; + +const INVENTORY_PATH: &str = "release/semantic-freeze.json"; +const INVENTORY_SCHEMA: &str = "auths.semantic-freeze/1"; +const FREEZE_VERSION: u64 = 1; +const PUBLIC_RUST_ROOTS: [&str; 2] = ["auths-proof", "auths-proof-sdk"]; +const PUBLIC_RUST_CLOSURE: [&str; 27] = [ + "auths-algebra-kernel", + "auths-assurance", + "auths-author", + "auths-authority", + "auths-codec", + "auths-composition", + "auths-config", + "auths-custody", + "auths-did-keri", + "auths-did-key", + "auths-model", + "auths-multikey", + "auths-operations", + "auths-ports", + "auths-profile-api", + "auths-profile-domains", + "auths-profile-mcp", + "auths-proof", + "auths-proof-exchange-model", + "auths-proof-exchange-port", + "auths-proof-sdk", + "auths-raw-key", + "auths-receipts", + "auths-registries", + "auths-runtime", + "auths-signature", + "auths-verifier", +]; + +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +struct SemanticFreezeInventory { + schema: String, + freeze_version: u64, + public_surface: PublicSurface, + entries: Vec, +} + +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +struct PublicSurface { + rust_roots: Vec, + rust_publishable_closure: Vec, + release_artifact_families: Vec, + deferred_surface_issue: String, +} + +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +struct FreezeEntry { + id: String, + version: u64, + classification: FreezeClassification, + categories: Vec, + owners: Vec, + sha256: String, +} + +#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Serialize)] +#[serde(rename_all = "kebab-case")] +enum FreezeClassification { + FrozenMeaning, + FrozenBytes, + ReleaseMetadata, +} + +struct RustSurface { + public: PublicSurface, + package_manifests: Vec, +} + +#[derive(Deserialize)] +struct BoundedDomainRegistry { + domains: Vec, +} + +#[derive(Deserialize)] +struct BoundedDomain { + package_path: String, + status: String, +} + +pub(crate) fn semantic_freeze(update: bool) -> Result<(), String> { + let generated = generate_inventory()?; + validate_inventory(&generated)?; + let mut bytes = serde_json::to_vec_pretty(&generated) + .map_err(|error| format!("could not encode semantic freeze: {error}"))?; + bytes.push(b'\n'); + let path = root().join(INVENTORY_PATH); + + if update { + if path.is_file() { + let committed = load_inventory(&path)?; + validate_evolution(&committed, &generated)?; + } + let parent = path + .parent() + .ok_or("semantic-freeze inventory has no parent directory")?; + fs::create_dir_all(parent) + .map_err(|error| format!("could not create {}: {error}", parent.display()))?; + fs::write(&path, bytes) + .map_err(|error| format!("could not write {}: {error}", path.display()))?; + println!("semantic freeze inventory updated"); + return Ok(()); + } + + let committed = fs::read(&path).map_err(|error| { + format!( + "could not read {}: {error}; run `cargo xtask semantic-freeze --update`", + path.display() + ) + })?; + if committed != bytes { + return Err( + "semantic freeze drifted; assign new semantic identities or versions, then run \ + `cargo xtask semantic-freeze --update`" + .to_owned(), + ); + } + println!( + "semantic freeze passed ({} entries, {} public Rust packages)", + generated.entries.len(), + generated.public_surface.rust_publishable_closure.len() + ); + Ok(()) +} + +fn generate_inventory() -> Result { + let rust_surface = rust_surface()?; + let bounded_domain_sources = bounded_domain_sources()?; + + let mut entries = vec![ + freeze_entry( + "auths.core.protocol", + 1, + FreezeClassification::FrozenMeaning, + &[ + "protocol-versions", + "canonicalization", + "decision-codes", + "denial-codes", + "indeterminate-codes", + ], + vec![ + "core/spec/v1".to_owned(), + "core/crates/auths-model/src".to_owned(), + "core/crates/auths-codec/src".to_owned(), + "core/crates/auths-verifier/src".to_owned(), + ], + )?, + freeze_entry( + "auths.portable-abi-bindings", + 1, + FreezeClassification::FrozenMeaning, + &["portable-abi", "binding-contracts"], + vec![ + "core/crates/auths-model/src/lib.rs".to_owned(), + "core/spec/v1/auths-proof.cddl".to_owned(), + "bindings/typescript/src".to_owned(), + "bindings/python/src".to_owned(), + ], + )?, + freeze_entry( + "auths.product.public-sdk-contract", + 1, + FreezeClassification::FrozenMeaning, + &[ + "rust-sdk-contract", + "exact-action-profiles", + "custody-boundary", + "runtime-boundary", + ], + vec![ + "product/sdk/auths-sdk/src".to_owned(), + "product/profiles/auths-profile-api/src".to_owned(), + "product/profiles/auths-profile-domains/src".to_owned(), + "product/profiles/auths-profile-mcp/src".to_owned(), + "product/integrations/auths-custody/src".to_owned(), + "product/runtime/auths-runtime/src".to_owned(), + "compliance.toml".to_owned(), + ], + )?, + freeze_entry( + "auths.product.bounded-policy", + 1, + FreezeClassification::FrozenMeaning, + &[ + "policy-semantic-ids", + "evaluator-semantic-ids", + "optimized-evaluator-semantic-ids", + ], + vec![ + "product/fixtures/v1/bounded-policy/registry.toml".to_owned(), + "product/policy/auths-bounded-policy/src".to_owned(), + ], + )?, + freeze_entry( + "auths.product.bounded-domains", + 1, + FreezeClassification::FrozenMeaning, + &[ + "bounded-domain-inventory", + "exact-action-profiles", + "domain-evaluators", + "domain-lifecycle-transitions", + "domain-credential-scopes", + "domain-provider-gateways", + "domain-receipt-meanings", + ], + with_paths(["bounded-domains.toml"], &bounded_domain_sources), + )?, + freeze_entry( + "auths.product.lifecycle", + 1, + FreezeClassification::FrozenMeaning, + &[ + "reservation-state", + "claim-state", + "execution-state", + "reconciliation-state", + "lifecycle-codes", + ], + vec![ + "product/fixtures/v1/lifecycle/registry.toml".to_owned(), + "product/runtime/auths-lifecycle/src".to_owned(), + "product/stores/auths-stores/src/lifecycle.rs".to_owned(), + "product/stores/auths-stores/migrations/postgres_lifecycle_v1.sql".to_owned(), + ], + )?, + freeze_entry( + "auths.product.receipts", + 1, + FreezeClassification::FrozenMeaning, + &["receipt-schemas", "receipt-commitment-meanings"], + vec![ + "product/receipts/auths-receipts/src".to_owned(), + "product/spec/v1/receipts.md".to_owned(), + ], + )?, + freeze_entry( + "auths.product.configuration-commitments", + 1, + FreezeClassification::FrozenMeaning, + &[ + "required-configuration-commitments", + "executed-configuration-commitments", + ], + vec![ + "product/policy/auths-bounded-policy/src/commitment.rs".to_owned(), + "product/policy/auths-bounded-policy/src/receipt.rs".to_owned(), + ], + )?, + freeze_entry( + "auths.release.benchmark-contract", + 1, + FreezeClassification::FrozenMeaning, + &["benchmark-definition", "accepted-baseline"], + vec![ + "demos/benchmarks/profiles/release.toml".to_owned(), + "demos/benchmarks/auths-bench-model/src".to_owned(), + "xtask/src/benchmark.rs".to_owned(), + "xtask/src/bounded_benchmark.rs".to_owned(), + "docs/research/domains/0004-seven-domain-bounded-authorization-performance-baseline.md" + .to_owned(), + ], + )?, + ]; + + for (id, path) in frozen_byte_inventories()? { + entries.push(freeze_entry( + &id, + 1, + FreezeClassification::FrozenBytes, + &["canonical-generated-evidence"], + vec![path], + )?); + } + + let mut release_owners = rust_surface.package_manifests; + release_owners.extend([ + "Cargo.toml".to_owned(), + "Cargo.lock".to_owned(), + "rust-toolchain.toml".to_owned(), + "bindings/typescript/package.json".to_owned(), + "bindings/typescript/package-lock.json".to_owned(), + "bindings/python/pyproject.toml".to_owned(), + "architecture.toml".to_owned(), + "docs/plans/PHASE_7_RELEASE_OWNER_DECISIONS.md".to_owned(), + "xtask/src/architecture.rs".to_owned(), + "xtask/src/fixtures.rs".to_owned(), + "xtask/src/semantic_freeze.rs".to_owned(), + ]); + entries.push(freeze_entry( + "auths.release.public-surface", + 1, + FreezeClassification::ReleaseMetadata, + &[ + "package-names", + "package-versions", + "publishable-closure", + "binding-names", + "toolchains", + ], + release_owners, + )?); + + entries.sort_by(|left, right| left.id.cmp(&right.id)); + Ok(SemanticFreezeInventory { + schema: INVENTORY_SCHEMA.to_owned(), + freeze_version: FREEZE_VERSION, + public_surface: rust_surface.public, + entries, + }) +} + +fn rust_surface() -> Result { + let output = Command::new("cargo") + .args([ + "metadata", + "--format-version", + "1", + "--all-features", + "--locked", + ]) + .current_dir(root()) + .output() + .map_err(|error| format!("could not inspect release package closure: {error}"))?; + if !output.status.success() { + return Err("cargo metadata failed while freezing release package closure".to_owned()); + } + let metadata: Value = serde_json::from_slice(&output.stdout) + .map_err(|error| format!("invalid cargo metadata: {error}"))?; + let packages = metadata["packages"] + .as_array() + .ok_or("cargo metadata has no packages")?; + let workspace_ids = metadata["workspace_members"] + .as_array() + .ok_or("cargo metadata has no workspace members")? + .iter() + .map(|id| { + id.as_str() + .ok_or_else(|| "workspace package id is not a string".to_owned()) + .map(str::to_owned) + }) + .collect::, _>>()?; + let mut names_by_id = BTreeMap::new(); + let mut manifest_by_name = BTreeMap::new(); + let mut publishable = BTreeSet::new(); + for package in packages { + let id = package["id"].as_str().ok_or("cargo package has no id")?; + let name = package["name"] + .as_str() + .ok_or("cargo package has no name")?; + names_by_id.insert(id.to_owned(), name.to_owned()); + if workspace_ids.contains(id) { + let manifest = Path::new( + package["manifest_path"] + .as_str() + .ok_or("workspace package has no manifest path")?, + ); + manifest_by_name.insert(name.to_owned(), repository_relative(manifest)?); + if package_is_publishable(package) { + if package["license"] != "MIT OR Apache-2.0" + || package["description"] + .as_str() + .is_none_or(|value| value.trim().is_empty()) + || package["repository"] + .as_str() + .is_none_or(|value| value.trim().is_empty()) + || package["homepage"] + .as_str() + .is_none_or(|value| value.trim().is_empty()) + { + return Err(format!( + "public package {name} must freeze its license, description, repository, and homepage" + )); + } + publishable.insert(name.to_owned()); + } + } + } + + let expected = PUBLIC_RUST_CLOSURE + .iter() + .map(|name| (*name).to_owned()) + .collect::>(); + if publishable != expected { + return Err(set_drift( + "publishable Rust package surface", + &expected, + &publishable, + )); + } + + let nodes = metadata["resolve"]["nodes"] + .as_array() + .ok_or("cargo metadata has no resolve nodes")?; + let node_by_id = nodes + .iter() + .filter_map(|node| node["id"].as_str().map(|id| (id, node))) + .collect::>(); + let roots = PUBLIC_RUST_ROOTS + .iter() + .map(|root_name| { + names_by_id + .iter() + .find_map(|(id, name)| (name == root_name).then(|| id.clone())) + .ok_or_else(|| format!("public Rust root package is absent: {root_name}")) + }) + .collect::, _>>()?; + let mut stack = roots; + let mut visited = BTreeSet::new(); + while let Some(id) = stack.pop() { + if !visited.insert(id.clone()) { + continue; + } + let node = node_by_id + .get(id.as_str()) + .ok_or_else(|| format!("cargo resolve node is absent for {id}"))?; + for dependency in node["deps"] + .as_array() + .ok_or("cargo resolve dependencies are not an array")? + { + let kinds = dependency["dep_kinds"] + .as_array() + .ok_or("cargo dependency kinds are not an array")?; + let is_normal = kinds.is_empty() + || kinds + .iter() + .any(|kind| kind["kind"].is_null() || kind["kind"] == "normal"); + if is_normal { + let dependency_id = dependency["pkg"] + .as_str() + .ok_or("cargo dependency has no package id")?; + stack.push(dependency_id.to_owned()); + } + } + } + let actual_closure = visited + .intersection(&workspace_ids) + .map(|id| { + names_by_id + .get(id) + .ok_or_else(|| format!("workspace package name is absent for {id}")) + .cloned() + }) + .collect::, _>>()?; + if actual_closure != expected { + return Err(set_drift( + "all-features normal dependency closure for public Rust roots", + &expected, + &actual_closure, + )); + } + let package_manifests = expected + .iter() + .map(|name| { + manifest_by_name + .get(name) + .ok_or_else(|| format!("manifest path is absent for public package {name}")) + .cloned() + }) + .collect::, _>>()?; + + Ok(RustSurface { + public: PublicSurface { + rust_roots: PUBLIC_RUST_ROOTS + .iter() + .map(|name| (*name).to_owned()) + .collect(), + rust_publishable_closure: expected.into_iter().collect(), + release_artifact_families: vec![ + "source-archive".to_owned(), + "rust-crates".to_owned(), + "npm:@auths-dev/proof".to_owned(), + "pypi:auths-proof".to_owned(), + "assurance-bundle".to_owned(), + ], + deferred_surface_issue: "https://github.com/auths-dev/auths-proof/issues/51".to_owned(), + }, + package_manifests, + }) +} + +fn bounded_domain_sources() -> Result, String> { + let registry_path = root().join("bounded-domains.toml"); + let registry: BoundedDomainRegistry = toml::from_str( + &fs::read_to_string(®istry_path) + .map_err(|error| format!("could not read {}: {error}", registry_path.display()))?, + ) + .map_err(|error| format!("invalid {}: {error}", registry_path.display()))?; + let mut sources = registry + .domains + .into_iter() + .filter(|domain| domain.status == "implemented") + .map(|domain| format!("{}/src", domain.package_path.trim_end_matches('/'))) + .collect::>(); + sources.sort(); + sources.dedup(); + if sources.is_empty() { + return Err("bounded-domain inventory has no implemented source owners".to_owned()); + } + for source in &sources { + validate_relative_path(source)?; + if !root().join(source).is_dir() { + return Err(format!("bounded-domain source owner is absent: {source}")); + } + } + Ok(sources) +} + +fn frozen_byte_inventories() -> Result, String> { + let mut paths = vec![ + "architecture/dependency-graph.json".to_owned(), + "bounded-domains.toml".to_owned(), + "core/conformance/v1/manifest.json".to_owned(), + "core/explanations/v1/fact-inventory.json".to_owned(), + "core/fixtures/v1/manifest.json".to_owned(), + "core/formal-vectors/v1/manifest.json".to_owned(), + "formal/assurance-manifest-v1.toml".to_owned(), + "formal/qualification/aeneas/generated".to_owned(), + "formal/qualification/aeneas/qualification.toml".to_owned(), + "formal/qualification/aeneas/source-closure.json".to_owned(), + "demos/benchmarks/profiles/release.toml".to_owned(), + ]; + paths.extend(selected_files( + &root().join("product/fixtures/v1"), + |path| path.file_name().and_then(|name| name.to_str()) == Some("manifest.json"), + )?); + paths.extend(selected_files( + &root().join("product/integrations/auths-stripe/fixtures"), + |path| path.file_name().and_then(|name| name.to_str()) == Some("manifest.sha256.json"), + )?); + paths.sort(); + paths.dedup(); + Ok(paths + .into_iter() + .map(|path| (format!("auths.frozen-bytes/{path}"), path)) + .collect()) +} + +fn selected_files( + directory: &Path, + predicate: impl Fn(&Path) -> bool + Copy, +) -> Result, String> { + if !directory.is_dir() { + return Err(format!( + "semantic source directory is absent: {}", + directory.display() + )); + } + let mut selected = Vec::new(); + visit_files(directory, &mut |path| { + if predicate(path) { + selected.push(repository_relative(path)?); + } + Ok(()) + })?; + selected.sort(); + if selected.is_empty() { + return Err(format!( + "semantic source selection is empty: {}", + directory.display() + )); + } + Ok(selected) +} + +fn freeze_entry( + id: &str, + version: u64, + classification: FreezeClassification, + categories: &[&str], + mut owners: Vec, +) -> Result { + owners.sort(); + owners.dedup(); + if id.trim().is_empty() || version == 0 || categories.is_empty() || owners.is_empty() { + return Err("semantic freeze entry is incomplete".to_owned()); + } + let sha256 = digest_owners(&owners)?; + Ok(FreezeEntry { + id: id.to_owned(), + version, + classification, + categories: categories + .iter() + .map(|category| (*category).to_owned()) + .collect(), + owners, + sha256, + }) +} + +fn digest_owners(owners: &[String]) -> Result { + let mut files = BTreeMap::>::new(); + let mut owner_names = BTreeSet::new(); + for owner in owners { + validate_relative_path(owner)?; + if !owner_names.insert(owner) { + return Err(format!("duplicate semantic owner path: {owner}")); + } + let path = root().join(owner); + let metadata = fs::symlink_metadata(&path) + .map_err(|error| format!("semantic owner is absent {owner}: {error}"))?; + if metadata.file_type().is_symlink() { + return Err(format!("semantic owner must not be a symlink: {owner}")); + } + if metadata.is_file() { + files.insert(owner.clone(), read_owned_file(&path)?); + } else if metadata.is_dir() { + let before = files.len(); + visit_files(&path, &mut |file| { + let relative = repository_relative(file)?; + files.insert(relative, read_owned_file(file)?); + Ok(()) + })?; + if files.len() == before { + return Err(format!("semantic owner directory is empty: {owner}")); + } + } else { + return Err(format!( + "semantic owner is not a file or directory: {owner}" + )); + } + } + let mut hasher = Sha256::new(); + for owner in owners { + hash_field(&mut hasher, owner.as_bytes()); + } + for (path, bytes) in files { + hash_field(&mut hasher, path.as_bytes()); + hash_field(&mut hasher, &bytes); + } + Ok(hex::encode(hasher.finalize())) +} + +fn visit_files( + directory: &Path, + visitor: &mut impl FnMut(&Path) -> Result<(), String>, +) -> Result<(), String> { + let mut entries = fs::read_dir(directory) + .map_err(|error| format!("could not read {}: {error}", directory.display()))? + .collect::, _>>() + .map_err(|error| format!("could not enumerate {}: {error}", directory.display()))?; + entries.sort_by_key(std::fs::DirEntry::file_name); + for entry in entries { + let path = entry.path(); + let metadata = fs::symlink_metadata(&path) + .map_err(|error| format!("could not inspect {}: {error}", path.display()))?; + if metadata.file_type().is_symlink() { + return Err(format!( + "semantic owner trees must not contain symlinks: {}", + path.display() + )); + } + if metadata.is_dir() { + visit_files(&path, visitor)?; + } else if metadata.is_file() { + visitor(&path)?; + } + } + Ok(()) +} + +fn read_owned_file(path: &Path) -> Result, String> { + fs::read(path).map_err(|error| format!("could not read {}: {error}", path.display())) +} + +fn hash_field(hasher: &mut Sha256, bytes: &[u8]) { + hasher.update((bytes.len() as u64).to_be_bytes()); + hasher.update(bytes); +} + +fn repository_relative(path: &Path) -> Result { + let relative = path + .strip_prefix(root()) + .map_err(|_| format!("path escapes repository: {}", path.display()))?; + let text = relative.to_string_lossy().replace('\\', "/"); + validate_relative_path(&text)?; + Ok(text) +} + +fn validate_relative_path(path: &str) -> Result<(), String> { + if path.trim().is_empty() + || Path::new(path) + .components() + .any(|component| !matches!(component, std::path::Component::Normal(_))) + { + return Err(format!( + "semantic owner path is not repository-relative: {path}" + )); + } + Ok(()) +} + +fn validate_inventory(inventory: &SemanticFreezeInventory) -> Result<(), String> { + if inventory.schema != INVENTORY_SCHEMA || inventory.freeze_version == 0 { + return Err("semantic freeze schema or version is invalid".to_owned()); + } + if inventory.public_surface.rust_roots + != PUBLIC_RUST_ROOTS + .iter() + .map(|name| (*name).to_owned()) + .collect::>() + { + return Err("semantic freeze public Rust roots drifted".to_owned()); + } + let mut identities = BTreeSet::new(); + let mut classifications = BTreeSet::new(); + for entry in &inventory.entries { + if entry.id.trim().is_empty() + || entry.version == 0 + || entry.categories.is_empty() + || entry.owners.is_empty() + || entry.sha256.len() != 64 + || !entry + .sha256 + .bytes() + .all(|byte| byte.is_ascii_digit() || (b'a'..=b'f').contains(&byte)) + { + return Err(format!("semantic freeze entry is invalid: {}", entry.id)); + } + if !identities.insert((entry.id.as_str(), entry.version)) { + return Err(format!( + "duplicate semantic freeze identity: {}@{}", + entry.id, entry.version + )); + } + classifications.insert(match entry.classification { + FreezeClassification::FrozenMeaning => "frozen-meaning", + FreezeClassification::FrozenBytes => "frozen-bytes", + FreezeClassification::ReleaseMetadata => "release-metadata", + }); + for owner in &entry.owners { + validate_relative_path(owner)?; + } + } + if classifications + != ["frozen-bytes", "frozen-meaning", "release-metadata"] + .into_iter() + .collect() + { + return Err("semantic freeze must contain all three classifications".to_owned()); + } + Ok(()) +} + +fn validate_evolution( + previous: &SemanticFreezeInventory, + proposed: &SemanticFreezeInventory, +) -> Result<(), String> { + validate_inventory(previous)?; + validate_inventory(proposed)?; + if proposed.freeze_version < previous.freeze_version { + return Err("semantic freeze version must not decrease".to_owned()); + } + if proposed != previous && proposed.freeze_version == previous.freeze_version { + return Err("semantic freeze changed without a new freezeVersion".to_owned()); + } + let proposed_entries = proposed + .entries + .iter() + .map(|entry| (entry.id.as_str(), entry)) + .collect::>(); + for old in &previous.entries { + if let Some(new) = proposed_entries.get(old.id.as_str()) + && (old.sha256 != new.sha256 || old.owners != new.owners) + && old.version == new.version + { + return Err(format!( + "{} changed under frozen identity version {}; assign a new version", + old.id, old.version + )); + } + } + Ok(()) +} + +fn load_inventory(path: &Path) -> Result { + let bytes = + fs::read(path).map_err(|error| format!("could not read {}: {error}", path.display()))?; + serde_json::from_slice(&bytes) + .map_err(|error| format!("invalid semantic freeze {}: {error}", path.display())) +} + +fn with_paths(base: [&str; N], additions: &[String]) -> Vec { + base.into_iter() + .map(str::to_owned) + .chain(additions.iter().cloned()) + .collect() +} + +fn set_drift(label: &str, expected: &BTreeSet, actual: &BTreeSet) -> String { + let missing = expected.difference(actual).cloned().collect::>(); + let extra = actual.difference(expected).cloned().collect::>(); + format!("{label} drifted; missing={missing:?}, extra={extra:?}") +} + +#[cfg(test)] +mod tests { + use super::*; + + fn digest(character: char) -> String { + std::iter::repeat_n(character, 64).collect() + } + + fn test_inventory( + freeze_version: u64, + entry_version: u64, + sha256: String, + ) -> SemanticFreezeInventory { + SemanticFreezeInventory { + schema: INVENTORY_SCHEMA.to_owned(), + freeze_version, + public_surface: PublicSurface { + rust_roots: PUBLIC_RUST_ROOTS + .iter() + .map(|name| (*name).to_owned()) + .collect(), + rust_publishable_closure: PUBLIC_RUST_CLOSURE + .iter() + .map(|name| (*name).to_owned()) + .collect(), + release_artifact_families: vec!["source-archive".to_owned()], + deferred_surface_issue: "https://example.invalid/51".to_owned(), + }, + entries: vec![ + FreezeEntry { + id: "auths.test.meaning".to_owned(), + version: entry_version, + classification: FreezeClassification::FrozenMeaning, + categories: vec!["test".to_owned()], + owners: vec!["core/spec/v1/protocol.md".to_owned()], + sha256, + }, + FreezeEntry { + id: "auths.test.bytes".to_owned(), + version: 1, + classification: FreezeClassification::FrozenBytes, + categories: vec!["test".to_owned()], + owners: vec!["core/fixtures/v1/manifest.json".to_owned()], + sha256: digest('b'), + }, + FreezeEntry { + id: "auths.test.metadata".to_owned(), + version: 1, + classification: FreezeClassification::ReleaseMetadata, + categories: vec!["test".to_owned()], + owners: vec!["Cargo.toml".to_owned()], + sha256: digest('c'), + }, + ], + } + } + + #[test] + fn same_identity_semantic_drift_is_terminal() { + let previous = test_inventory(1, 1, digest('a')); + let proposed = test_inventory(2, 1, digest('d')); + let error = validate_evolution(&previous, &proposed).expect_err("drift must fail"); + assert!(error.contains("changed under frozen identity version 1")); + } + + #[test] + fn same_identity_frozen_byte_drift_is_terminal() { + let previous = test_inventory(1, 1, digest('a')); + let mut proposed = test_inventory(2, 1, digest('a')); + proposed.entries[1].sha256 = digest('d'); + let error = validate_evolution(&previous, &proposed).expect_err("drift must fail"); + assert!(error.contains("auths.test.bytes changed under frozen identity version 1")); + } + + #[test] + fn versioned_semantic_change_requires_and_accepts_new_freeze_version() { + let previous = test_inventory(1, 1, digest('a')); + let proposed = test_inventory(2, 2, digest('d')); + validate_evolution(&previous, &proposed).expect("versioned change must pass"); + } + + #[test] + fn inventory_change_without_freeze_version_is_terminal() { + let previous = test_inventory(1, 1, digest('a')); + let proposed = test_inventory(1, 2, digest('d')); + let error = validate_evolution(&previous, &proposed).expect_err("freeze drift must fail"); + assert!(error.contains("without a new freezeVersion")); + } + + #[test] + fn owner_path_escape_is_terminal() { + assert!(validate_relative_path("../Cargo.toml").is_err()); + assert!(validate_relative_path("/tmp/Cargo.toml").is_err()); + assert!(validate_relative_path("Cargo.toml").is_ok()); + } + + #[test] + fn missing_owner_is_terminal() { + let error = digest_owners(&["definitely-not-a-semantic-owner".to_owned()]) + .expect_err("missing owner must fail"); + assert!(error.contains("semantic owner is absent")); + } + + #[test] + fn duplicate_identity_is_terminal() { + let mut inventory = test_inventory(1, 1, digest('a')); + inventory.entries.push(inventory.entries[0].clone()); + let error = validate_inventory(&inventory).expect_err("duplicate must fail"); + assert!(error.contains("duplicate semantic freeze identity")); + } +}