Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
5dafec0
feat(FOSS-454): example exercises atomic API and hostile pin from inv…
jmsbooth Oct 22, 2026
abe2762
test(FOSS-454): verify actual unpublished crate archive in isolated o…
jmsbooth Oct 22, 2026
5d128cc
test(FOSS-454): freeze clean-room consumer output and hostile archive…
jmsbooth Oct 22, 2026
bea4adf
test(FOSS-454): freeze clean-room consumer output and hostile archive…
jmsbooth Oct 22, 2026
bbf9e6d
docs(FOSS-454): correct public API behavior and package metadata
jmsbooth Oct 22, 2026
4a8d246
docs(FOSS-454): correct public API behavior and package metadata
jmsbooth Oct 22, 2026
1b35531
docs(FOSS-454): correct public API behavior and package metadata
jmsbooth Oct 22, 2026
4a59de2
docs(FOSS-454): complete public API, trust model and packaged clean-r…
jmsbooth Oct 22, 2026
34ba6c1
test(FOSS-454): tighten package checker imports, regex and toolchain …
jmsbooth Oct 22, 2026
618f005
ci(FOSS-454): gate actual packaged offline consumer on stable and MSRV
jmsbooth Oct 22, 2026
b7e072f
chore(FOSS-454): integrate E2 F1 F2 baseline with packaged clean-room…
jmsbooth Oct 22, 2026
7c951fc
docs(FOSS-454): align public developer adoption and five required gates
jmsbooth Oct 22, 2026
d85052f
docs(FOSS-454): align public developer adoption and five required gates
jmsbooth Oct 22, 2026
40bc3a5
docs(FOSS-454): correct all five required-check instructions after re…
jmsbooth Oct 22, 2026
6b4b53b
fix(FOSS-454): pin Cargo target dir and reject stale packaged archives
jmsbooth Oct 22, 2026
4d6b077
test(FOSS-454): expose and enforce controlled package target location
jmsbooth Oct 22, 2026
f9e51e3
test(FOSS-454): regression for injected Cargo target directory
jmsbooth Oct 22, 2026
ef2a010
fix(FOSS-454): import Path and tempfile for isolated Cargo target reg…
jmsbooth Oct 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ jobs:
grep -Fq "neutral delta claims: 1" <<< "$output"
grep -Fq "neutral policy gate: Unverified" <<< "$output"
grep -Fq "No authentication, negotiated peer proof, migration approval, or publishing occurred." <<< "$output"
- name: Detached packaged crate acceptance (no registry publish)
shell: bash
run: |
python3 -m unittest scripts.test_package_consumer_check -v
python3 scripts/package_consumer_check.py
- name: Documentation
env:
RUSTDOCFLAGS: -D warnings
Expand All @@ -121,6 +126,8 @@ jobs:
run: cargo +1.85.0 test --workspace --all-features --locked
- name: Independently build neutral fixture consumer on MSRV
run: cargo +1.85.0 run --frozen --manifest-path acceptance/neutral-consumer/Cargo.toml
- name: Packaged clean-room consumer on Rust 1.85
run: python3 scripts/package_consumer_check.py --toolchain 1.85.0

supply-chain:
name: Supply chain and SemVer
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ The [Gate E2 conformance corpus](docs/CONFORMANCE.md) exercises a versioned synt
The [FOSS-450 atomic analysis API](docs/ANALYSIS_RESULTS.md) composes existing offline phase contracts into one all-or-nothing advisory result with typed status diagnostics and opt-in aggregate-only metrics. It does not authenticate source claims or authorize migration.
Reproducible [phase scaling and benchmark methodology](docs/PERFORMANCE.md) is available for synthetic graph, SCC, risk, peer compatibility, remediation, advisory wave and plan workloads. The benchmark never approves cryptographic migrations and gates semantic identity rather than wall-clock performance.

## Developer adoption

The [Getting Started guide](docs/GETTING_STARTED.md) documents the v1 public API, full inventory-to-advisory-plan example and the isolated offline Cargo consumer that validates the actual unpublished `.crate` archive, including Rust 1.85. Plan outputs never confer migration authority. The package remains marked `publish = false`.

## Development

cargo fmt --all -- --check
Expand Down
2 changes: 1 addition & 1 deletion crates/cryptoshift/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ rust-version.workspace = true
license.workspace = true
repository.workspace = true
homepage.workspace = true
description = "cryptoshift library for the cryptoshift project."
description = "Offline evidence-bound cryptographic migration and post-quantum transition planning"
readme = "README.md"

# Publishing is prohibited until reviewed release work FOSS-456.
Expand Down
7 changes: 4 additions & 3 deletions crates/cryptoshift/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# cryptoshift

