Splicery · executed example

Prepare the edit.
Preserve the original.

In the Writfold harness, Splicery is how a change is expressed: a small language for byte-exact edits to source files in any language. You select exact text, describe the replacement, and get a separate candidate file. The original is never touched.

Runs today Offline preview · never writes the original

01 / A precise change

Wrap one call, not every call

This Rust file calls open(url) in two functions. The recipe adds a retry around the call in connect only, and leaves probe alone.

Download client.rs · Download add-retry.spl. Save both files together.

pub fn connect(url: &str) -> Result<Conn, Error> {
    let conn = open(url)?;
    conn.handshake()?;
    Ok(conn)
}

pub fn probe(url: &str) -> bool {
    open(url).is_ok()
}
edit "client.rs" {
  @bind := one text "let conn = open(url)?;"
  @call := one text "open(url)" within @bind
  replace @call with ["with_retry(3, || ", keep(@call), ")"]
}

Anchor the line.

@bind selects the one exact line let conn = open(url)?;. If it is missing or appears twice, the recipe refuses.

Narrow the search.

@call finds open(url) only within @bind. The same call in probe is outside that span, so it is never a candidate.

Keep exact bytes.

keep(@call) copies the original bytes into the replacement. Nothing is reformatted or regenerated.

Every selector is resolved against the original bytes, never against a half-edited copy, so edits cannot drift.

02 / Computation, not application

Before and after

The preview resolves the selectors, turns the recipe into checked byte edits, and prints the candidate. The original file stays untouched.

client.rs · original, unchanged

pub fn connect(url: &str) -> Result<Conn, Error> {
    let conn = open(url)?;
    conn.handshake()?;
    Ok(conn)
}

pub fn probe(url: &str) -> bool {
    open(url).is_ok()
}

candidate.rs · preview on stdout

pub fn connect(url: &str) -> Result<Conn, Error> {
    let conn = with_retry(3, || open(url))?;
    conn.handshake()?;
    Ok(conn)
}

pub fn probe(url: &str) -> bool {
    open(url).is_ok()
}
@bind the anchored line · @call the call inside it, kept byte for byte · inserted new bytes. Nothing is written back to client.rs; applying an edit is Writfold's job, which today runs only in its trial profile.

03 / Run it

What the preview produced

This command was run with the development binary, which is not published yet. With both downloaded files in the current directory:

splicery preview --root . add-retry.spl > candidate.rs

The preview exited 0 and printed the candidate shown above; the shell saved it as candidate.rs. The bytes of client.rs were unchanged afterwards. Splicery works on bytes, so the same recipe style applies to TypeScript, Python, Markdown or any other text file.

Proved over the shipped Rust: batch validation, ordering and rendering. The candidate is the original with each target replaced in canonical order, the result does not depend on the order edits are listed, lengths add up exactly, and an empty batch changes nothing. The UTF-8 check of text candidates is tested, not proved. How we know

Development binary used: Splicery SHA-256 db79d50147cc51d7183b18474d1ea9f3f6eb935e14f7c7f8719e7fdea3965081.

04 / Refuse rather than guess

When Splicery refuses

Each of these variants was run against the same file. Each exited 2 without printing a candidate.

Ambiguity

Drop within @bind and open(url) matches in both functions. one text refuses with AmbiguousSelector rather than picking the first.

No match

Ask for let conn = open( url )?; with different spacing and nothing matches exactly. The recipe refuses with MissingSelector instead of choosing similar text.

Overlapping edits

Add a second replace @bind that covers the same bytes as the first edit. The edits conflict, and Splicery refuses with Overlap rather than silently ordering them.

This preview covers part of the language; unsupported constructs are refused rather than approximated. In the full flow, Weft assesses the claims behind a change, Splicery prepares it, and Writfold applies it after approval. See how that will work.