First-release documentation preview. Understand the release scope.
Browse documentation

Tutorials

Build a library and its consumer

Create reusable Rust, exercise it through a consumer, then make one visible change.

Create a reusable library with one consuming application and executable examples. Then change a value and see the consumer test detect it.

You need a runtime binary with a recorded source identity. A build from a clean Git checkout records its commit. A non-colocated JJ checkout or source archive instead needs the supported EFFECTFUL_SOURCE_COMMIT build override set to the exact, independently verified commit for those source bytes. Do not assign an unrelated commit to modified source. A binary with an unknown source commit refuses to create this scaffold because it cannot make an exact façade pin.

1. Create the project

From a directory where pricing does not already contain files, run:

effectful new ./pricing --kind library --name pricing
effectful verify ./pricing
effectful test ./pricing

The first command reports the files it wrote. Verification checks the declared consumer graph. The tests check the generated consumer’s two operations, including 6 × 7 = 42 and a revision value of 1.

The fast verification and test commands use the runtime. They do not invoke Cargo, rustc or a package download for each edit.

2. Look at the useful boundaries

File or directory Responsibility
pricing/library.toml Names the library, consumers and runtime source identity
pricing/packages/pricing/src/lib.rs Reusable functions
pricing/consumers/example/src/lib.rs Entries that call the library
pricing/consumers/example/tests/ The consumer’s expected results
pricing/oracle/ A separate native Rust comparison project

The library contains this function:

pub fn scale(value: i64, factor: i64) -> i64 {
    value * factor
}

The consumer exposes it through a checked entry:

use effectful::effectful;

#[effectful]
pub fn scaled(value: i64, factor: i64) -> i64 {
    pricing::scale(value, factor)
}

The library owns no listener, grant or deployment. Its consumer gives it an application context.

3. Make one change

Ask your coding agent to change the return value of revision() in pricing/packages/pricing/src/lib.rs from 1 to 2. Keep the function’s signature unchanged. Then run:

effectful verify ./pricing
effectful test ./pricing

Verification can still succeed because the source remains valid. The revision test should fail because its expectation still names 1. This is a useful distinction: checked code can still do the wrong thing for a stated requirement.

4. Review and accept the new result

Decide whether 2 is the intended new result. If it is, update pricing/consumers/example/tests/revision.json so its expected result is ["s64", "2"], then rerun verification and tests.

Do not update an expectation merely to make a failing test pass. In this exercise the intended change was explicit; in a real feature, compare the observed result with the acceptance criteria first.

The native oracle separately expects the original revision. If you use that comparison project, update its reviewed expectation too and run it using the toolchain specified by the generated README. It has its own Cargo build path.

What just happened?

You edited reusable code, checked its consumer and observed a contract change through a test. Septa’s library workflow keeps that relationship visible. Exact source identities make the selected code unambiguous, while tests make expectations executable.

Continue with the running consumer watch loop or code and evidence using this pricing project.

Search concepts, guides and reference.