Cookpit v3.2 — Definitive Glossary
The authoritative field-by-field reference for the v3.2 schema. Treats v3.2 as a clean-slate format (no backward-compatibility ballast). Every value defined by
schema/cookpit-cooking-file-v3.2.jsonis documented here: name, JSON type, purpose within the v3.2 cooking-file model, and where applicable the constant set, regex, or canonical reference.When a field has been the subject of a published canonical profile, a published rule, or a corpus-derived pattern, the glossary points at the authoritative document rather than restating it. The glossary is therefore intentionally compact — it indexes the v3.2 world, it does not re-explain it.
Cross-references in
→ doc#sectionform point at the bundle's canonical documents.
Lifecycle context
Every v3.2 cooking file passes through four stages
(rules.md A0):
- Generation. AI Chef emits an unauthenticated (
U) file. - Validation. Validator runs the file against
validation.md. - Attestation. Validator stamps a passed file, replacing the
attestation block with the authenticated form and flipping the
filename flag to
A. - Consumption. Chef app or other consumer verifies the file's signature and runs the plan.
The schema fields documented below appear at different stages. Two fields in particular are stage-bound:
cookpit.quantitativeFingerprint(§2.17, §12) — the stage-1 source fingerprint. AI populates it; validator confirms it at stage 2.cookpit.attestation(§2.20, §16) — the stage-1 unauthenticated marker that the validator replaces with the stage-3 authenticated attestation carrying the file fingerprint and signature consumed at stage 4.
These two fingerprints are not redundant — they answer different
integrity questions at different stages (rules.md A0.6).
How to read this glossary
Every entry follows the same structure:
| Heading | Meaning |
|---|---|
| Name | The JSON path used in the schema |
| Type | JSON type (string, number, array<T>, object, etc.) |
| Required | Whether the field is required at its position in the schema |
| Constraint | Regex, enum, range, or $ref referenced by the schema |
| Purpose | What this field carries; what consumes it; what role it plays |
| Reference | Pointer to the canonical document if one exists |
| Example | A representative value drawn from the walked corpus where appropriate |
Schema paths use dotted notation. Array element fields are written as
<array>[].<field>. oneOf branches are numbered.
Section 1 — Top-level (schema.org pass-through + cookpit anchor)
1.1 @context
- Type:
string|array|object - Required: yes
- Constraint: must include
https://schema.org/and acookpitnamespace mapping - Purpose: JSON-LD context anchor. The
https://schema.org/declaration gives the file schema.org Recipe semantics for any consumer that doesn't know about cookpit. Thecookpitnamespace mapping (canonical URIhttps://cookpit.org/ns/v3.2#) gives cookpit-aware consumers access to thecookpit:typed extension. - Example:
["https://schema.org/", { "cookpit": "https://cookpit.org/ns/v3.2#" }]
1.2 @type
- Type:
array<string>(length ≥ 2) - Required: yes
- Constraint: MUST include both
Recipeandcookpit:CookingFile - Purpose: declares the file as both a schema.org Recipe (for schema.org-aware consumers like Google Search) and a v3.2 CookingFile (for the Chef app and the cookpit corpus). The dual declaration is what makes the file portable across the two worlds.
- Reference: rules.md B1
- Example:
["Recipe", "cookpit:CookingFile"]
1.3 $schema
- Type:
string(URI) - Required: optional but expected
- Purpose: identifies the v3.2 JSON Schema URL for tooling that resolves schemas by URI. Convenience field.
- Reference: rules.md B3
- Example:
https://cookpit.org/v3.2/schema.json
1.4 name
- Type:
string(minLength 1) - Required: yes
- Purpose: the recipe's display name. Pass-through to
schema.org
Recipe.name. Drives the file's deterministic id (thef…id is hashed from this value via the canonical id derivation profile). - Reference: → canonical-id-derivation.md §3.1
- Example:
"Pork fillet, braised cheeks and pork belly"
1.5 description
- Type:
string - Required: optional
- Purpose: free-text description for human readers and schema.org consumers. Lexicon does NOT apply to this field; it is a schema.org pass-through that may carry source warmth verbatim.
- Reference: lexicon.md §1 scope table
1.6 image
- Type:
string(URI) |array<string> - Required: optional
- Purpose: schema.org image URL(s) for the dish. Single URI or array.
1.7 author
- Type:
object|string - Required: optional
- Purpose: schema.org author. Either a
Person/Organizationobject with@typeandname, or a free-text string. - Example:
{ "@type": "Person", "name": "Stephen Crane" }
1.8 datePublished
- Type:
string - Required: optional
- Purpose: schema.org publication date. Free-text — the schema doesn't restrict the format.
1.9 prepTime
- Type:
string(ISO 8601 duration) - Required: optional
- Constraint: pattern starts with
P - Purpose: schema.org prep duration. Reflects the source's
prep-time field. The cookpit-internal authoritative copy is at
cookpit.sourceTiming.prepTime. - Example:
"PT45M"
1.10 cookTime
- Type:
string(ISO 8601 duration) - Required: optional
- Constraint: pattern starts with
P - Purpose: schema.org cook duration. Drives the SUM of all
declared phases'
nominalDurationper rule C2 (live timer is cook time only, never total). The cookpit-internal copy is atcookpit.sourceTiming.cookTime.
1.11 totalTime
- Type:
string(ISO 8601 duration) - Required: optional
- Constraint: pattern starts with
P - Purpose: schema.org total duration. Informational only — v3.2's live timer is bound to cook time, not total time.
1.12 recipeYield
- Type:
string|number - Required: optional
- Purpose: schema.org yield. Either a number ("4") or a phrase ("Serves 6-8"). Free-text.
1.13 recipeCategory
- Type:
string - Required: optional
- Purpose: schema.org category. Free-text.
- Example:
"Main","Dessert","Starter"
1.14 recipeCuisine
- Type:
string - Required: optional
- Purpose: schema.org cuisine. Free-text. Lexicon §8 source-faithful preservation rules apply to in-scope text but the cuisine label itself is metadata.
- Example:
"Italian","French","Chinese"
1.15 keywords
- Type:
string(comma-separated) - Required: optional
- Purpose: schema.org keywords. Comma-separated. For dietary
tags, prefer
cookpit.dietary[](typed, validated) over keywords string.
1.16 nutrition
- Type:
object - Required: optional
- Purpose: schema.org
NutritionInformationobject. Pass-through to schema.org consumers.
1.17 recipeIngredient
- Type:
array<string>(length ≥ 1) - Required: yes
- Purpose: schema.org ingredient list — the SOURCE recipe's
ingredient lines preserved verbatim. The chef-detective's cookpit-
typed view is at
cookpit.ingredients[]. Both should be present in every file; this is the source-faithful pass-through copy. - Reference: lexicon.md §1 scope table — lexicon does NOT apply
- Example:
["1 kg beef fillet", "250 g mushrooms", ...]
1.18 recipeInstructions
- Type:
arrayofrecipeInstructionItem($def) - Required: optional
- Purpose: schema.org method steps preserved verbatim from the
source. The chef-detective's cookpit-typed plan is split across
declared phases (
cookpit.prepCook.tasks[],cookpit.preCook.tasks[],cookpit.liveCook.tasks[]). Source typos and culinary tips remain visible here per the source-content-handling rules; the typed plan filters them. - Reference: → source-content-handling.md
- Example: items shape per
recipeInstructionItem$def
1.19 cookpit
- Type:
object($refcookpit) - Required: yes
- Purpose: the v3.2 extension block. Holds every cookpit-typed field below (sections 2-12).
Section 2 — cookpit block (top-level extension)
2.1 cookpit.version
- Type:
string - Required: yes
- Constraint: pattern
^3\.2\.\d+$ - Purpose: the cookpit cooking-file format version. Always
3.2.0for files conforming to this glossary. - Reference: rules.md B2
2.2 cookpit.id
- Type:
string - Required: yes
- Constraint:
$fileIdpattern^f[0-9a-f]{10}$ - Purpose: the file's deterministic id. Derived from the
recipe's
namefield via the canonical id derivation profile. - Reference: → canonical-id-derivation.md §3.1
2.3 cookpit.courses
- Type:
array<string> - Required: yes
- Constraint: 1-3 items, no duplicates, each from
["starter", "main", "dessert"] - Purpose: declares which course(s) this file's plan covers.
Drives lane-scope (
S1/S2/S3lanes are valid only when"starter"is in courses, etc.). - Reference: rules.md B5
2.4 cookpit.difficulty
- Type:
string(enum) - Required: yes
- Constraint: one of
["easy", "medium", "hard", "expert"] - Purpose: declares the dish's difficulty band. Drives Chef-app filtering and progressive-disclosure UX.
- Reference: rules.md B6
2.5 cookpit.sourceTiming
- Type:
object - Required: optional
- Purpose: preserves the source recipe's stated timing facts verbatim. Carries either ISO durations (when the source uses ISO-compatible phrasing) or text equivalents (when the source uses ranges, prose, or open bounds).
2.5.1 cookpit.sourceTiming.prepTime
- Type: ISO 8601 duration string
- Purpose: source prep time, ISO form.
2.5.2 cookpit.sourceTiming.cookTime
- Type: ISO 8601 duration string
- Purpose: source cook time, ISO form. Drives the SUM of all
declared phases'
nominalDuration(rule C2). For files with only aliveCookphase this is theliveCook.nominalDurationitself.
2.5.3 cookpit.sourceTiming.totalTime
- Type: ISO 8601 duration string
- Purpose: source total time, ISO form.
2.5.4 cookpit.sourceTiming.prepTimeText
- Type: free-text string
- Purpose: when the source uses prose (e.g.
"Less than 30 mins") or a range ("15 mins - 20 mins"), the prose is preserved here.
2.5.5 cookpit.sourceTiming.cookTimeText
- Type: free-text string
- Purpose: cook-time prose. Used when the source has a range
(
"30 mins to 1 hour") or open bound ("Over 2 hours"); the chosen phase decomposition (thenominalDurationvalues across declared phases) is justified per rules.md C3.
2.5.6 cookpit.sourceTiming.totalTimeText
- Type: free-text string
2.6 (removed in v3.2 three-phase) cookpit.nominalCookDuration
This top-level field has been removed. Each declared phase now
carries its own nominalDuration inside the phase block — see
section 14 below for cookpit.prepCook, section 15 for
cookpit.preCook, and section 16 for cookpit.liveCook. The total
live runtime of the file is the SUM of all declared phases'
nominalDuration values.
2.7 cookpit.laneModel
- Type:
object($reflaneModel) - Required: yes
- Purpose: the fixed primary/secondary/tertiary course lane block. Same shape in every v3.2 file. Provides the alarm lane (A0 at second :00) and three lanes per course (e.g. M1/M2/M3 at seconds :30/:35/:40).
- Reference: rules.md D1, D5; → canonical-patterns.md §1
2.8 cookpit.orchestration
- Type:
object($reforchestration) - Required: yes
- Purpose: declares orchestration semantics — how the live timer relates to source timing, how prep is handled, how runtime overruns are managed.
2.9 cookpit.prerequisites
- Type:
object($refprerequisites) - Required: optional
- Purpose: pre-Start checklist groups. Six groups: ingredients, equipment, utensils, sundries, skills, hotspots, notes. Pre-cook prep that satisfies its deadline trivially is detective-promoted here; the Chef app blocks Start until all included items are confirmed.
- Reference: rules.md F
2.10 cookpit.ingredients
- Type:
array<ingredient> - Required: optional but expected
- Purpose: the chef-detective's typed ingredient view. Each
entry mirrors a
recipeIngredientline but is structurally encoded with quantity, unit, section, role, and optional primitives (alternative, choices, splits, extras, depth).
2.11 cookpit.equipment
- Type:
array<equipment> - Required: optional but expected
- Purpose: declared equipment (vessels, ovens, hobs, mixers, fryers). Closed-world: every equipment-ref in tasks/processes resolves to a declared item.
2.12 cookpit.utensils
- Type:
array<utensil> - Required: optional but expected
- Purpose: declared utensils (knives, spoons, scales, jugs).
2.13 cookpit.sundries
- Type:
array<sundry> - Required: optional
- Purpose: declared sundries — consumables that aren't ingredients (cling film, parchment, foil, kitchen paper).
2.14 cookpit.prepCook
- Type:
object($refphaseBlock+ requiredidof pattern^y[0-9a-f]{10}$) - Required: optional — declared only when the source establishes a discrete TIMED active-prep window BEFORE the cook day (pressing meat under weights, salt-curing, marinating with active monitoring).
- Purpose: the active timed prep phase. Carries its own clock,
lanes, tasks, processes and completion cue. Independent of
cookpit.preCookat runtime — the Chef app starts the prepCook A0 timer when file-level prerequisites are confirmed; prepCook may run concurrently with or sequentially before/after preCook (Q4). prepCook is NOT a relocation target for prep that F2 places insidecookpit.liveCook(F5). - Reference: rules.md F3, F5, Q1-Q9; → canonical-patterns.md §8
2.15 cookpit.preCook
- Type:
object($refphaseBlock+ requiredidof pattern^z[0-9a-f]{10}$) - Required: optional — declared when the source cooks a mainstay component ahead of final assembly (a slow braise whose product is plated, a meringue base, a poached salmon for a pâté).
- Purpose: the pre-cook phase for cooked mainstay components.
Internal lane concurrency handles parallel processes (cheeks on
M1, confit on M2 within preCook). Independent of
cookpit.prepCookat runtime — the Chef app starts the preCook A0 timer when file-level prerequisites are confirmed; preCook may run concurrently with or sequentially before/after prepCook (Q4). - Reference: rules.md F3, Q1-Q9; → canonical-patterns.md §8
2.16 cookpit.liveCook
- Type:
object($refphaseBlock, NOidfield of its own) - Required: yes — every v3.2 file declares liveCook.
- Purpose: the final-assembly cook phase ending in serving. The
dish reaches the plate at liveCook time-up. liveCook borrows the
file's
cookpit.id(f…) as its identity — the file IS the live cook. Strictly downstream ofcookpit.prepCookandcookpit.preCookat runtime — liveCook becomes available only when the LAST of the declared upstream phases fires its A0 time-up alarm; liveCook NEVER overlaps prepCook or preCook (Q4). Live prep that F2 places inside the cook window stays in liveCook; the presence of a prepCook block does not relocate it out (F5). - Reference: rules.md F2, F5, Q1-Q9; the canonical default for the vast majority of recipes.
2.17 cookpit.quantitativeFingerprint
- Type:
object($refquantitativeFingerprint) - Required: optional but expected
- Purpose: the strict active-number fingerprint of the SOURCE
recipe's numeric content (the stage-1 source fingerprint).
Computed by the AI at generation time from the source recipe;
re-checked by the validator at stage 2 (V-FINGERPRINT-B). Identifies
the file's source numeric skeleton. Distinct from the file
fingerprint that lives at
cookpit.attestation.fileFingerprintand is computed by the validator at stage 3 (rules.md A0.6). - Reference: → canonical-fingerprint-normalisation.md, rules.md K, A0.6
2.18 cookpit.dietary
- Type:
array<string>(enum) - Required: optional
- Constraint: each value from a 20-element vocabulary (vegetarian, vegan, pescatarian, dairy-free, egg-free, nut-free, peanut-free, gluten-free, wheat-free, soy-free, shellfish-free, low-sugar, low-sodium, low-fat, low-carb, high-protein, halal, kosher, pregnancy-friendly, alcohol-free)
- Purpose: structural dietary tags. Replaces lossy
keywordsstorage for downstream filtering / allergen audit / shopping list.
2.19 cookpit.generation
- Type:
object($refgeneration) - Required: yes
- Purpose: generation metadata declaring the canonical profile the file was authored against. Drives validator behaviour.
2.20 cookpit.attestation
- Type:
object($refattestation) - Required: yes
- Purpose: the lifecycle-attestation block. Carries either the
stage-1 unauthenticated marker (AI Chef output, before
validation) or the stage-3 authenticated attestation (after
the canonical validator stamps a passed file). Carries the file
fingerprint, signature, issuer, validator version, timestamp and
key id when authenticated. The block is the load-bearing trust
signal at stage-4 consumption; the filename's
A/Uflag is decorative and is not consulted for trust (rules.md A0.7, R10). - Reference: → §16, rules.md R, A0.6
Section 3 — Type-prefixed deterministic ID patterns
Every entity in the v3.2 file carries a deterministic id of the form
<typePrefix><10 hex>. The 10 hex digits derive from the canonical
id derivation profile.
3.1 $fileId
- Pattern:
^f[0-9a-f]{10}$ - Purpose: file id. Derived from the recipe's
name.
3.2 $ingredientId
- Pattern:
^i[0-9a-f]{10}$ - Purpose: ingredient id. Derived from
cookpit.ingredients[].text- array index. Splits (sub-portions) also use this id type.
3.3 $equipmentId
- Pattern:
^e[0-9a-f]{10}$ - Purpose: equipment id. Derived from
cookpit.equipment[].text+ index.
3.4 $utensilId
- Pattern:
^u[0-9a-f]{10}$ - Purpose: utensil id.
3.5 $sundryId
- Pattern:
^s[0-9a-f]{10}$ - Purpose: sundry id.
3.6 $prereqId
- Pattern:
^q[0-9a-f]{10}$ - Purpose: prerequisite-item id. Used by every prereq group
(ingredients, equipment, utensils, sundries, skills, notes) — the
derivation distinguishes the group via
entityType. - Reference: → canonical-id-derivation.md §3.6
3.7 $processId
- Pattern:
^p[0-9a-f]{10}$ - Purpose: process id.
3.8 $taskId
- Pattern:
^t[0-9a-f]{10}$ - Purpose: task id. Derived from
tasks[].action+tasks[].time(the lane-time, NOT the array index — anchors the id to the source-derived moment). The derivation'sentityTypeis phase-scoped (taskfor liveCook,prepCook-task,preCook-task) so identical actions in different phases produce distinct ids. - Reference: → canonical-id-derivation.md §3.9
3.9 $hotspotId
- Pattern:
^h[0-9a-f]{10}$ - Purpose: hotspot id. Hotspots live in
cookpit.prerequisites.hotspots[]and reference task ids that mark dish-critical moments. HotspottaskRefsmay target tasks in any declared phase.
3.10 $prepCookId
- Pattern:
^y[0-9a-f]{10}$ - Purpose: prepCook phase id. Identifies
cookpit.prepCook. Distinct prefixyseparates the prepCook namespace from the preCook (z…) and file (f…) namespaces. - Reference: → canonical-id-derivation.md §3.10
3.11 $preCookId
- Pattern:
^z[0-9a-f]{10}$ - Purpose: preCook phase id. Identifies
cookpit.preCook. - Reference: → canonical-id-derivation.md §3.11
(liveCook does not carry a phase id of its own — its identity is
the file's cookpit.id (f…); see §3.12 of
canonical-id-derivation.md.)
Section 4 — Time and duration patterns
4.1 $duration
- Pattern:
^[0-9]{2}:[0-5][0-9]:[0-5][0-9]$ - Purpose: HH:MM:SS time-of-day or duration. Hours range 00-99, so each phase timer accommodates up to 99h 59min 59sec.
- Used at:
cookpit.prepCook.nominalDuration,cookpit.preCook.nominalDuration,cookpit.liveCook.nominalDuration.
4.2 $isoDuration
- Pattern: ISO 8601 duration (
P…) - Purpose: ISO 8601 durations. Used for prep/cook/total times, process target/min/max durations, prereq leadTime, temperature.atOffset.
4.3 $signedIsoDuration
- Pattern: ISO 8601 duration, optionally negative
- Purpose: signed ISO duration. Used by
timingBasis.offsetwithsourceImpliedDeadlinebasis to record the deduced prep duration as a negative offset from the consumer task. - Example:
"-PT2M"for "2 minutes before the consumer task"
4.4 $laneTime
- Pattern:
^[0-9]{2}:[0-5][0-9]:[0-5][0-9]\.(A0|S[1-3]|M[1-3]|D[1-3])$ - Purpose: lane-time stamp combining clock time and lane label. The seconds component MUST match the lane (A0=:00, S1=:15, S2=:20, S3=:25, M1=:30, M2=:35, M3=:40, D1=:45, D2=:50, D3=:55).
- Used at:
tasks[].time. - Reference: rules.md D5
Section 5 — Lane model
5.1 $lane
- Enum:
["A0", "S1", "S2", "S3", "M1", "M2", "M3", "D1", "D2", "D3"] - Purpose: the 10 lane labels. A0 is the global alarm lane; S1-3, M1-3, D1-3 are course-scoped.
5.2 $courseLane
- Enum:
["S1", "S2", "S3", "M1", "M2", "M3", "D1", "D2", "D3"] - Purpose: subset of
$laneexcluding A0. Used where only course-scoped lanes are valid.
5.3 $course
- Enum:
["starter", "main", "dessert"] - Purpose: the three courses.
5.4 $laneModel.type
- Constant:
"fixedPrimarySecondaryTertiaryCourseLanes" - Purpose: identifies the v3.2 lane model. Always this constant.
5.5 $laneModel.alarmLane
- Object with:
lane: "A0",second: 0,scope: "global",defaultSound: "klaxon" - Purpose: the alarm-lane block. Always exactly this shape.
5.6 $laneModel.courseLanes.starter / .main / .dessert
- Each: array of 3
$courseLanesArrayitems - Purpose: the three lanes per course, with their second (15/20/25 for starter; 30/35/40 for main; 45/50/55 for dessert), role (primary/secondary/tertiary), and defaultSound.
5.7 $courseLanesArray[].lane
- Type:
$courseLane - Purpose: the lane label.
5.8 $courseLanesArray[].second
- Type:
integer(15-55) - Purpose: the seconds-of-minute for this lane.
5.9 $courseLanesArray[].role
- Enum:
["primary", "secondary", "tertiary"]
5.10 $courseLanesArray[].defaultSound
- Type:
$sound(see 6.1)
5.11 $sound
- Enum:
["bell", "klaxon", "chime", "tick"] - Purpose: the four sound options. A0 alarm-lane defaults to
klaxon; course lanes default to bell. Per-task override via
tasks[].sound.
Section 6 — Orchestration
The orchestration block declares the timing semantics — how the live timer relates to source timing, how prep is handled, how overruns are managed.
6.1 cookpit.orchestration.mode
- Constant:
"countup" - Purpose: timer mode. Always count-up from 00:00:00 in v3.2.
6.2 cookpit.orchestration.timingBasis
- Constant:
"cookTime" - Purpose: identifies that the sum of phase
nominalDurations is bound to the source's cook time (not total time). Per rule C2.
6.3 cookpit.orchestration.prepHandling
- Constant:
"preStartChecklist" - Purpose: prep is modelled as pre-Start prerequisites, not as timed tasks. Per rule F1.
6.4 cookpit.orchestration.livePrepHandling
- Constant:
"scheduledWithinCookDuration" - Purpose: prep that must happen during the live cook (per rule F2) is scheduled as normal timed tasks, not as a separate prep timer.
6.5 cookpit.orchestration.startEnabledBy
- Constant:
"allPrerequisitesConfirmed" - Purpose: the Start button condition. Per rule F3.
6.6 cookpit.orchestration.timelineStyle
- Constant:
"sequentialTimedPlan"
6.7 cookpit.orchestration.timingPolicy
- Constant:
"sourceDerivedDeterministicOptimal" - Purpose: identifies the chef-detective's deductive timing policy. Per rules.md A1.
6.8 cookpit.orchestration.overlapPolicy
- Constant:
"usePassiveTimeForActiveWork" - Purpose: blesses the chef-detective's "schedule active work inside passive windows" pattern (sourceMeanwhile basis).
6.9 cookpit.orchestration.runtimeOverruns
- Constant:
"appOwned" - Purpose: declares that runtime overrun handling is the Chef app's responsibility, not the file's. Per rule A3.
Section 7 — Prerequisites
7.1 cookpit.prerequisites.ingredients[]
- Each:
$prerequisiteItem - Purpose: pre-Start ingredient prep — chopping, weighing, beating, blanching. Items here are confirmed before Start.
7.2 cookpit.prerequisites.equipment[]
- Each:
$prerequisiteItem - Purpose: pre-Start equipment readiness — oven preheat
(with
leadTime: PT15M), pan on the hob, etc.
7.3 cookpit.prerequisites.utensils[]
- Each:
$prerequisiteItem - Purpose: utensils to-hand prereqs.
7.4 cookpit.prerequisites.sundries[]
- Each:
$prerequisiteItem - Purpose: sundries-to-hand prereqs (cling film cut, parchment ready).
7.5 cookpit.prerequisites.skills[]
- Each:
$prerequisiteItem - Purpose: skill checks. The user confirms they're comfortable with the named technique before Start.
7.6 cookpit.prerequisites.hotspots[]
- Each:
$hotspotItem - Purpose: dish-critical moments. Each hotspot references the task(s) it bears on; the Chef app surfaces these at the bound task moment.
7.7 cookpit.prerequisites.notes[]
- Each:
$prerequisiteItem - Purpose: free-text notes that need user acknowledgement before Start. Used for chef-detective decisions, source-content filter decisions, range-resolution justifications.
7.8 $prerequisiteItem.id
- Type:
$prereqId - Required: yes
7.9 $prerequisiteItem.text
- Type:
string(minLength 1) - Required: yes
- Purpose: the prereq's user-facing text. Lexicon applies fully for action-bearing prereqs and lightly for state descriptions (per lexicon.md §1 scope table).
7.10 $prerequisiteItem.leadTime
- Type:
$isoDuration - Required: optional
- Purpose: the source-implied window before the live timer can
start. Three-tier vocabulary corpus-confirmed:
P1D(overnight),PT8H(multi-hour press / chill),PT15M(oven preheat). - Reference: → canonical-patterns.md §3
7.11 $prerequisiteItem.ingredientRefs[]
- Type: array of
$ingredientId - Purpose: structural references to the ingredients this prereq concerns. Closure rule applies; V-REFS-COVERAGE recognises these as legitimate consumers.
7.12 $prerequisiteItem.equipmentRefs[]
- Type: array of
$equipmentId - Purpose: structural equipment references. Same closure semantics.
7.13 $prerequisiteItem.utensilRefs[]
- Type: array of
$utensilId
7.14 $prerequisiteItem.sundryRefs[]
- Type: array of
$sundryId
7.15 $prerequisiteItem.helpRef
- Type:
string - Purpose: optional help-content URL or anchor for the Chef app.
7.16 $hotspotItem.id
- Type:
$hotspotId
7.17 $hotspotItem.text
- Type:
string(minLength 1) - Purpose: the hotspot's user-facing description — typically a warning about what goes wrong if the moment is missed (e.g. "If the eggs scramble you've lost it").
7.18 $hotspotItem.taskRefs[]
- Type: array of
$taskId(length ≥ 1) - Purpose: the task(s) the hotspot bears on.
Section 8 — Resource definitions
8.1 $ingredient.id
- Type:
$ingredientId - Required: yes
8.2 $ingredient.text
- Type:
string(minLength 1) - Required: yes
- Purpose: the chef-detective's typed ingredient label. May carry purpose qualifiers ("Butter for the bechamel", "Pork stock for the braise") to disambiguate same-noun-different-purpose cases.
8.3 $ingredient.quantity
- Type:
$quantityValue(number or{min, max}) - Required: optional
- Purpose: the canonical quantity. Omit for
toTaste,toServe,asNeededsemantic units (those carry the meaning inunitalone).
8.4 $ingredient.unit
- Type:
string - Required: optional
- Purpose: the canonical unit. Drawn from the canonical-units vocabulary.
- Reference: → canonical-units.md
8.5 $ingredient.size
- Type:
string - Required: optional
- Purpose: optional size qualifier ("large", "medium", "small") per source phrasing.
8.6 $ingredient.metricQuantity / $ingredient.metricUnit
- Type:
$quantityValue/string - Required: optional
- Purpose: optional metric-equivalent values when the canonical quantity is non-metric.
8.7 $ingredient.metricApproximate
- Type:
boolean - Required: optional
- Purpose: flags the metric value as a rounding rather than exact conversion.
8.8 $ingredient.container
- Type:
objectwithtype(string) andquantity(number) - Required: optional
- Purpose: structural packaging context —
{type: "jar", quantity: 1}for "1 jar",{type: "can", quantity: 2}for "2 cans". Distinct fromunit; preferred overunit: "jar".
8.9 $ingredient.course
- Type:
$course - Required: optional
- Purpose: which course this ingredient serves.
8.10 $ingredient.section
- Type:
string - Required: optional
- Purpose: within-course grouping label (
"Filling","Topping","Sauce","Seasoning"). Drives Chef-app shopping-list grouping.
8.11 $ingredient.optional
- Type:
boolean - Required: optional, default
false - Purpose: flags decorative / "to serve" ingredients exempt from V-REFS-COVERAGE coverage requirements.
8.12 $ingredient.alternative
- Type:
objectwithtext(required),quantity,unit,metricQuantity,metricUnit - Required: optional
- Purpose: source-stated PRIMARY + FALLBACK substitution
(
"vanilla pod, or vanilla extract"). Distinct fromchoices[].
8.13 $ingredient.choices
- Type: array (≥ 2) of choice objects
- Required: optional
- Purpose: source-stated EQUIVALENT same-role options the chef
picks from (
"cod, haddock or pollock";"pearl onions or 24 baby onions"). Each choice carries its own quantity+unit.
8.14 $ingredient.splits
- Type: array (≥ 2) of split objects
- Required: optional
- Purpose: partitioning of this ingredient across multiple tasks
at distinct fractions (
"three-quarters for the mash, the remaining quarter for the topping"). Each split has its owni…id, a fraction (0 < f ≤ 1), optional label, optional usedBy taskId.
$ingredient.splits[].id
- Type:
$ingredientId - Required: yes
$ingredient.splits[].fraction
- Type:
number(0 < f ≤ 1) - Required: yes
$ingredient.splits[].label
- Type:
string - Required: optional
$ingredient.splits[].usedBy
- Type:
$taskId - Required: optional
8.15 $ingredient.extras
- Type: array (≥ 1) of extras objects
- Required: optional
- Purpose: "plus extra for X" annotations
(
"120g unsalted butter, plus extra for greasing").
$ingredient.extras[].purpose
- Type:
string(minLength 1) - Required: yes
- Purpose: short phrase describing the extra's use.
$ingredient.extras[].quantity / $ingredient.extras[].unit
- Type: optional
- Purpose: optional explicit quantity/unit for the extra.
8.16 $ingredient.depth
- Type:
objectwithvalue,unit, optionalvesselRef - Required: optional
- Purpose: fill-to-depth specification for ingredients added by
depth not volume (deep-fry oil).
unitfrom["cm", "inch", "in"].vesselRefpoints at the equipment whose geometry determines actual volume.
8.17 $equipment.id
- Type:
$equipmentId - Required: yes
8.18 $equipment.text
- Type:
string(minLength 1) - Required: yes
8.19 $equipment.course
- Type:
$course - Required: optional
8.20 $equipment.power
- Enum:
["electric", "gas", "induction", "none"] - Required: optional
- Purpose: optional power-source qualifier. The chef-detective may use this to make timing decisions where the source is silent on heat-up time. Heat-level abstraction principle keeps this optional and rarely populated.
8.21 $equipment.notes
- Type:
string - Required: optional
- Purpose: free-text notes ("wok works equally", "non-stick").
8.22 $equipment.choices
- Type: array (≥ 2) of choice objects with
textandnotes - Required: optional
- Purpose: source-stated equipment equivalents (
"deep fryer or deep saucepan").
8.23 $utensil.id / .text / .course
- Same shape as equipment without
power/notes/choices.
8.24 $sundry.id / .text / .course
- Same shape.
Section 9 — Tasks and processes
9.1 $task.id
- Type:
$taskId - Required: yes
9.2 $task.time
- Type:
$laneTime - Required: yes
- Purpose: the lane-time stamp. Encodes both the clock moment and the lane.
9.3 $task.kind
- Enum:
["alarm", "alert", "update"] - Required: yes
- Purpose: classifies the task.
alarmis reserved for the A0 global alarm lane (start, remaining-time warnings, time-up).alertis the standard course-lane prompt.updateis a passive state notification.
9.4 $task.course
- Type:
$course - Required: yes for alert/update; not used for alarm
- Purpose: which course this task belongs to. Schema's
conditional allOf branches enforce lane↔course consistency
(e.g.
lane: "M2"forcescourse: "main").
9.5 $task.lane
- Type:
$lane - Required: yes for alert/update
- Purpose: the lane label, redundant with the seconds component
of
time. Schema enforces consistency.
9.6 $task.action
- Type:
string(minLength 1) - Required: yes
- Purpose: the user-facing action sentence. Lexicon applies fully — rebel-chef voice, imperative, no UI verbs, no hedgers. Source typos are silently corrected here per source-content-handling rules.
9.7 $task.sound
- Type:
$sound - Required: optional
- Purpose: per-task sound override. When omitted, the lane's defaultSound applies.
9.8 $task.{ingredientRefs,equipmentRefs,utensilRefs,sundryRefs,processRefs}
- Type: arrays of corresponding ids
- Required: optional
- Purpose: structural references the task consumes. Closure rule applies — every ref must resolve to a declared entity of the matching type.
9.9 $task.completion
- Type:
$completion(oneOf 4 shapes — see Section 11) - Required: optional
- Purpose: optional sensory / temperature / compound completion cue describing what success looks like.
9.10 $task.timingBasis
- Type:
$timingBasis - Required: required for alert/update; not used for alarm
- Purpose: the audit trail justifying this task's time.
9.11 $process.id
- Type:
$processId - Required: yes
9.12 $process.label
- Type:
string(minLength 1) - Required: yes
- Purpose: short present-continuous noun phrase
(
"Boiling the spaghetti","Roasting the chicken"). Lexicon §3.6 caps at 3-5 words; phase qualifiers permitted. - Reference: → canonical-patterns.md §4
9.13 $process.course
- Type:
$course - Required: yes
9.14 $process.startTask
- Type:
$taskId - Required: yes
- Purpose: the task that begins this process.
9.15 $process.endTask
- Type:
$taskId - Required: yes
- Purpose: the task that ends this process. May reference a task on a different lane (cross-lane processes are conformant).
9.16 $process.duration
- Type:
objectwithtarget(required),min,max - Required: yes
- Purpose: ISO 8601 duration target. The interval between startTask.time and endTask.time (ignoring lane seconds) MUST equal duration.target per V-PROCESSES.
9.17 $process.temperature
- Type: array (≥ 1) of temperature-phase objects
- Required: optional
- Purpose: temperature schedule for ovens / hobs that change setting during the process.
$process.temperature[].value / .unit
- Type:
number/ enum["C", "F"] - Required: yes
$process.temperature[].fanValue / .gasValue
- Type: optional
- Purpose: preserve source's
180C/160C Fan/Gas 4notation.gasValueaccepts string for fraction-mark gas marks ("¼").
$process.temperature[].phase
- Enum:
["preheat", "cook", "rest"] - Required: yes
$process.temperature[].atOffset
- Type:
$isoDuration - Required: optional
- Purpose: offset from process startTask at which this temperature applies. Omit on the first phase.
9.18 $process.completion
- Type:
$completion - Required: yes
- Purpose: completion cue describing the process's success state.
Section 10 — $timingBasis
The audit trail for non-alarm tasks. Every alert/update task carries a timingBasis recording the kind of evidence used to choose the task's time and the source phrase that justifies it.
10.1 $timingBasis.basis
- Enum:
["sourceExactDuration", "sourceRangeMinimum", "sourceRangeTarget", "sourceCookTimeEndpoint", "sourceOrder", "sourceMeanwhile", "sourceOutcomeCue", "sourceImpliedDeadline", "canonicalProcessEstimate"] - Purpose: identifies the evidence kind. See rules.md I8 for the full evidence-table.
10.2 $timingBasis.source
- Type:
string(minLength 1) - Required: yes
- Purpose: the source phrase that justifies the chosen time.
For
canonicalProcessEstimate, a one-line professional-practice rationale.
10.3 $timingBasis.offsetFrom
- Type:
$taskId - Required: yes when basis is
sourceImpliedDeadline - Purpose: the consumer task whose deadline this prep task is deduced from.
10.4 $timingBasis.offset
- Type:
$signedIsoDuration - Required: yes when basis is
sourceImpliedDeadline - Purpose: the deduced prep duration as a negative offset from
the consumer task. Always negative (
-PT2M,-PT5M, etc.).
Section 11 — $completion (4 oneOf branches)
Completion cues describe outcome state. v3.2 distinguishes four completion types:
11.1 timed
- Shape:
{ type: "timed" } - Purpose: the process/task completes when its duration elapses. No sensory cue needed.
11.2 sensory
- Shape:
{ type: "sensory", modality, cue, confirm? } - Modality enum:
["visual", "aural", "tactile", "olfactory"] - Purpose: single-modality sensory completion.
- Reference: lexicon.md §6 sensory vocabulary
11.3 temperature
- Shape:
{ type: "temperature", target, unit, confirm? } - Unit enum:
["C", "F"] - Purpose: probe-driven completion (e.g. "until probe reads 52 °C for medium-rare beef").
11.4 compound
- Shape:
{ type: "compound", conditions: [{modality, cue}, ...], confirm? } - Purpose: multi-modality completion. Each condition is a modality+cue pair; the cue passes when ALL conditions are met.
11.5 confirm (used by sensory/temperature/compound)
- Enum:
["user", "auto"] - Required: optional
- Purpose: declares whether the user confirms completion or the app auto-detects (e.g. via probe).
Section 12 — Quantitative fingerprint and generation metadata
12.1 $quantitativeFingerprint.type
- Constant:
"strict"
12.2 $quantitativeFingerprint.basis
- Constant:
"ingredients-and-method-active-numbers"
12.3 $quantitativeFingerprint.normalization
- Constant:
"cookpit-active-number-sequence-v3.2.0" - Reference: → canonical-fingerprint-normalisation.md
12.4 $quantitativeFingerprint.sequence
- Pattern:
^[0-9]+(-[0-9]+)*$ - Purpose: the dash-separated active-number sequence extracted from the source per the published normalisation.
12.5 $quantitativeFingerprint.hash.algorithm
- Constant:
"sha256"
12.6 $quantitativeFingerprint.hash.value
- Pattern:
^[0-9a-f]{64}$ - Purpose: lowercase 64-hex SHA-256 of the sequence string.
12.7 $generation.profile
- Type:
string(minLength 1) - Purpose: the canonical generation profile name. Default value
for v3.2 files:
"cookpit-ai-canonical-v3.2".
12.8 $generation.idPolicy
- Constant:
"deterministic-type-prefixed-10-hex"
12.9 $generation.timingPolicy
- Constant:
"source-derived-deterministic-optimal"
12.10 $generation.resourcePolicy
- Constant:
"closed-world-declared-resources"
12.11 $generation.randomTimingAllowed
- Constant:
false
12.12 $generation.taskOrdering
- Constant:
"time-lane-id"
12.13 $generation.prepTiming
- Constant:
"pre-start-checklist"
12.14 $generation.lanePolicy
- Constant:
"fixed-primary-secondary-tertiary"
Section 13 — phaseBlock (the three-phase model)
The $phaseBlock $def is the shared shape used by cookpit.prepCook,
cookpit.preCook and cookpit.liveCook. Each phase is a
self-contained timed block with its own clock, lanes, tasks and
processes. The phase clock starts at 00:00:00 when the Chef app
begins the phase and runs to the phase's nominalDuration.
13.1 $phaseBlock.id
- Type: phase-specific id
- Required: yes for
prepCook($prepCookId,^y[0-9a-f]{10}$) andpreCook($preCookId,^z[0-9a-f]{10}$); ABSENT forliveCook(its identity is the file idcookpit.id). - Reference: → canonical-id-derivation.md §3.10–§3.12
13.2 $phaseBlock.label
- Type:
string(minLength 1) - Required: yes
- Purpose: short human label for the phase, e.g.
"belly press","cheek braise","final assembly cook". Drives the phase-id derivation for prepCook / preCook.
13.3 $phaseBlock.nominalDuration
- Type:
$duration(HH:MM:SS) - Required: yes
- Purpose: the phase's clock duration. The Chef app's per-phase A0 timer runs from 00:00:00 to this value. Drives the alarm rules (E1-E5) for tasks within the phase.
13.4 $phaseBlock.tasks
- Type:
array<task>(length ≥ 1) - Required: yes
- Purpose: the deduced timeline within the phase. Each task has a lane-time, kind, action sentence and timingBasis audit trail. Same shape as the v3.2 task definition.
- Reference: rules.md I
13.5 $phaseBlock.processes
- Type:
array<process> - Required: optional
- Purpose: ongoing background activities WITHIN the phase. Each
process's
startTaskandendTaskmust reference tasks declared in the SAME phase'stasks[](rules.md Q5). - Reference: rules.md J
13.6 $phaseBlock.completion
- Type:
$completion - Required: optional
- Purpose: sensory cue describing "phase complete" state. For liveCook this is the dish-on-plate cue. For preCook this is the cooked-component cue (e.g. "cheeks tender to a knife tip; meringue dry on top, soft within"). For prepCook it is the prep-done cue.
13.7 Phase composition reference
| File composition | Source signature |
|---|---|
| liveCook only | Single-arc recipe (≤ 90 min cook); the canonical default |
| preCook + liveCook | Cooked mainstay component before final assembly |
| prepCook + liveCook | Active timed prep window before cooking |
| prepCook + preCook + liveCook | Both — pork-fillet-braised-cheeks-and-pork-belly |
Runtime ordering: prepCook ⊥ preCook (independent — chef may
run them concurrently or sequentially); liveCook ≻ both (strictly
downstream — runs only after the LAST upstream phase fires its A0
time-up). liveCook never overlaps the upstream phases. See
rules.md Q4 and canonical-patterns.md §8.6.
→ canonical-patterns.md §8 documents each composition with active-corpus examples.
Section 14 — $recipeInstructionItem (schema.org pass-through)
The recipeInstructions[] array uses one of three shapes per item:
14.1 Plain string
- Purpose: free-text method step.
14.2 HowToStep object
- Shape:
{ "@type": "HowToStep", "name"?, "text"?, "url"? } - Purpose: schema.org structured method step.
14.3 HowToSection object
- Shape:
{ "@type": "HowToSection", "name"?, "itemListElement": [...] } - Purpose: schema.org grouped method section.
Section 15 — $quantityValue
Used wherever a number-or-range is acceptable.
15.1 Number form
- Type:
number - Purpose: a single value.
15.2 Range form
- Type:
objectwith requiredminandmaxnumbers - Purpose: a closed range when the chef-detective wants to preserve range semantics structurally rather than collapsing to a single value.
Section 16 — attestation lifecycle block
The attestation $def is a discriminated object whose shape depends on
status. AI Chef output (stage 1) carries the unauthenticated form;
the canonical validator's stage-3 output replaces it with the
authenticated form. The two forms share the same JSON path
(cookpit.attestation) but carry different field sets.
→ rules.md R for the full lifecycle contract. → rules.md A0.6 for the distinction between this file fingerprint and the source fingerprint at §12.
16.1 $attestation.status
- Constant set:
"unauthenticated"|"authenticated" - Purpose: the discriminator. Drives which sub-fields are required.
- Reference: rules.md R1, R2, R3
16.2 Unauthenticated form (stage 1)
- Required fields:
status: "unauthenticated"only. - Forbidden fields:
signature,fileFingerprint,issuer,keyId,validatorVersion,issuedAt,canonicalization. - Optional:
selfReportedsub-object (rulesSelfChecked: bool,validatorRun: bool, etc.). - Reference: rules.md R2, R4
16.3 Authenticated form (stage 3)
- Required fields:
status: "authenticated",issuer,validatorVersion,issuedAt,canonicalization,keyId,fileFingerprint,signature. - Optional:
auditsub-object holding the validator's report summary (hardFailures,softWarnings,infos). - Reference: rules.md R3, R5, R6
16.4 $attestation.issuer
- Type:
string(URI) - Purpose: canonical validator endpoint URL, e.g.
"https://cookpit.spec/v3.2/validate". Consumers pin this value. - Reference: rules.md R3
16.5 $attestation.validatorVersion
- Type:
string(minLength 1) - Purpose: exact version string of the validator that issued the stamp. Consumers may enforce a minimum acceptable version.
- Reference: rules.md R3, R6
16.6 $attestation.issuedAt
- Type:
string(ISO 8601 timestamp) - Purpose: time of stamping.
- Reference: rules.md R3
16.7 $attestation.canonicalization
- Type:
string - Default:
"RFC8785"(JSON Canonicalisation Scheme) - Purpose: name of the canonicalisation profile used to compute the file fingerprint and the signed payload. Consumers MUST use the same profile when re-canonicalising for verification.
- Reference: rules.md R5
16.8 $attestation.keyId
- Type:
string(minLength 1) - Purpose: identifier of the public key used to sign. Lets a consumer pick the right key from a multi-key set published by the validator (e.g. across key-rotation overlap windows).
- Reference: rules.md R3, R6
16.9 $attestation.fileFingerprint
- Type:
string - Pattern:
^[0-9a-f]{64}$ - Purpose: lowercase 64-hex SHA-256 of the canonicalised file body
with
cookpit.attestation.signaturecleared (see rules.md R5). This is the file fingerprint introduced at stage 3 — the integrity-bound identifier for the exact stamped file. Consumers recompute it on load and reject any mismatch. - Reference: rules.md R5, validation.md V-FILE-FINGERPRINT
16.10 $attestation.signature
- Type:
string - Purpose: cryptographic signature over the canonical bytes
produced by R5, base64-encoded. Consumers verify with the public
key resolved by
keyId. - Reference: rules.md R6, validation.md V-SIGNATURE
16.11 $attestation.audit
- Type:
object(optional) - Purpose: validator report summary, included for tamper-evident forensic context. The signature covers the audit object so that audit data is immutable post-stamp, even though it is not the primary trust signal.
- Reference: rules.md R3
16.12 Filename flag (decorative)
The filename's <status> segment is A when status is
authenticated and U otherwise (rules.md O1). The flag is
decorative; the load-bearing trust signal is the cryptographic
binding (fileFingerprint + signature against pinned key).
Filename / internal-status disagreement is a hard validation failure
(V-ATTESTATION-CONSISTENCY).
Cross-reference index
| Topic | Authoritative document |
|---|---|
| Persona & rebel-chef voice | bundle/v3.2/lexicon.md §0 |
| Detective deductive method | bundle/v3.2/prompt.md |
| Numbered rules A0–R | bundle/v3.2/rules.md |
| Lifecycle (4 stages) | bundle/v3.2/rules.md §A0 |
| Attestation block | bundle/v3.2/rules.md §R, glossary §16 |
| Validation criteria | bundle/v3.2/validation.md |
| Canonical id derivation | bundle/v3.2/canonical-id-derivation.md |
| Active-number-sequence rules | bundle/v3.2/canonical-fingerprint-normalisation.md |
| Source-content categorisation | bundle/v3.2/source-content-handling.md |
| Unit vocabulary | bundle/v3.2/canonical-units.md |
| Concurrency / lane / leadTime patterns | bundle/v3.2/canonical-patterns.md |
| Filename pattern (incl. A/U) | bundle/v3.2/canonical-patterns.md §6, rules.md O |
| Executable validator | scripts/validate_cookpit_v3.2.py |
| Schema (executable contract) | schema/cookpit-cooking-file-v3.2.json |
Conformance
A v3.2 file is conformant when:
- It validates against
schema/cookpit-cooking-file-v3.2.json(Draft 2020-12). - It satisfies every rule in
rules.mdA0 through R. - Its ids are derivable per
canonical-id-derivation.md. - Its source quantitative fingerprint is computable per
canonical-fingerprint-normalisation.md. - Every hard criterion in
validation.mdpasses when checked byscripts/validate_cookpit_v3.2.py.
A v3.2 file is authenticated when, in addition to being
conformant, it has been processed through stage-3 attestation by the
canonical validator (rules.md R), carries the authenticated
attestation block, and verifies under V-FILE-FINGERPRINT and
V-SIGNATURE. Authenticated files use the A filename flag;
unauthenticated files use U (rules.md O1).
Soft criteria are advisory; soft warnings do not break conformance but should drive prompt refinement, source-PDF cleanup, or schema follow-up.
This glossary indexes every field. If a field is in the schema, it is in this glossary.