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
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ All notable changes to OriginWeave are documented in this file. The format follo
- Credential-free TLS evidence containing canonical origin, requested and observed peer, DNS/IP 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