The `cryptoshift` crate is part of the Lattix open-source ecosystem.
The `cryptoshift` crate is part of the Lattix open-source ecosystem. Its public API is an offline, non-executing cryptographic migration planner.

This crate currently provides development-only Rust contracts for inventory,
immutable graphs, explainable risk, approved target and capability profiles,
Expand All @@ -10,8 +10,9 @@ with source-pinned residual risk and unverified exception claims, and independen
inventory/ChangeSet/policy-result fixture contracts.
It produces advisory migration plan drafts but does **not** authenticate external
cryptographic proofs, upstream native wire formats, exception approvals,
or authorize infrastructure changes. It remains unpublished; the first public
release requires separately approved release work (FOSS-456).
or authorize infrastructure changes. It remains unpublished with `publish = false`; the first public release requires separately approved release work (FOSS-456). Public `Complete` and `Warnings` outcomes are reserved and not emitted by the v1 runner while capability evidence is unverified.

The [API reference and getting started guide](https://github.com/LATTIX-IO/cryptoshift/blob/main/docs/GETTING_STARTED.md) describes the end-to-end example and separately packaged Cargo consumer. The example is read-only and never authorizes migration.

Repository: https://github.com/LATTIX-IO/cryptoshift

Expand Down
61 changes: 61 additions & 0 deletions crates/cryptoshift/examples/migration_plan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,67 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("blockers: {}", report.blockers().len());
println!("proposed actions: {}", report.actions().len());
println!("digest: {}", report.digest().as_identifier());
// The public all-or-nothing runner must preserve the manual plan's
// semantic identity and retain the same unverified state.
let atomic = AnalysisRunner::analyze(
&AnalysisRequest {
inventory: &inventory,
graph: &graph,
target: &target,
expected_inventory_digest: inventory.export(&limits)?.digest,
expected_graph_digest: graph.fingerprint(),
expected_target_digest: target.digest(),
compatibilities: &[],
capability_catalogs: &[],
quantum: &[],
context: &[],
scoring: None,
evaluated_at_unix_secs: at,
capacity_systems_per_wave: 1,
max_waves: 1,
submitted_for_review_units: &[],
exceptions: &[],
include_metrics: true,
},
&limits,
);
if atomic.outcome() != AnalysisOutcome::Partial
|| atomic.plan().map(MigrationPlanDraft::digest) != Some(plan.digest())
|| atomic.metrics().is_none()
{
return Err("atomic planning must match the manually pinned advisory plan".into());
}
// A forged upstream graph fingerprint cannot return a partial draft.
let rejected = AnalysisRunner::analyze(
&AnalysisRequest {
inventory: &inventory,
graph: &graph,
target: &target,
expected_inventory_digest: inventory.export(&limits)?.digest,
expected_graph_digest: SnapshotDigest::from_bytes([0; 32]),
expected_target_digest: target.digest(),
compatibilities: &[],
capability_catalogs: &[],
quantum: &[],
context: &[],
scoring: None,
evaluated_at_unix_secs: at,
capacity_systems_per_wave: 1,
max_waves: 1,
submitted_for_review_units: &[],
exceptions: &[],
include_metrics: true,
},
&limits,
);
if rejected.outcome() != AnalysisOutcome::Failed
|| rejected.plan().is_some()
|| rejected.metrics().is_some()
{
return Err("forged plan input pins must fail atomically".into());
}
println!("atomic analysis state: {:?}", atomic.outcome());
println!("forged graph pin: {:?}", rejected.outcome());
println!("This is not an authorization to execute, migrate, or approve changes.");
Ok(())
}
20 changes: 16 additions & 4 deletions crates/cryptoshift/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
//! Deterministic cryptographic-migration planning contracts.
//!
//! This early, unpublished library includes trust-boundary preflight plus a
//! validated, canonical binary inventory snapshot contract. Its snapshots retain
//! evidence and collection incompleteness; they are not authenticated observations.
//! This crate does not yet evaluate policies or generate migration plans.
//! This unpublished Rust library validates versioned inventory and evidence
//! graphs, analyzes dependency SCCs and cryptographic risk, models desired
//! post-quantum profiles and source-qualified vendor capabilities, and generates
//! immutable non-executing migration plans with explicit unresolved gates.
//!
//! [`AnalysisRunner`] composes topology, risk, remediation, advisory waves and a
//! source-pinned [`MigrationPlanDraft`] into an atomic result. Input digests bind
//! bytes and scope, but **do not authenticate** collectors, vendors, peers,
//! policy approvals, PKI, source claims or control-plane authority.
//! Unverified capability evidence remains `Partial` in v1. The public
//! `Complete` and `Warnings` enum cases are reserved for future trusted
//! evidence support and cannot currently be returned by the runner.
//!
//! For a complete tested example, run
//! `cargo run -p cryptoshift --example migration_plan --locked`. The same
//! example also runs outside this workspace against the *packaged* crate.
//!
//! # Example
//!
Expand Down
8 changes: 5 additions & 3 deletions docs/CI_VERIFICATION.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# CI verification architecture (FOSS-471)

