Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ All notable changes to OriginWeave are documented in this file. The format follo
- Credential-free TLS evidence containing canonical origin, TCP peers, reference identity, TLS version, cipher-suite identifier, selected ALPN or explicit absence, leaf certificate and SPKI hashes, server-presented certificate hashes and bounds, trust-bundle identity and hash, validity interval, fixed verification time, revocation configuration, and measured handshake duration.
- Credential-free connection and redirect evidence containing canonical addresses, destination classes, target digests, hop numbers, and approved-address counts.
- Credential-free verified TCP evidence containing the logical origin, requested socket, observed peer, destination class, successful attempt number, and per-attempt timeout.
- Standard `Display` and `std::error::Error` contracts for destination, redirect, digest, direct-network, and TLS failures, including preserved destination-policy, rustls, and operating-system sources where applicable.
- Standard `Display` and `std::error::Error` contracts for destination, redirect, digest, direct-network, TLS, and resource-budget failures, including preserved destination-policy, rustls, and operating-system sources where applicable.
- Real loopback TCP integration proof plus deterministic timeout, refusal, retry, peer-inspection, peer-mismatch, canonicalization, IPv6 metadata, and single-use replay tests.
- Real loopback rustls integration covering trusted DNS SAN, Common-Name fallback rejection, wrong-name and untrusted-root rejection, fixed-time expiry and not-yet-valid failures, exact IPv4 and IPv6 SANs, TLS 1.2/TLS 1.3, required and optional ALPN, and transport-origin binding.
- Cumulative interactive-first RAM, VRAM, batch, local-model, admission, pause, and compositor-pressure mitigation plans, including active-consumer reduction at exact hard limits.
Expand Down
15 changes: 15 additions & 0 deletions crates/originweave-resource/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#![forbid(unsafe_code)]
#![deny(missing_docs)]

use std::fmt;

/// A validation error in a resource budget.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BudgetError {
Expand All @@ -18,6 +20,19 @@ pub enum BudgetError {
SoftExceedsHard,
}

impl fmt::Display for BudgetError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::ZeroLimit => formatter.write_str("resource budget limits must be nonzero"),
Self::SoftExceedsHard => {
formatter.write_str("resource budget soft limits must not exceed hard limits")
}
}
}
}

impl std::error::Error for BudgetError {}

/// Validated resource limits for one agent task.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ResourceBudget {
Expand Down
21 changes: 21 additions & 0 deletions crates/originweave-resource/tests/error_contract.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use originweave_resource::BudgetError;
use std::error::Error as _;

#[test]
fn budget_errors_expose_stable_standard_error_contract() {
let cases = [
(
BudgetError::ZeroLimit,
"resource budget limits must be nonzero",
),
(
BudgetError::SoftExceedsHard,
"resource budget soft limits must not exceed hard limits",
),
];

for (error, expected_message) in cases {
assert_eq!(error.to_string(), expected_message);
assert!(error.source().is_none());
}
}
Loading