# description
v3.2 is the optimal, source-faithful, closed-world recipe plan: optimal in its timings for the dish's outcome, closed under the resources it declares, and static once generated. The Chef app is responsible for runtime time-and-progress management against this fixed plan. v3.2 is a clean-slate format with no backward compatibility to earlier versions.

# properties.@context.description
JSON-LD context. Must include schema.org and a cookpit namespace mapping.

# properties.@type.description
Must declare both Recipe (schema.org) and cookpit:CookingFile.

# $defs.cookpit.description
The cookpit extension block. Holds the v3.2 cooking-plan content. v3.2 organises the plan into up to three sequential phases: prepCook (optional active timed prep), preCook (optional cooking of mainstay components), and liveCook (required final-assembly cook ending in serving). Each phase is a self-contained timed block with its own clock, lanes, tasks and processes; the file-level prerequisites are confirmed once at file start before any phase begins.

# $defs.cookpit.properties.version.description
Cookpit cooking-file format version. Must be 3.2.x for this schema.

# $defs.cookpit.properties.sourceTiming.description
Source recipe timing facts, preserved verbatim from the source.

# $defs.cookpit.properties.prepCook.description
Optional active timed prep phase. Used when the source recipe contains TIMED multi-task prep with stated durations — pressing meat under weights, salt-curing, marinating with active monitoring, mise that genuinely takes long enough to warrant a runtime timer rather than a checklist confirmation. The Chef app starts the prepCook timer after the file-level prerequisites are confirmed and before preCook (if present) or liveCook. Carries its own id (y…), label, nominalDuration, tasks[], processes[] and completion cue. Lane model is reused with phase-local clock starting at 00:00:00.

# $defs.cookpit.properties.preCook.description
Optional pre-cook phase for cooked components that become mainstays of the final dish (the cheeks that go on the plate, the meringue base, the salmon fillet that gets shredded into the pâté). Internal lane concurrency handles parallel processes (cheeks on M1, confit on M2 within preCook). The Chef app starts the preCook timer after prepCook ends (or after file-level prereqs if no prepCook) and before liveCook. Carries its own id (z…), label, nominalDuration, tasks[], processes[] and completion cue.

# $defs.cookpit.properties.liveCook.description
Required final-assembly cook phase ending in serving. The dish reaches the plate at liveCook time-up. No id field — the file's id (cookpit.id, f…) IS the liveCook's identity; the file is the live cook. Carries label, nominalDuration, tasks[], processes[] and completion cue with the same shape as prepCook and preCook.

# $defs.cookpit.properties.attestation.description
Lifecycle-attestation block. Carries either the stage-1 unauthenticated marker (AI Chef output, before validation) or the stage-3 authenticated attestation issued by the canonical validator. The attestation block — not the filename — is the load-bearing trust signal at stage-4 consumption. See bundle/v3.2/rules.md §R for the full normative contract and bundle/v3.2/validation.md V-ATTESTATION-* / V-FILE-FINGERPRINT / V-SIGNATURE for the validator's per-criterion behaviour. Optional in the JSON Schema for backward compatibility with the existing corpus; the bundle's section R requires its presence at every lifecycle stage and the validator enforces that requirement at run time.

# $defs.cookpit.properties.dietary.description
Optional dietary tag set, drawn from the v3.2.0 published vocabulary. Source recipes routinely tag dietary attributes ('Egg-free Nut-free Pregnancy-friendly', 'Vegetarian', 'Dairy-free') in their headers; this field captures them structurally for downstream filtering, allergen audit, and shopping-list integration. The Chef app uses these tags directly. Sources that don't tag dietary attributes leave this field absent.

# $defs.signedIsoDuration.description
ISO 8601 duration, optionally negative. Negative durations are used by sourceImpliedDeadline to record prep duration relative to the deadline task (e.g. -PT2M).

# $defs.laneTime.description
HH:MM:SS.LANE timestamp where LANE is one of A0, S1..S3, M1..M3, D1..D3. The seconds component must match the lane (enforced via task.if/then).

# $defs.laneModel.description
Fixed primary/secondary/tertiary course lanes block. Structure must match section 6 of the v3.2 spec exactly.

# $defs.prerequisiteItem.properties.equipmentRefs.description
Optional structural references to equipment items consumed by this prerequisite (e.g. a knife or board used during pre-cook prep). Recognised by V-REFS-COVERAGE as a legitimate consumer.

# $defs.prerequisiteItem.properties.utensilRefs.description
Optional structural references to utensils consumed by this prerequisite. Recognised by V-REFS-COVERAGE as a legitimate consumer.

# $defs.prerequisiteItem.properties.sundryRefs.description
Optional structural references to sundries consumed by this prerequisite. Recognised by V-REFS-COVERAGE as a legitimate consumer.

# $defs.phaseBlock.description
Shared shape for a v3.2 cooking phase (prepCook, preCook, liveCook). Each phase carries its own label, nominalDuration, lane-keyed timeline (tasks[]) and process roster (processes[]), and an optional completion cue describing what 'phase done' looks like. The phase clock starts at 00:00:00 when the Chef app begins the phase. Tasks reference the phase's local clock; lane assignments use the same fixed lane model as the file. The id field is phase-specific and added by the per-phase wrapper (prepCook → y…, preCook → z…, liveCook borrows the file's f… id).

# $defs.phaseBlock.properties.id.description
Phase id. Added by the per-phase wrapper schema. liveCook omits this field — its identity is the file id.

# $defs.phaseBlock.properties.label.description
Short human label for the phase, e.g. 'belly press', 'cheek braise', 'final assembly cook'.

# $defs.phaseBlock.properties.nominalDuration.description
Phase clock duration (HH:MM:SS). The Chef app's per-phase timer runs from 00:00:00 to this value.