The two checks named **Rust checks** and **Supply chain and SemVer** are both mandatory for PRs targeting `main` and for pushes to `main`. Configure branch rules to require BOTH distinct check names. A successful Rust check alone is not a merge authorization.
Five checks must independently succeed for complete protected-main release qualification: **Rust checks**, **Rust 1.85 MSRV**, **Supply chain and SemVer**, **Windows Rust stable conformance**, and **Windows Rust 1.85.0 conformance**. Every required status must be registered in the active main ruleset, with strict up-to-date policy. The current incomplete live ruleset is tracked as FOSS-509 and must be corrected before registry publication. A single green Rust check is never a complete release authorization.
Comment thread
jmsbooth marked this conversation as resolved.
Resolved

## Independent jobs

Expand All @@ -16,6 +16,8 @@ The cached `~/.cargo/bin` entries are checked by executing each tool's `--versio

The existing Rust workspace cache is separately scoped to its build job and is also saved only from `main`.

FOSS-454 adds source-package acceptance under stable and Rust 1.85. Its checker verifies the actual `.crate` archive and builds a synthetic developer example using a temporary clean-room Cargo project outside the workspace. It uses `--offline` and `--frozen`, checks a fixed semantic golden, and never publishes.

These are compilation caches, not independently signed binary supply-chain attestations. To increase assurance later, replace them with a provenance-attested binary distribution plus verified digest. Current safety relies on protected-main writers, exact tool-version checks and pinned installer inputs.

