Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 5 additions & 1 deletion .github/workflows/formal-verification.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,11 @@ jobs:
# the scope of bounded model checking entirely.
tolerate_failure: true
- module: dsse
pkg: wsc
# The DSSE `compute_pae` proofs live in `wsc-dsse` after the carve
# (issue #218 / REQ-24), so the harness must be invoked against that
# crate — invoking `-p wsc` would match zero harnesses and the gate
# would report green without running anything.
pkg: wsc-dsse
harness: dsse
# WIP — CI observation post-rebase: dsse harnesses also hit
# "unwinding assertion loop 0" at --default-unwind 4. The
Expand Down
7 changes: 5 additions & 2 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -295,9 +295,12 @@ jobs:
with:
tool: cargo-llvm-cov
- name: Generate coverage (LCOV + HTML)
# Include wsc-dsse: the DSSE code was carved out of wsc into its own crate
# (#218), so `-p wsc` alone no longer sees it and its moved tests wouldn't
# count — codecov would report the moved lines as uncovered.
run: |
cargo llvm-cov -p wsc --lcov --output-path lcov.info
cargo llvm-cov -p wsc --html --output-dir coverage-html
cargo llvm-cov -p wsc -p wsc-dsse --lcov --output-path lcov.info
cargo llvm-cov -p wsc -p wsc-dsse --html --output-dir coverage-html
- name: Upload LCOV to Codecov
if: env.CODECOV_TOKEN != ''
uses: codecov/codecov-action@v7
Expand Down
11 changes: 11 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ members = [
"src/attestation",
"src/cli",
"src/component",
"src/dsse",
"src/lib",
"src/verify-core",
]
Expand Down
14 changes: 14 additions & 0 deletions artifacts/dev/features.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -719,3 +719,17 @@ artifacts:
created-by: ai-assisted
model: claude-opus-4-8
timestamp: 2026-08-08T06:00:07Z

- id: DD-13
type: design-decision
title: DSSE extracted to a new no_std wsc-dsse crate, not into wsc-verify-core
status: draft
description: "wsc::dsse moves to a new wsc-dsse crate (base64/serde/serde_json/ed25519-compact, no_std+alloc) rather than into wsc-verify-core. Reason: verify-core is the witness-MC/DC-instrumented crate whose gaps are REQ-25 — adding 600 lines of DSSE + serde_json there would add decisions to the exact crate we're closing gaps in, self-interfering within v0.11.0. wsc re-exports wsc-dsse as wsc::dsse with From<DsseError> for WSError so internal consumers (composition/mod.rs) and the public API keep working."
tags: [dsse, no-std, crate-topology]
fields:
rationale: "Single-responsibility crate gives embedded/offline consumers (varve, #187 Cortex-M) minimal-dep DSSE without verify-core's wasm-parsing or perturbing its MC/DC gate; no_std+alloc from the start avoids a std-only rewrite for the on-target verifier."
release: v0.11.0
provenance:
created-by: ai-assisted
model: claude-opus-4-8
timestamp: 2026-08-08T15:04:57Z
6 changes: 5 additions & 1 deletion scripts/publish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use std::time::Duration;
// wsc-verify-core and wsc-attestation MUST precede wsc (wsc depends on both);
// wsc-cli depends on wsc. wsc-component/wsc-crypto are not deps of any published
// crate, so they are intentionally not published.
const CRATES_TO_PUBLISH: &[&str] = &["wsc-verify-core", "wsc-attestation", "wsc", "wsc-cli"];
const CRATES_TO_PUBLISH: &[&str] = &["wsc-verify-core", "wsc-attestation", "wsc-dsse", "wsc", "wsc-cli"];

struct Workspace {
version: String,
Expand Down Expand Up @@ -55,6 +55,10 @@ fn main() {
let attestation_crate = read_crate(Some(&ws), "./src/attestation/Cargo.toml".as_ref());
crates.push(attestation_crate);

// Add DSSE crate (leaf: wsc depends on it; must precede wsc)
let dsse_crate = read_crate(Some(&ws), "./src/dsse/Cargo.toml".as_ref());
crates.push(dsse_crate);

// Add main library crate
let lib_crate = read_crate(Some(&ws), "./src/lib/Cargo.toml".as_ref());
crates.push(lib_crate);
Expand Down
26 changes: 26 additions & 0 deletions src/dsse/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"""DSSE (Dead Simple Signing Envelope) sign/verify for wsc.

Carved out of `//src/lib:wsc` (issue #218 / REQ-24) as a `no_std` + `alloc`
crate so embedded/offline consumers can verify DSSE envelopes with only
base64/serde/serde_json/ed25519-compact — no registry, TLS or X.509. `wsc`
re-exports its public API as `wsc::dsse` for backwards compatibility.
"""

load("@rules_rust//rust:defs.bzl", "rust_library")

package(default_visibility = ["//visibility:public"])

rust_library(
name = "wsc-dsse",
srcs = glob(["src/**/*.rs"]),
crate_name = "wsc_dsse",
edition = "2024",
deps = [
"@wsc_deps//:base64",
"@wsc_deps//:ed25519-compact",
"@wsc_deps//:serde",
"@wsc_deps//:serde_json",
],
)

exports_files(["Cargo.toml"])
18 changes: 18 additions & 0 deletions src/dsse/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "wsc-dsse"
version.workspace = true
edition.workspace = true
authors.workspace = true
license.workspace = true
repository.workspace = true
description = "DSSE (Dead Simple Signing Envelope) sign/verify for wsc: a lightweight no_std + alloc crate so embedded/offline consumers can verify DSSE envelopes with just base64/serde/serde_json/ed25519-compact — no registry, TLS or X.509. Carved out of the wsc crate."
readme = "../../README.md"
keywords = ["dsse", "signatures", "attestation", "no-std"]
homepage = "https://github.com/pulseengine/sigil"
categories = ["cryptography", "no-std"]

[dependencies]
serde = { version = "1.0", default-features = false, features = ["alloc", "derive"] }
serde_json = { version = "1.0", default-features = false, features = ["alloc"] }
base64 = { version = "0.22", default-features = false, features = ["alloc"] }
ed25519-compact = { version = "2.3", default-features = false }
Loading
Loading