# $defs.phaseBlock.properties.completion.description
Optional sensory cue describing 'phase complete' state. For preCook this is typically the cooked-component cue ('cheeks tender to a knife tip; meringue dry on top, soft within'); for liveCook this is the dish-on-plate cue.

# $defs.ingredient.properties.alternative.description
Optional source-stated substitute, preserved verbatim from the source recipe. Use when the source explicitly offers a primary form with a fallback (e.g. 'vanilla pod, or vanilla extract'). For 'any of these works' equivalents, use choices[] instead.

# $defs.ingredient.properties.choices.description
Optional source-stated equivalents — a set of same-role choices the chef may pick from. Distinct from 'alternative' (which is primary + single fallback). Use when the source offers a list of equally valid options (e.g. 'cod, haddock or pollock'; 'pearl onions or 24 baby onions'; 'chicken or pork stock'). Each choice carries its own quantity+unit pair; the chef picks one.

# $defs.ingredient.properties.splits.description
Optional partitioning of this ingredient across multiple tasks at distinct fractions. Each split is a usage record: a sub-portion id, the fraction of the parent ingredient it represents, and the task that consumes it. Tasks reference the split id (still an i… id) just like a primary ingredient; the closure rule treats each split as a valid consumption of the parent. Use this for 'three-quarters for the mash, the remaining quarter for the topping'-style partitioning that source recipes routinely express in prose.

# $defs.ingredient.properties.splits.items.properties.fraction.description
Fraction of the parent ingredient (0 < f <= 1). Splits within a single ingredient should sum to ≤ 1.0; the validator emits a soft warning when they sum to materially less or more than 1.0.

# $defs.ingredient.properties.splits.items.properties.label.description
Optional short label for the split (e.g. 'mash portion', 'reserved for topping').

# $defs.ingredient.properties.splits.items.properties.usedBy.description
Optional taskId pointer indicating where this split is consumed; if omitted, the consumer is inferred from task ingredientRefs.

# $defs.ingredient.properties.extras.description
Optional 'plus extra for X' annotations. Source recipes routinely list a primary quantity plus an unspecified additional amount for a secondary purpose ('120g unsalted butter, plus extra for greasing'). Each extras entry records the purpose; quantity and unit are optional. The Chef app surfaces extras in the shopping list and pre-cook prep prompts.

# $defs.ingredient.properties.extras.items.properties.purpose.description
Short phrase describing the extra's purpose (e.g. 'greasing the dish', 'finishing the salmon', 'topping up the braise').

# $defs.ingredient.properties.depth.description
Optional fill-to-depth specification for ingredients added by depth rather than volume. Used for deep-frying ('5cm/2in vegetable oil to a wok') where the wok size determines actual volume. Carries a value, a unit (cm or inch), and an optional vesselRef pointing at the equipment whose geometry determines actual volume.

# $defs.ingredient.properties.depth.properties.vesselRef.description
Optional reference to the equipment item whose geometry determines actual volume.

# $defs.equipment.properties.choices.description
Optional source-stated equipment equivalents — e.g. 'deep fryer or deep saucepan', 'large frying pan or wok'. Each choice is a same-role substitute the chef may pick from.

# $defs.process.properties.temperature.description
Optional temperature schedule for the process. Most processes carry a single phase ('cook' at one temperature). Multi-phase processes (pavlova preheat→drop→hold; pork three ways confit→raise→roast) declare each phase explicitly. Phase semantics: 'preheat' is the oven coming up to temperature before the cook starts (typically a prereq.equipment fact, but may be embedded here for processes that drive a phase change); 'cook' is the live cooking phase; 'rest' is post-bake holding at residual heat. The Chef app surfaces the schedule as 'oven goes from <T1> to <T2> at <time>'.

# $defs.process.properties.temperature.items.properties.fanValue.description
Optional °C value for fan oven (preserves source's '180C/160C Fan' notation).

# $defs.process.properties.temperature.items.properties.gasValue.description
Optional gas-mark value (e.g. 4 for gas mark 4, '¼' for gas mark ¼). String allows for fraction marks.

# $defs.process.properties.temperature.items.properties.atOffset.description
Optional offset from process startTask at which this temperature applies. Omit on the first phase.

# $defs.quantitativeFingerprint.description
Stage-1 source fingerprint: a strict active-number summary of the SOURCE recipe's numeric content. The AI populates it at generation; the validator re-checks it at stage 2 (V-FINGERPRINT-B). Distinct from the stage-3 file fingerprint at cookpit.attestation.fileFingerprint, which hashes the cooking file body. See rules.md A0.6 and bundle/v3.2/canonical-fingerprint-normalisation.md.

# $defs.attestation.description
Lifecycle-attestation block. The `status` discriminator selects between the unauthenticated form (stage-1 AI Chef output) and the authenticated form (stage-3 canonical-validator output). See rules.md §R.

# $defs.attestationUnauthenticated.description
Stage-1 unauthenticated attestation form. The AI Chef MUST emit this exact shape; it MUST NOT carry any authenticated-only fields (signature, fileFingerprint, issuer, keyId, validatorVersion, issuedAt, canonicalization). The validator rejects malformed claims at V-LIFECYCLE-AI-EMITS-U.

# $defs.attestationUnauthenticated.properties.selfReported.description
Optional advisory data the AI may report about its own self-checks. Not a trust signal; the validator does not consume it for verdict purposes.

# $defs.attestationAuthenticated.description
Stage-3 authenticated attestation form. Issued by the canonical validator after a hard-pass verdict. The signature covers the canonicalised file body with `signature` cleared, per rules.md R5/R6.

# $defs.attestationAuthenticated.properties.audit.description
Validator report summary, included for tamper-evident forensic context. The signature covers this object so audit data is immutable post-stamp.