Skip to content

Overview — Project 1: Brandforge

The fastest way to understand Rust and AI together is to make something you can inspect. In this project you will build Brandforge, a command-line product inspired by a small TypeScript experiment: give it business research, ask a model for a brand profile, reject unsupported advertising claims, and create a campaign pack.

The model is allowed to propose. Rust decides what is valid, what is supported by evidence, and what may become an artifact.

Beginner rule: the page must name the file

Section titled “Beginner rule: the page must name the file”

You are never expected to decide where a lesson’s code belongs. Project 1 uses two separate copies:

rust/rust-ai-engineering/crates/brandforge/ # finished reference answer
rust/rust-ai-engineering/learning/brandforge/ # your private working copy

Every day begins with an edit map. Every code block that you should paste is labeled CREATE, REPLACE, or ADD, followed by the exact path. Explanatory snippets are labeled READ ONLY.

Start by creating the working copy with Before Day 1 — Make Your Working Copy. Do not edit the finished reference crate while following the lesson.

Run the finished reference crate:

Terminal window
cd rust/rust-ai-engineering
cargo run -p brandforge -- build \
--source fixtures/brandforge/site.md \
--profile fixtures/brandforge/business-profile.json \
--output target/brandforge

It writes:

target/brandforge/
├── business-profile.json # typed model output
├── claim-audit.json # evidence result for every proposed claim
├── image-prompt.txt # compiled only from approved information
├── ad-preview.svg # visible preview you can open in a browser
└── run-report.json # input hashes and artifact inventory

Now run the dangerous case:

Terminal window
cargo run -p brandforge -- build \
--source fixtures/brandforge/site.md \
--profile fixtures/brandforge/business-profile-unsupported.json \
--output target/brandforge-bad

The model profile claims 98% client satisfaction, but the website snapshot never says that. The program exits unsuccessfully, preserves claim-audit.json, and refuses to create an ad preview. That failure is part of the product.

DayProduct sliceRust that the slice forcesAI lesson
Setupseparate working copypaths, Cargo project layout, edit loopkeep the runnable answer separate
1CLI plus website snapshotCargo, modules, PathBuf, String, borrowingfreeze model input
2typed business profilestructs, enums, Serde, Option, validationstructured output is still untrusted
3replaceable profile producertraits, errors, configurationscripted first, live provider second
4evidence gateiterators, normalization, exhaustive stateprompts do not verify facts
5campaign pack and previewbytes, files, hashing, unit and CLI testsartifact provenance and evals
website snapshot ───────┐
├─▶ claim audit ─▶ verified prompt ─▶ preview / image
model business profile ┘ │
└─▶ reject unsupported campaign

There are two important boundaries:

  1. The model output is decoded into BusinessProfile, but decoding only proves its shape.
  2. Every promotional claim must point to a quote present in the frozen source before generation.

The live-provider extension may use an API, but the required build is offline. You can learn the software, rerun the tests, and diagnose failures without a key, network, GPU, or paid request.

crates/brandforge/
├── src/
│ ├── main.rs # CLI and exit status
│ ├── lib.rs # public product boundary
│ ├── model.rs # scripted model and live-provider trait boundary
│ ├── profile.rs # model-facing data and claim audit
│ ├── pipeline.rs # read, validate, compile, write
│ ├── render.rs # image prompt and SVG preview
│ └── error.rs # named failure modes
└── tests/cli.rs # run the real executable

The reference crate is the finished answer. The setup page creates a separate starter with fixtures and dependencies already in place, so the remaining pages can tell you exactly which file to edit.

Start with Before Day 1 — Make Your Working Copy →.