From e4598bc7bc58e1655ab5f7afad025849505fa706 Mon Sep 17 00:00:00 2001 From: Bruce Mitchener Date: Sun, 31 May 2026 15:32:33 +0700 Subject: [PATCH] docs: prepare execution crates for release Expand the workspace and crate READMEs for execution_tape and execution_graph with current usage examples, release checks, MSRV notes, and package roles. Add Understory-style changelogs for both publishable crates and include execution_graph in the CI MSRV package set so release checks cover both crates. --- .github/workflows/ci.yml | 1 + README.md | 26 +++++++--- execution_graph/CHANGELOG.md | 26 ++++++++++ execution_graph/README.md | 71 ++++++++++++++++++++++++++ execution_graph/src/lib.rs | 56 +++++++++++++++++++++ execution_tape/CHANGELOG.md | 26 ++++++++++ execution_tape/README.md | 96 ++++++++++++++++++++++++++++++++++-- 7 files changed, 293 insertions(+), 9 deletions(-) create mode 100644 execution_graph/CHANGELOG.md create mode 100644 execution_tape/CHANGELOG.md diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 809fda6..69927f0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,6 +13,7 @@ env: # This should be limited to packages that are intended for publishing. RUST_MIN_VER_PKGS: >- -p execution_tape + -p execution_graph # List of packages that don't support `no_std`. RUST_STD_ONLY_PKGS: >- --exclude execution_graph_examples diff --git a/README.md b/README.md index 9c7930c..05d7b6b 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,25 @@ # `forest-rs/execution` -Workspace repository for the `execution_tape` bytecode container + VM and related crates. +Workspace repository for `execution_tape`, a small verifiable bytecode container and VM, and +`execution_graph`, an incremental execution graph built on top of it. Crates: -- `execution_tape/`: core `no_std + alloc` crate (format, verifier, VM, tracing hooks) -- `execution_tape_conformance/`: conformance/regression tests -- `execution_tape_wind_tunnel/`: benchmarks (Criterion) +- `execution_tape/`: publishable `no_std + alloc` crate for the bytecode format, verifier, VM, + tracing hooks, host ABI, and disassembler. +- `execution_graph/`: publishable `no_std + alloc` crate for dirty-tracked incremental execution + of verified tape programs. +- `execution_graph_examples/`: runnable graph examples, including the `tax` demo. +- `execution_tape_conformance/`: conformance/regression tests for the tape format, verifier, and VM. +- `execution_tape_profiling/`: optional profiling adapters; kept separate from the core crate. +- `execution_tape_wind_tunnel/` and `execution_graph_wind_tunnel/`: Criterion benchmarks. Docs: -- `docs/overview.md` -- `docs/v1_spec.md` +- `docs/overview.md`: design notes for the tape VM and host boundary. +- `docs/v1_spec.md`: current v1 bytecode/container draft. +- `execution_tape/README.md`: crate overview and quick start. +- `execution_graph/README.md`: graph model, dependency keys, and demo. + +The workspace MSRV is Rust 1.88. Tickets: - Tickets live in `.tickets/` at the repo root. @@ -20,5 +30,9 @@ Suggested checks: cargo fmt --all cargo clippy --workspace --all-targets --all-features -- -D warnings cargo test --workspace --all-features +cargo test --doc --workspace --all-features +cargo package -p execution_tape +cargo package -p execution_graph cargo bench -p execution_tape_wind_tunnel +cargo bench -p execution_graph_wind_tunnel ``` diff --git a/execution_graph/CHANGELOG.md b/execution_graph/CHANGELOG.md new file mode 100644 index 0000000..cd1850d --- /dev/null +++ b/execution_graph/CHANGELOG.md @@ -0,0 +1,26 @@ + + +# Changelog + +The latest published Execution Graph release is [0.0.1](#001-2026-05-31) which was released on 2026-05-31. +You can find its changes [documented below](#001-2026-05-31). + +## [Unreleased] + +## [0.0.1][] (2026-05-31) + +This release has an [MSRV][] of 1.88. + +This is the initial release of Execution Graph, a `no_std` incremental execution graph for +dirty-tracked re-execution of verified `execution_tape` programs. + +[Unreleased]: https://github.com/forest-rs/execution/compare/execution_graph-v0.0.1...HEAD +[0.0.1]: https://github.com/forest-rs/execution/releases/tag/execution_graph-v0.0.1 + +[MSRV]: README.md#minimum-supported-rust-version-msrv diff --git a/execution_graph/README.md b/execution_graph/README.md index 47bafa7..9847098 100644 --- a/execution_graph/README.md +++ b/execution_graph/README.md @@ -5,6 +5,63 @@ Incremental execution graph built on `execution_tape`. This crate provides a small `no_std` graph that executes verified `execution_tape` programs as nodes and re-executes only the nodes that are affected by changes. +## Quick Start + +Use `execution_tape` to build verified programs, then wire them as graph nodes: + +```rust +use std::sync::Arc; + +use execution_graph::ExecutionGraph; +use execution_tape::asm::{Asm, FunctionSig, ProgramBuilder}; +use execution_tape::host::{Host, HostContext, HostError, SigHash, ValueRef}; +use execution_tape::program::ValueType; +use execution_tape::value::Value; +use execution_tape::vm::Limits; + +struct NoHost; + +impl Host for NoHost { + fn call( + &mut self, + _symbol: &str, + _sig_hash: SigHash, + _args: &[ValueRef<'_>], + _rets: &mut [Value], + _ctx: HostContext<'_, '_>, + ) -> Result { + Err(HostError::UnknownSymbol) + } +} + +fn main() -> Result<(), Box> { + let mut asm = Asm::new(); + asm.const_i64(2, 1); + asm.i64_add(3, 1, 2); + asm.ret(0, &[3]); + + let mut builder = ProgramBuilder::new(); + let entry = builder.push_function_checked( + asm, + FunctionSig { + arg_types: vec![ValueType::I64], + ret_types: vec![ValueType::I64], + }, + )?; + builder.set_function_output_name(entry, 0, "y")?; + let program = Arc::new(builder.build_verified()?); + + let mut graph = ExecutionGraph::new(NoHost, Limits::default()); + let node = graph.add_node(program, entry, vec!["x".into()]); + graph.set_input_value(node, "x", Value::I64(41)); + + let summary = graph.run_all()?; + assert_eq!(summary.executed_nodes, 1); + assert_eq!(graph.node_outputs(node).unwrap().get("y"), Some(&Value::I64(42))); + Ok(()) +} +``` + ## Model - **Nodes** are `(VerifiedProgram, entry FuncId)` pairs. @@ -48,7 +105,21 @@ Run the demo with: cargo run -p execution_graph_examples --bin tax ``` +Emit Graphviz DOT for the same graph: + +```sh +cargo run -p execution_graph_examples --bin tax -- --dot +``` + ## Current limitations - `execution_graph` intentionally stays close to the VM: traps expose `execution_tape::vm::TrapInfo` rather than source-language diagnostics. +- VM traps are still collapsed to `GraphError::Trap` at the graph boundary. Missing inputs, + missing upstream outputs, bad output arity, and strict-deps failures are reported with context. +- Graph nodes are currently `execution_tape` entrypoints only; custom dispatch can be layered later + without changing the resource-key model. + +## Minimum supported Rust Version (MSRV) + +This crate has been verified to compile with **Rust 1.88** and later. diff --git a/execution_graph/src/lib.rs b/execution_graph/src/lib.rs index 424ff8c..5dd36c5 100644 --- a/execution_graph/src/lib.rs +++ b/execution_graph/src/lib.rs @@ -13,6 +13,62 @@ //! used consistently: the name passed to [`ExecutionGraph::set_input_value`] must match the name //! passed to [`ExecutionGraph::invalidate_input`] (otherwise the invalidation will not affect the //! reads recorded by runs). +//! +//! ## Example +//! +//! ``` +//! use std::sync::Arc; +//! +//! use execution_graph::ExecutionGraph; +//! use execution_tape::asm::{Asm, FunctionSig, ProgramBuilder}; +//! use execution_tape::host::{Host, HostContext, HostError, SigHash, ValueRef}; +//! use execution_tape::program::ValueType; +//! use execution_tape::value::Value; +//! use execution_tape::vm::Limits; +//! +//! struct NoHost; +//! +//! impl Host for NoHost { +//! fn call( +//! &mut self, +//! _symbol: &str, +//! _sig_hash: SigHash, +//! _args: &[ValueRef<'_>], +//! _rets: &mut [Value], +//! _ctx: HostContext<'_, '_>, +//! ) -> Result { +//! Err(HostError::UnknownSymbol) +//! } +//! } +//! +//! let mut asm = Asm::new(); +//! asm.const_i64(2, 1); +//! asm.i64_add(3, 1, 2); +//! asm.ret(0, &[3]); +//! +//! let mut builder = ProgramBuilder::new(); +//! let entry = builder.push_function_checked( +//! asm, +//! FunctionSig { +//! arg_types: vec![ValueType::I64], +//! ret_types: vec![ValueType::I64], +//! }, +//! )?; +//! builder.set_function_output_name(entry, 0, "y")?; +//! let program = Arc::new(builder.build_verified()?); +//! +//! let mut graph = ExecutionGraph::new(NoHost, Limits::default()); +//! let node = graph.add_node(program, entry, vec!["x".into()])?; +//! graph.set_input_value(node, "x", Value::I64(41))?; +//! +//! let summary = graph.run_all()?; +//! assert_eq!(summary.executed_nodes, 1); +//! assert_eq!( +//! graph.node_outputs(node).unwrap().get("y"), +//! Some(&Value::I64(42)) +//! ); +//! # Ok::<(), Box>(()) +//! ``` #![no_std] diff --git a/execution_tape/CHANGELOG.md b/execution_tape/CHANGELOG.md new file mode 100644 index 0000000..63f67cf --- /dev/null +++ b/execution_tape/CHANGELOG.md @@ -0,0 +1,26 @@ + + +# Changelog + +The latest published Execution Tape release is [0.0.1](#001-2026-05-31) which was released on 2026-05-31. +You can find its changes [documented below](#001-2026-05-31). + +## [Unreleased] + +## [0.0.1][] (2026-05-31) + +This release has an [MSRV][] of 1.88. + +This is the initial release of Execution Tape, a `no_std` bytecode container, verifier, register VM +runtime, host-call ABI, tracing API, and disassembler. + +[Unreleased]: https://github.com/forest-rs/execution/compare/execution_tape-v0.0.1...HEAD +[0.0.1]: https://github.com/forest-rs/execution/releases/tag/execution_tape-v0.0.1 + +[MSRV]: README.md#minimum-supported-rust-version-msrv diff --git a/execution_tape/README.md b/execution_tape/README.md index 007b254..dd3a1d5 100644 --- a/execution_tape/README.md +++ b/execution_tape/README.md @@ -2,6 +2,96 @@ Portable, verifiable bytecode container format and register VM runtime (draft). -Design docs: -- `docs/overview.md` -- `docs/v1_spec.md` +`execution_tape` is the low-level execution layer for already-lowered programs. It owns the +portable program format, verifier, register VM, host-call ABI, aggregate values, tracing hooks, and +disassembly tools. It does not own language semantics, graph authoring, or host object lifetimes. + +The crate is `no_std + alloc` by default. The `std` feature is currently reserved for integrations +that need standard-library support. + +## Quick Start + +Build, verify, and run a one-function program: + +```rust +extern crate alloc; + +use alloc::vec; + +use execution_tape::asm::{Asm, FunctionSig, ProgramBuilder}; +use execution_tape::host::{Host, HostContext, HostError, SigHash, ValueRef}; +use execution_tape::program::ValueType; +use execution_tape::trace::TraceMask; +use execution_tape::value::Value; +use execution_tape::vm::{Limits, Vm}; + +struct NoHost; + +impl Host for NoHost { + fn call( + &mut self, + _symbol: &str, + _sig_hash: SigHash, + _args: &[ValueRef<'_>], + _rets: &mut [Value], + _ctx: HostContext<'_, '_>, + ) -> Result { + Err(HostError::UnknownSymbol) + } +} + +fn main() -> Result<(), Box> { + let mut asm = Asm::new(); + asm.const_i64(2, 1); + asm.i64_add(3, 1, 2); + asm.ret(0, &[3]); + + let mut builder = ProgramBuilder::new(); + builder.set_program_name("add_one"); + let entry = builder.push_function_checked( + asm, + FunctionSig { + arg_types: vec![ValueType::I64], + ret_types: vec![ValueType::I64], + }, + )?; + builder.set_function_input_name(entry, 0, "x")?; + builder.set_function_output_name(entry, 0, "y")?; + + let program = builder.build_verified()?; + let mut vm = Vm::new(NoHost, Limits::default()); + let out = vm.run(&program, entry, &[Value::I64(41)], TraceMask::NONE, None)?; + assert_eq!(out, vec![Value::I64(42)]); + Ok(()) +} +``` + +## Core Pieces + +- `asm`: ergonomic builders for functions, call signatures, constants, host signatures, and + bytecode emission. +- `program`: serialized program model, type tables, constants, host signatures, and names. +- `verifier`: validation and lowering into an execution-ready `VerifiedProgram`. +- `vm`: bounded interpreter for verified programs. +- `host`: host-call trait, borrowed argument views, aggregate readers, and access recording hooks. +- `trace`: low-overhead tracing events for profiling and diagnostics. +- `disasm`: human-readable disassembly for verified programs. + +## Design Docs + +The repository-level design notes live outside the packaged crate: + +- +- + +## Examples + +Print disassembly for a small branching program: + +```sh +cargo run -p execution_tape --example disasm +``` + +## Minimum supported Rust Version (MSRV) + +This crate has been verified to compile with **Rust 1.88** and later.