Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
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: 6 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ Materialized graphs are optional readings.
Continuum is the protocol for lawful causal-history exchange.
```

## Trace Architecture Principle

> Graph is truth. Delta log is transport. Roaring is index. Matrix is projection. Receipt is proof.

Echo execution traces are not a separate event-sourcing reality. They are a bounded, append-only, canonical streaming log of WSC `NodeRow`, `EdgeRow`, and `AttRow` deltas. Trace storage is chunked. Sparse selector columns may be encoded as compressed bitsets, but they are derived indexes, not the source of truth. Prover-specific rectangular traces are downstream projections of the delta log.

## Git Rules

- **NEVER** amend commits.
Expand Down
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@

### Added

- `warp-core` now exposes a recovered WAL evidence segment catalog derived from
`RecoveryScanReport`, with a non-authoritative live cache in
`TrustedRuntimeWal` that marks cache-update failures as rebuild posture
without turning committed WAL transactions into failures.

- `warp-core` now exposes a narrow Edict `echo.span-ir/v1` Target IR fixture
bridge that accepts strict lowercase digest-locked pre-step
`continueObstructed` requirements, evaluates deterministic basis freshness
Expand Down Expand Up @@ -847,6 +852,14 @@ Applied, Rejected, Obstructed}` with receipt evidence and typed contract

### Fixed

- `warp-core` recovered filesystem WAL ACK paths now rebuild the live evidence
catalog before returning recovered success, live catalog-update failures record
the last commit where the catalog was actually fresh, and committed evidence
segments now populate `coverings_by_range` for their exact LSN range. Rebuilt
evidence catalogs now reject malformed commit/frame evidence before admitting
`ExactCommittedWal` segments.
- `Cargo.lock` now pins `crossbeam-epoch` to `0.9.20`, clearing
`RUSTSEC-2026-0204` for the benchmark-only `rayon` dependency path.
- `warp-core` evolving braid logs now reject unchecked incremental mutations:
`Braid::apply` returns typed lifecycle errors, rejects duplicate member
weaving and mixed revealed/sealed membership, refuses empty-frontier
Expand Down
8 changes: 6 additions & 2 deletions Cargo.lock

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

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ members = [
"crates/ttd-protocol-rs",
"crates/echo-ttd",
"crates/method",
"xtask"
"xtask",
"crates/echo-trace",
]
resolver = "2"

Expand Down
18 changes: 18 additions & 0 deletions crates/echo-trace/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# SPDX-License-Identifier: Apache-2.0
# © James Ross Ω FLYING•ROBOTS <https://github.com/flyingrobots>
[package]
Comment thread
flyingrobots marked this conversation as resolved.
name = "echo-trace"
version = "0.1.0"
edition = "2024"
license.workspace = true
repository.workspace = true
rust-version.workspace = true
Comment thread
flyingrobots marked this conversation as resolved.
description = "Canonical causal trace boundary for Echo graph delta streams"
readme = "README.md"
keywords = ["echo", "trace", "causal", "graph"]
categories = ["data-structures", "development-tools"]

[dependencies]

[lints]
workspace = true
Comment thread
flyingrobots marked this conversation as resolved.
11 changes: 11 additions & 0 deletions crates/echo-trace/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!-- SPDX-License-Identifier: Apache-2.0 OR LicenseRef-MIND-UCAL-1.0 -->
<!-- © James Ross Ω FLYING•ROBOTS <https://github.com/flyingrobots> -->

# echo-trace

Canonical causal trace boundary for Echo graph delta streams.

`echo-trace` defines the small trait and data shapes used by trace sinks that
consume ordered graph deltas, seal deterministic chunks, and return receipts.
The crate is intentionally transport-neutral: it names the boundary between a
causal producer and a trace sink without owning storage, replay, or rendering.
117 changes: 117 additions & 0 deletions crates/echo-trace/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// SPDX-License-Identifier: Apache-2.0
// © James Ross Ω FLYING•ROBOTS <https://github.com/flyingrobots>

//! Echo Trace
//!
//! Graph is truth. Delta log is transport. Roaring is index.
//! Matrix is projection. Receipt is proof.
//!
//! This crate defines the canonical causal delta stream boundary.

/// Represents an execution tick identifier.
pub type TickId = u64;

/// A digest representing a causal frontier in the WARP graph.
pub type FrontierDigest = [u8; 32];

/// The core graph delta, encapsulating the exact WSC rows appended in a tick.
/// Parameterized over the row types to avoid circular dependencies with `warp-core`.
pub struct CanonicalGraphDelta<'a, N, E, A> {
/// The tick at which this delta occurred.
pub tick: TickId,
/// The causal frontier digest before this delta.
pub causal_frontier_before: FrontierDigest,
/// The canonical NodeRows appended.
pub node_rows: &'a [N],
/// The canonical EdgeRows appended.
pub edge_rows: &'a [E],
/// The canonical AttRows appended.
pub att_rows: &'a [A],
/// The causal frontier digest after this delta.
pub causal_frontier_after: FrontierDigest,
}

/// Metadata describing an execution trace run.
pub struct TraceRunMeta {
/// The starting tick of the execution trace run.
pub start_tick: TickId,
/// The root causal frontier digest.
pub root_frontier: FrontierDigest,
}

