sdk

Radroots SDK and bindings
git clone https://radroots.dev/git/sdk.git
Log | Files | Refs | README

commit 97fdfe0efa84fb2cb5a9bd0984c978550b133be7
parent 4ac891a625014e3044ab343ac3a704c20882335d
Author: triesap <tyson@radroots.org>
Date:   Mon, 27 Jul 2026 12:48:29 +0000

ci: enforce crates release architecture

- add the repository-owned architecture and freshness aggregate
- pin the coordinated library baseline for migration checks
- isolate workflow caching from outputs and build artifacts
- document separately authorized status-check activation

Diffstat:
A.github/workflows/architecture.yml | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Adocs/engineering/ci.md | 33+++++++++++++++++++++++++++++++++
Mdocs/implementation/deviations.toml | 14+++++++++++++-
Mtools/xtask/src/architecture.rs | 6++++++
Mtools/xtask/src/check.rs | 12++++++++++++
Mtools/xtask/src/main.rs | 18+++++++++++++++++-
6 files changed, 134 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/architecture.yml b/.github/workflows/architecture.yml @@ -0,0 +1,53 @@ +name: Architecture + +on: + pull_request: + push: + branches: + - master + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: architecture-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + architecture: + name: architecture + runs-on: ubuntu-24.04 + timeout-minutes: 30 + defaults: + run: + working-directory: sdk + steps: + - name: Check out SDK source + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + path: sdk + persist-credentials: false + + - name: Check out coordinated library baseline + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + repository: radrootslabs/lib + ref: bb9832fa4c33f68b4262140599c111abb5d5480d + path: lib + persist-credentials: false + + - name: Restore Cargo download cache + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 + with: + path: | + ~/.cargo/registry/index + ~/.cargo/registry/cache + ~/.cargo/git/db + key: ${{ runner.os }}-architecture-${{ hashFiles('sdk/Cargo.lock', 'sdk/rust-toolchain.toml', 'lib/Cargo.lock', 'lib/rust-toolchain.toml') }} + + - name: Install the governed Rust toolchain + run: rustup toolchain install 1.97.1 --profile minimal --component llvm-tools-preview --target wasm32-unknown-unknown + + - name: Validate crates-release architecture + run: cargo run --locked -p radroots_sdk_xtask -- architecture-ci diff --git a/docs/engineering/ci.md b/docs/engineering/ci.md @@ -0,0 +1,33 @@ +# Architecture continuous integration + +The pull-request architecture lane is a thin GitHub adapter over the +repository-owned dispatcher: + +```sh +cargo xtask architecture-ci +``` + +The command validates the synchronized release specification, workspace and +package metadata, production dependency paths, the Cargo-resolved package-tier +graph, public API implementation leakage, SDK feature boundaries, publication +freeze, facade scaffold, language contracts, and generated-source freshness. +The workflow invokes the same dispatcher with `cargo run --locked` so lockfile +drift fails rather than being resolved implicitly. + +Until the lower public packages are available from the registry, the checked-in +developer patch configuration requires a coordinated `radrootslabs/lib` +checkout. The workflow pins that public source to +`bb9832fa4c33f68b4262140599c111abb5d5480d`; update the pin only after a +replacement commit is publicly reachable and passes the library architecture +lane. This checkout does not alter any production dependency declaration. + +The workflow grants only read access to repository contents. Action +dependencies are pinned to full commit identifiers. It caches only Cargo +registry and Git downloads, keyed by both repositories' lockfiles and governed +toolchains; generated outputs and build artifacts are never restored from the +cache. + +Repository administrators may require the `Architecture / architecture` +status after the pinned library commit and this workflow commit are publicly +reachable. Changing branch protection or other repository administration +remains a separate authorized operation. diff --git a/docs/implementation/deviations.toml b/docs/implementation/deviations.toml @@ -6,7 +6,18 @@ id = "RCRV1-DEV-001" date = "2026-07-27" status = "active" approval = "Explicit user correction dated 2026-07-27." -affected_steps = ["015", "016", "017", "018", "019", "020", "021", "022", "023"] +affected_steps = [ + "015", + "016", + "017", + "018", + "019", + "020", + "021", + "022", + "023", + "026", +] spec_anchors = [ "docs/specs/radroots_crates_release_v1.md#repository-ownership", "docs/specs/radroots_crates_release_v1.toml#repository_policy", @@ -19,6 +30,7 @@ replacement_action = "Retain the two existing standalone repositories; replace i verification = [ "Both repository-local architecture validators resolve every spec anchor.", "The synchronized architecture catalog enforces the exact 17/2 ownership partition.", + "Each standalone repository owns a required architecture CI adapter over its repository-local command surface.", ] unresolved_risk = "Parent gitlinks cannot advance until the new standalone commits are public-remote reachable under separate authorization." normative_architecture_change = false diff --git a/tools/xtask/src/architecture.rs b/tools/xtask/src/architecture.rs @@ -182,6 +182,12 @@ pub fn validate_api_boundaries(workspace_root: &Path) -> Result<(), String> { api_leakage::validate_public_api(workspace_root) } +pub fn validate_ci(workspace_root: &Path) -> Result<(), String> { + validate(workspace_root)?; + dependency_boundary::validate_resolved_boundaries(workspace_root)?; + api_leakage::validate_public_api(workspace_root) +} + fn validate_workspace_toolchain( workspace_root: &Path, architecture: &ArchitectureIdentity, diff --git a/tools/xtask/src/check.rs b/tools/xtask/src/check.rs @@ -156,6 +156,18 @@ pub fn check() -> Result<(), String> { Ok(()) } +pub fn architecture_ci(root: &Path) -> Result<(), String> { + validate_package_matrix()?; + check_publication_policy(root)?; + check_radroots_facade_scaffold(root)?; + validate_sdk_contracts(root)?; + check_sdk_feature_matrix(root)?; + check_forbidden_packages(root)?; + check_binding_crate_sources(root)?; + check_package_source_metadata(root)?; + check_generated_outputs(root) +} + fn check_radroots_facade_scaffold(root: &Path) -> Result<(), String> { let manifest_path = root.join("crates/radroots/Cargo.toml"); let manifest_raw = fs::read_to_string(&manifest_path) diff --git a/tools/xtask/src/main.rs b/tools/xtask/src/main.rs @@ -19,6 +19,7 @@ mod wasm_declarations; enum CommandAction<'a> { Architecture, + ArchitectureCi, CheckApiBoundaries, CheckDependencyBoundaries, GenerateAll, @@ -41,6 +42,11 @@ fn run(args: impl IntoIterator<Item = String>) -> Result<(), String> { let args = args.into_iter().collect::<Vec<_>>(); match command_action(&args)? { CommandAction::Architecture => architecture::validate(&fs::workspace_root()?), + CommandAction::ArchitectureCi => { + let root = fs::workspace_root()?; + architecture::validate_ci(&root)?; + check::architecture_ci(&root) + } CommandAction::CheckApiBoundaries => { architecture::validate_api_boundaries(&fs::workspace_root()?) } @@ -60,6 +66,7 @@ fn run(args: impl IntoIterator<Item = String>) -> Result<(), String> { fn command_action(args: &[String]) -> Result<CommandAction<'_>, String> { match args { [command] if command == "architecture" => Ok(CommandAction::Architecture), + [command] if command == "architecture-ci" => Ok(CommandAction::ArchitectureCi), [command] if command == "check-api-boundaries" => Ok(CommandAction::CheckApiBoundaries), [command] if command == "check-dependency-boundaries" => { Ok(CommandAction::CheckDependencyBoundaries) @@ -83,7 +90,7 @@ fn command_action(args: &[String]) -> Result<CommandAction<'_>, String> { } fn usage() -> String { - "usage: cargo xtask architecture | cargo xtask check-api-boundaries | cargo xtask check-dependency-boundaries | cargo xtask generate | cargo xtask generate ts | cargo xtask generate wasm [--package <key>] | cargo xtask generate package-metadata | cargo xtask check | cargo xtask smoke knowledge-rust-local | cargo xtask coverage run" + "usage: cargo xtask architecture | cargo xtask architecture-ci | cargo xtask check-api-boundaries | cargo xtask check-dependency-boundaries | cargo xtask generate | cargo xtask generate ts | cargo xtask generate wasm [--package <key>] | cargo xtask generate package-metadata | cargo xtask check | cargo xtask smoke knowledge-rust-local | cargo xtask coverage run" .to_owned() } @@ -101,6 +108,15 @@ mod tests { } #[test] + fn accepts_architecture_ci() { + let args = ["architecture-ci".to_owned()]; + assert!(matches!( + command_action(&args).expect("action"), + CommandAction::ArchitectureCi + )); + } + + #[test] fn accepts_api_boundary_check() { let args = ["check-api-boundaries".to_owned()]; assert!(matches!(