## Validate from repository root
Expand All @@ -33,12 +35,12 @@ cargo deny check
cargo semver-checks check-release --workspace --all-features
```

Expected: all exit zero; two CI jobs succeed. Negative regressions must fail if either job/mandatory step is disabled, made nonfatal, or replaced with an echo command; weakening the publication guard or allowing PR cache writes must also fail.
Expected: all exit zero; all five independent CI check contexts succeed on the exact head, including Rust 1.85 and the Windows stable/1.85 matrix. Negative regressions must fail if either job/mandatory step is disabled, made nonfatal, or replaced with an echo command; weakening the publication guard or allowing PR cache writes must also fail.

## Observability and acceptance

Baseline single-job Rust CI on `main`: [run #38969570693](https://github.com/LATTIX-IO/cryptoshift/actions/runs/38969570693). Final exact-head prior release: [run #38970105468](https://github.com/LATTIX-IO/cryptoshift/actions/runs/38970105468). These installed cargo tools serially on every clean runner and delayed audit execution.

Record both **cold** (empty cache) and **warm** (`main` cache available) job start/end times from GitHub's job page after this PR runs. There is no benchmark claim until both have actually executed. Fail closed if cache unavailable; do not make elapsed time a release gate.

**Administration**: GitHub branch rules are not configured by this PR. Require `Rust checks` and `Supply chain and SemVer` in repo settings, and keep review-thread resolution, signed commits and protected `main` where available.
**Administration**: GitHub branch rules are not configured by this PR. Require all five exact contexts: `Rust checks`, `Rust 1.85 MSRV`, `Supply chain and SemVer`, `Windows Rust stable conformance`, and `Windows Rust 1.85.0 conformance`. Keep strict checks, review-thread resolution, signed commits, linear history and protected `main`. FOSS-509 tracks the necessary administrator change.
69 changes: 69 additions & 0 deletions docs/GETTING_STARTED.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Cryptoshift v1: Developer Guide

Cryptoshift is an offline, evidence-bound Rust library for **advisory** cryptographic migration planning. Its planned post-quantum transition stages are deterministic and source-pinned. It does not scan your environment, encrypt data, authenticate vendors or operators, modify workloads, publish packages, or grant permission to migrate.

## Build and Inspect

The package is currently unpublished and the Cargo manifest deliberately contains `publish = false`. From a clean Git checkout with Rust 1.85 or newer:

```sh
cargo fmt --all -- --check
cargo check --workspace --all-targets --all-features --locked
cargo clippy --workspace --all-targets --all-features --locked -- -D warnings
cargo test --workspace --all-features --locked
RUSTDOCFLAGS="-D warnings" cargo doc --workspace --all-features --no-deps --locked
cargo run -p cryptoshift --example migration_plan --locked
```

The example constructs one synthetic inventory snapshot, a directed evidence graph, and a scoped target, then computes SCC topology, cryptographic risk, remediation blockers, nonauthorizing waves, and an immutable plan. It runs the same fixture through `AnalysisRunner::analyze` and requires the atomic plan digest to equal the manually composed plan digest. It also checks a forged graph source pin is rejected **without a partial plan**.

Expected behavioral lines include:

```text
migration plan state: Partial
readiness: Unverified
atomic analysis state: Partial
forged graph pin: Failed
This is not an authorization to execute, migrate, or approve changes.
```

Do not interpret `Partial` as a failed test: it correctly records missing owner/capability evidence and authority. `Complete`, `Warnings`, and the associated external-review classification remain reserved in v1 because this library cannot independently authenticate those facts. Those states must not be synthesized from unverified claims.

## Public API Boundaries

| Stage | Entry point | Contract |
|---|---|---|
| Source admission | `ValidatedInventorySnapshot`, `NeutralInventoryAdapter` | Scoped, bounded, versioned source facts; not collector authentication |
| Graph | `EvidenceGraph` | Typed, evidence-bound edges, canonical fingerprint |
| Dependencies | `DependencyAnalysis::analyze` | Iterative SCCs and prerequisite-first order |
| Risk | `RiskAnalysis::analyze` | Evidence-qualified factor vector, not an authorization score |
| Desired state | `TargetProfile`, `CapabilityCatalog` | Explicit algorithm/protocol constraints and untrusted vendor source attributes |
| Peer assessment | `CompatibilityAnalyzer::analyze` | Hostile negotiation, PKI and downgrade checks, never authoritative interoperability |
| Remediation | `RemediationAnalyzer` | Blocker and prerequisite-linked review actions; no execution |
| Waves | `WavePlanner` | Bounded, prerequisite-preserving advisory waves |
| Plan | `MigrationPlanner` | Digest-bound immutable plan, residual risk and claimed exception records |
| Atomic facade | `AnalysisRunner::analyze` | One complete advisory draft or one typed failure with no partial artifact |

All public schema/version constants are exported from `cryptoshift::`. Use the version constants and explicit `Limits` rather than guessing wire formats. Source-content SHA-256 fingerprints detect changes but are **not signatures** or identity attestations. A caller must obtain expected digests from an independently trusted channel. All sample timestamps are explicit synthetic UTC Unix seconds. An expired profile or cross-tenant/stale source must not be silently accepted.

The neutral handoff adapters currently use Cryptoshift-owned fixture structures; real Cryptomap and Cryptopolicy native interoperability is outside this release's verified acceptance. FOSS-513 tracks a separate trusted-evidence capability for any eventual actionable Complete/Warnings outcome.

## Clean-Room Package Adoption

A repo-relative Rust path dependency does not verify that a downstream developer can use the actual crates.io-shaped archive. FOSS-454 includes `scripts/package_consumer_check.py` to exercise the archive itself.

```sh
python3 -m unittest scripts.test_package_consumer_check -v
python3 scripts/package_consumer_check.py
python3 scripts/package_consumer_check.py --toolchain 1.85.0
```

The script performs `cargo package --offline --locked` without publishing, checks package identity and declared MSRV, validates bounded extraction paths and archive types, creates an **isolated temporary Cargo project outside this repository**, and compiles the existing inventory-to-plan example against the unpacked crate. It generates a detached consumer lockfile offline, executes with `--frozen` twice, checks exact output determinism, and compares the key behavior against `tests/acceptance/packaged-consumer.golden`. The acceptance script prints the SHA-256 of the package archive and consumer output as traceability data. The temporary project is removed when validation finishes.

The consumer depends on the *unpacked archive*, not the workspace, and uses no crates.io registry publishing token. Cargo's offline flag makes missing cached dependencies a reproducible setup error rather than an implicit network operation. The package remains marked `publish = false` throughout this acceptance process.

## Verification Limits

The suite covers Linux stable, Linux Rust 1.85, Windows stable and Windows Rust 1.85 via CI. The Windows acceptance also replays versioned E2 source/enterprise conformance and checks the detached neutral consumer. FOSS-453 provides performance smoke and frozen semantic identities, not execution authorization or timing-based CI thresholds.

Before any public crate release, the owner must separately approve the release version, package ownership, branch protections, verified reproducible artifacts, dependency/security report, SBOM and provenance, and an explicit restricted publishing operation (FOSS-456). Nothing in this guide authorizes publication.
Loading
Loading