Scullery
Sovereign food provisioning pipeline. Sourcing, processing, larder, cooking.
Pipeline
Four stages. From source to table.
Source
Track suppliers, pack sizes, and pricing. Know exactly where every ingredient comes from and what it costs.
Process
Document transformations. Crack grains in a Zassenhaus hand mill. Dehydrate onions at 57°C for eight hours. Every method, explicit.
Store
Assign mixes to containers. Track capacity and availability. Know which jar holds which blend at all times.
Cook
Define recipes as structured steps — water volumes, durations, heat levels. Precise enough to reproduce perfectly every time.
Philosophy
Food is a system.
A recipe is the last step, not the first. Before you cook, you source. Before you source, you know what you need. Before you know what you need, you understand how ingredients transform.
Scullery models the entire lifecycle.
Most food software thinks in recipes. Scullery thinks in pipelines. YQ Wheat enters the system as whole berries from Hodmedod's in Suffolk. It flows through the Zassenhaus hand mill, becomes cracked grain, joins a named mix in a Muji jar, and becomes Skógargrautr. Every stage is data. Every transformation is traceable.
The Larder
Six sovereign collections.
Name, kind, form, notes. Wheat, barley, porcini, parsley — each with its current physical state.
Supplier, URL, pack size in grams, price in pence. Know exactly what to buy and where.
Input ingredient, output form, method. Mortar and pestle, dehydrate, crumble, slice and dry.
Name, kind, capacity in millilitres. Muji heat-proof jars, storage containers, every vessel tracked.
Named blends with components, proportions, and assigned containers. The composed result of processing.
Mix reference, servings, cooking steps. Water, duration, heat level — structured and reproducible.
In Practice
Skógargrautr.
Old Norse — skógar (of the forest) + grautr (porridge). Cracked Nordic grains with wild porcini, parsley and dried onion. Heritage grains from Hodmedod's, porcini from Forest Fungi in Devon. Here's how it flows through the pipeline.
Real Code
Data in. Meals out.
#[derive(Serialize, Deserialize)]
pub struct Larder {
pub ingredients: Vec<Ingredient>,
pub sources: Vec<Source>,
pub processes: Vec<Process>,
pub containers: Vec<Container>,
pub mixes: Vec<Mix>,
pub recipes: Vec<Recipe>,
}
pub enum Proportion {
EqualPart,
Grams(f64),
Tablespoons(f64),
Teaspoons(f64),
ToTaste,
}
pub enum Form {
Whole, Cracked, Kibbled,
Flaked, Pearled, Dried,
Dehydrated, Crumbled, Ground,
}
pub fn shopping_list_for_mix(
larder: &Larder,
mix_name: &str,
) -> Vec<ShoppingItem> {
let mix = larder.mixes.iter()
.find(|m| m.name == mix_name);
let Some(mix) = mix else { return vec![]; };
mix.components.iter().filter_map(|comp| {
larder.sources.iter()
.find(|s| s.ingredient == comp.ingredient)
.map(|source| ShoppingItem {
ingredient: comp.ingredient.clone(),
supplier: source.supplier.clone(),
pack_grams: source.pack_grams,
})
}).collect()
}
let larder = seed::full_larder();
// Display each recipe and its pipeline
for recipe in &larder.recipes {
let mix = larder.mixes.iter()
.find(|m| m.name == recipe.mix);
let steps = processing::processing_steps_for_mix(
&larder, &recipe.mix
);
display::print_recipe(recipe);
}
// Combined order across all recipes
let order = sourcing::combined_order(&larder);
sourcing::print_combined_order(&order);
// Larder status
larder::print_larder_status(&larder);
Approach
Not a recipe app.
Recipe Software
- Starts and ends with cooking
- Ingredients are strings
- "1 cup flour" — from where?
- Processing steps invisible
- Storage untracked
- No data portability
Recipes without systems.
Scullery
- Models the full lifecycle
- Ingredients are typed data
- Supplier, pack size, price tracked
- Every transformation explicit
- Container assignments managed
- Serializable to TOML
Data in. Meals out.
Pure Rust. Serde + TOML serialization. Two recipes. Complete food sovereignty.
License
Sovereign software.
Scullery is free to use. Your kitchen, your data, your pipeline.
Get in Touch