/// A receipt for a sealed trace chunk.
pub struct TraceChunkReceipt {
/// The starting tick of this chunk.
pub start_tick: TickId,
/// The total number of ticks contained in this chunk.
pub tick_count: u64,
/// The cryptographic hash of the prior chunk.
pub prior_chunk_hash: [u8; 32],
/// The cryptographic hash of the current chunk.
pub chunk_hash: [u8; 32],
}

/// A receipt for a completed trace run.
pub struct TraceRunReceipt {
/// The total number of chunks generated in the run.
pub chunks: usize,
/// The final cryptographic hash representing the entire trace run.
pub final_hash: [u8; 32],
}

/// A generic error type for trace operations.
#[derive(Debug)]
pub enum TraceError {
/// An I/O error occurred while writing or reading the trace sink.
IoError,
/// The trace chunk could not be sealed.
SealError,
/// A causal boundary violation occurred.
BoundaryMismatch,
}

/// The trace boundary trait.
///
/// Consumes canonical graph deltas, bounded in chunked streams.
pub trait TraceSink<N, E, A> {
/// Start a new trace run.
fn begin_run(&mut self, meta: &TraceRunMeta) -> Result<(), TraceError>;

/// Append a canonical graph delta to the stream.
fn append_delta(&mut self, delta: &CanonicalGraphDelta<'_, N, E, A>) -> Result<(), TraceError>;

/// Seal the current chunk and return its cryptographic receipt.
fn seal_chunk(&mut self) -> Result<TraceChunkReceipt, TraceError>;

/// Finish the entire trace run and return the final receipt.
fn finish_run(&mut self) -> Result<TraceRunReceipt, TraceError>;
}

/// A baseline sink that incurs near-zero overhead and does nothing.
pub struct NullTraceSink;

impl<N, E, A> TraceSink<N, E, A> for NullTraceSink {
fn begin_run(&mut self, _meta: &TraceRunMeta) -> Result<(), TraceError> {
Ok(())
}
fn append_delta(
&mut self,
_delta: &CanonicalGraphDelta<'_, N, E, A>,
) -> Result<(), TraceError> {
Ok(())
}
fn seal_chunk(&mut self) -> Result<TraceChunkReceipt, TraceError> {
Ok(TraceChunkReceipt {
start_tick: 0,
tick_count: 0,
prior_chunk_hash: [0; 32],
chunk_hash: [0; 32],
})
}
fn finish_run(&mut self) -> Result<TraceRunReceipt, TraceError> {
Ok(TraceRunReceipt {
chunks: 0,
final_hash: [0; 32],
})
}
}
30 changes: 30 additions & 0 deletions crates/warp-core/src/causal_wal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -850,6 +850,14 @@ impl WalTransactionCommit {
self.compute_digest()
}

pub(crate) fn validate_frame_evidence(
&self,
frames: &[WalFrame],
) -> Result<(), WalValidationError> {
validate_transaction_frames(frames, self)?;
validate_transaction_semantics(frames, self.transaction_kind)
}

fn compute_digest(&self) -> Hash {
let mut h = blake3::Hasher::new();
h.update(WAL_COMMIT_DOMAIN);
Expand Down Expand Up @@ -4300,6 +4308,8 @@ pub enum FilesystemWalFaultTarget {
AppendFrame,
/// Fail the next commit flush before writing the commit marker.
FlushCommit,
/// Fail after writing and syncing the next commit marker.
CommitMarkerSynced,
/// Fail the next manifest publish before writing manifest material.
PublishManifest,
}
Expand All @@ -4310,6 +4320,7 @@ pub enum FilesystemWalFaultTarget {
pub struct FilesystemWalFaultPlan {
append_frame: u32,
flush_commit: u32,
commit_marker_synced: u32,
publish_manifest: u32,
}

Expand All @@ -4322,16 +4333,25 @@ impl FilesystemWalFaultPlan {
FilesystemWalFaultTarget::AppendFrame => Self {
append_frame: 1,
flush_commit: 0,
commit_marker_synced: 0,
publish_manifest: 0,
},
FilesystemWalFaultTarget::FlushCommit => Self {
append_frame: 0,
flush_commit: 1,
commit_marker_synced: 0,
publish_manifest: 0,
},
FilesystemWalFaultTarget::CommitMarkerSynced => Self {
append_frame: 0,
flush_commit: 0,
commit_marker_synced: 1,
publish_manifest: 0,
},
FilesystemWalFaultTarget::PublishManifest => Self {
append_frame: 0,
flush_commit: 0,
commit_marker_synced: 0,
publish_manifest: 1,
},
}
Expand All @@ -4341,6 +4361,7 @@ impl FilesystemWalFaultPlan {
let remaining = match target {
FilesystemWalFaultTarget::AppendFrame => &mut self.append_frame,
FilesystemWalFaultTarget::FlushCommit => &mut self.flush_commit,
FilesystemWalFaultTarget::CommitMarkerSynced => &mut self.commit_marker_synced,
FilesystemWalFaultTarget::PublishManifest => &mut self.publish_manifest,
};
if *remaining == 0 {
Expand Down Expand Up @@ -4590,6 +4611,15 @@ impl WalStorePort for FilesystemWalStore {
FilesystemSyncBoundary::CommitFileSynced,
transaction_id,
));
#[cfg(any(test, feature = "host_test"))]
if self
.fault_plan
.should_fail(FilesystemWalFaultTarget::CommitMarkerSynced)
{
return Err(WalStoreError::Io(
"injected filesystem WAL commit_marker_synced failure".to_owned(),
));
}
Ok(())
}

Expand Down
Loading
Loading