Restaurant Food Image Studio
Turn mixed real restaurant snapshots into a small, coherent website photography set. Use the real photo as the factual authority for the dish. Use the restaurant Photography System as the authority for camera angle, composition, light, background, color, crop and customer-facing presentation.
Do not preserve a weak source angle merely because it is real. When an overhead, cluttered or inconsistent snapshot does not fit the website system, use reference-restage to present the same dish from the locked customer-facing camera. Never let the restage change the dish facts.
Read references/food-image-playbook.md before collecting, planning, prompting, generating or reviewing. Copy the bundled Manifest V3 and Style Lock structures instead of inventing a work order.
Choose The Mode
- Collect: Retrieve real single-restaurant candidates and save provenance.
- Audit: Verify restaurant identity, dish visibility, source angle and restaging risk. Do not generate.
- Create: Lock one Photography System, route each source, generate one designed photo per real source and retain timing.
- Repair: Regenerate from the real source and locked Photography System after diagnosing a failed gate.
- Review: Retain the canonical source/output artifact and all five QA decisions automatically.
Let $restaurant-demo-builder establish the business evidence, audience, website layout and image slots for a complete Demo. Use this Skill for the food photography system and assets.
Keep Evidence Review Non-Blocking
Treat canonical candidate, source and source-versus-output sheets as automatic evidence records, not approval requests. Once a canonical source sheet exists, record every eligible source with status: recorded, reviewer: workflow, validate the generate stage and continue to image generation without waiting for the user. After output QA, record the canonical comparison the same way and continue to the private-Demo gate.
Stop only when evidence or validation fails, a current changes-requested record exists, the source cannot truthfully support the proposed image, or the user explicitly asks the current run to pause. Human inspection remains available later and may create changes-requested; it is never a prerequisite for generation. Keep owner factual confirmation and publication rights as separate launch gates.
Enforce The Manifest V3 Contract
Require every Demo food image to satisfy all of these rules:
- Bind exactly one unique
served-dish-photovisual primary from the same restaurant. - Save the untouched source locally with platform identity, original URL and SHA-256.
- Supply that real source to imagegen. Never use prompt-only food generation.
- Record
source_assessment.camera_view, customer-facing fit and hidden-detail risk. - Complete one restaurant-level
photography_systembefore generation. - Use
constrained-editonly when the source already fits that system. - Use
reference-restagewhen the camera, composition or customer-facing presentation must change. - Block angle-changing restages with high hidden-detail risk until another real view is available.
- Accept a corroborating view only when it is another live-audited
served-dish-photofrom the same restaurant with an exact same-dish match record. - Record a per-dish transformation plan and permitted appetite adjustments.
- Record imagegen start, completion and duration.
- Fully decode the output, record its real width and height, and verify its pixel ratio against the Photography System.
- Pass the five separate gates: fidelity, style consistency, appetite optimization, AI tells and website readiness.
- Save the canonical real-source and source-versus-designed-photo artifacts.
- Pass the Manifest
demostage before copying the output into a website.
If no credible real dish photo exists, keep the slot text-led, use a separately cleared non-food image, choose another photographed dish or request an owner photo.
Treat an owner photo as a future acquisition candidate, not a visual primary, until it has an implemented collector record, complete pixel decode, canonical candidate sheet and candidate audit equivalent to Apify/Masa. Manifest V3 currently admits only audited Apify Google Maps and Masa photos as visual primaries.
Prepare The Work Order
Create output/food-image-studio/<restaurant-slug>/ with sources/, prompts/, drafts/, selected/ and review/. Use:
- assets/image-manifest-template.json for
image-manifest.json. - assets/style-lock-template.md for
style-lock.md.
Use lowercase ASCII file names. Never put API tokens, private keys or account secrets in these files.
In commands, resolve <food-image-skill> from this Skill's available-skill locator.
Collect Real Dish References
Run the collector only for the selected restaurant:
APIFY_TOKEN=... python3 <food-image-skill>/scripts/collect_real_references.py apify \
--place-id <google-place-id> \
--max-images 20 \
--output-dir <work-order>
python3 <food-image-skill>/scripts/collect_real_references.py masa \
--store-id <masa-store-id> \
--item-name <exact-menu-item-name> \
--output-dir <work-order>
For a Maps URL, also supply the independently known Place ID; the returned record must match it:
APIFY_TOKEN=... python3 <food-image-skill>/scripts/collect_real_references.py apify \
--maps-url <exact-google-maps-place-url> \
--expected-place-id <google-place-id> \
--output-dir <work-order>
The collector fully decodes JPEG, PNG and WebP pixels and rejects sources below a 300 px short edge or 150,000 total pixels. It requires Apify to return the locked Place ID and Masa to return the requested StoreID in the response or menu-item context. It never treats the requested identifier alone as evidence.
Offline JSON imports are reproducible audit material only. They retain their input hash and offline-audit-only tier, but cannot be promoted or enter a Demo.
Record The Independent Candidate Audit
Render the canonical unclassified-candidate sheet:
python3 <food-image-skill>/scripts/make_candidate_sheet.py \
--source-index <work-order>/source-index.json \
--out <work-order>/review/candidate-sources.svg
Inspect every local candidate with view_image and the retained sheet. Reject screenshots, menus, placeholders, stock imagery, synthetic imagery, obscured food and wrong listings. Record the classification as an automatic audit step; do not pause for user approval:
python3 <food-image-skill>/scripts/record_candidate_review.py \
--source-index <work-order>/source-index.json \
--candidate-sheet <work-order>/review/candidate-sources.svg \
--candidate-id <candidate-id> \
--out <work-order>/review/<candidate-id>.json \
--status recorded \
--reviewer workflow \
--classification served-dish-photo \
--restaurant-match verified \
--restaurant-match-notes <identity-evidence> \
--dish-visibility served-dish-visible \
--visual-notes <visible-served-dish-evidence> \
--notes <audit-summary>
The audit record locks the candidate ID, untouched source hash, source-index hash, canonical candidate-sheet hash, reviewer, timestamp, classification and visual findings. Record non-food candidates under their real classification and do not promote them. A later changes-requested record immediately blocks promotion and Demo validation.
Assess The Snapshot Before Choosing A Mode
Record the source camera view as overhead, near-overhead, three-quarter, low-angle, straight-on or unknown. Then record:
fit: the source already matches the Photography System; allowconstrained-edit.restage-required: the dish is factual but the angle or composition is not customer-facing; requirereference-restage.unusable: the food is too obscured or uncertain; block generation.
Do not call an overhead snapshot fit when the locked customer-facing system is three-quarter tabletop. The Sake Sushi failure is the canonical anti-pattern: a real overhead source cannot pass merely because an edit keeps the same overhead composition.
The validator enforces camera-family compatibility. overhead and near-overhead sources cannot be marked fit for three-quarter-tabletop, low-tabletop or straight-on; incompatible views must be restage-required, set angle_change_required: true and use reference-restage.
Promote one candidate per proposed output:
python3 <food-image-skill>/scripts/promote_candidate.py \
--source-index <work-order>/source-index.json \
--candidate-review <work-order>/review/<candidate-id>.json \
--manifest <work-order>/image-manifest.json \
--candidate-id <candidate-id> \
--dish-id <dish-id> \
--dish-name <dish-name> \
--restaurant-name <restaurant-name> \
--restaurant-slug <restaurant-slug> \
--location <location> \
--google-place-id <place-id> \
--dish-match-status <exact-or-category-only> \
--dish-match-notes <name-or-category-evidence> \
--source-camera-view overhead \
--customer-facing-fit restage-required \
--hidden-detail-risk medium \
--composition-notes <why-the-snapshot-needs-restaging> \
--angle-change-required yes \
--generation-mode reference-restage
Use --masa-store-id instead of --google-place-id for Masa.
Promotion accepts only a current recorded / audit-record classified as served-dish-photo from a live-verified collection. It copies the complete original provenance and source metadata into the Manifest. The source-index and candidate-review files remain hash-bound and are revalidated at every later stage.
Treat live-verified as workflow-attested evidence, not a cryptographic signature from Apify or Masa. Someone with write access to the work order can edit local JSON and recompute local hashes. When provenance is disputed or before a public launch depends on that asset, rerun the live provider collection, compare the returned restaurant identity and image hash, or replace it with a cleared owner asset that has passed a future owner-ingestion audit. Never describe the local chain as tamper-proof.
Lock One Designed Photography System
Complete both the structured photography_system and style-lock.md before generation. Lock one primary camera family for the restaurant set, normally a repeatable three-quarter-tabletop system around 35–45 degrees for customer-facing casual food photography. Record an angle tolerance no wider than 15 degrees.
Lock all of these variables:
- target angle, camera height, lens feel and subject scale;
- aspect ratio, crop and website negative space;
- surface, background family and prop restraint;
- light direction, light quality and shadow character;
- exposure, white balance, saturation and contrast;
- appetite treatment and acceptable real imperfections;
- the natural cues required to avoid an AI-rendered look.
Use one primary camera family across the set. Do not alternate casually between overhead, straight-on and three-quarter images.
Plan Truthful Appetite Optimization
Record dish-specific adjustments before prompting. Allow only improvements supported by the source:
- modestly raise exposure and correct white balance;
- make existing bread or crust naturally warmer and more golden;
- clarify an existing sear, crisp edge, vegetable color or sauce sheen;
- clean distracting background details and improve plate placement;
- preserve ordinary service variation, uneven cuts and source asymmetry.
Do not invent browning, grill marks, garnish, ingredients, sauce, steam, portion, vessel or luxury plating. “More appetizing” is a presentation goal, not permission to redesign the food.
Record The Source Artifact Automatically
Require the structured Photography System, Style Lock and every transformation plan to be complete before creating the source sheet:
python3 <food-image-skill>/scripts/validate_manifest.py \
--manifest <image-manifest.json> \
--stage plan
Then create and retain the canonical source sheet and record it without pausing:
python3 <food-image-skill>/scripts/make_contact_sheet.py \
--manifest <image-manifest.json> \
--stage source \
--out <work-order>/review/source-review.svg
python3 <food-image-skill>/scripts/record_review.py \
--manifest <image-manifest.json> \
--dish-id <dish-id> \
--gate source \
--status recorded \
--reviewer workflow \
--notes <source-angle-route-and-evidence-notes>
Do not pause after rendering the sheet. Record every eligible source automatically, replace all prompt TODO markers, require validate_manifest.py --stage generate, and proceed directly to imagegen when validation passes.
Generate The Designed Photo
Use $imagegen. Supply the visual primary in every call and add real corroborating views when hidden detail risk requires them. In every prompt:
For every corroborating ID, record source_assessment.supporting_source_matches.<source-id> with status: exact and specific same-dish notes. Include only those audited real views after the visual primary in output.input_source_ids; menu documents, venue photos, stock and synthetic images cannot satisfy hidden-detail risk.
- Name the source ID and
constrained-editorreference-restage. - Name the target camera family and target angle explicitly.
- Treat the real source as dish truth and the Photography System as presentation truth.
- Repeat verified food facts, counts, portion, sides, sauce, doneness and vessel.
- Describe only the planned composition and appetite improvements.
- Preserve real irregularities and ordinary independent-restaurant presentation.
- Ban plastic gloss, waxy texture, repeated geometry, perfect symmetry, malformed edges, fake effects, text and logos.
- Make one call per asset and save the result non-destructively.
Do not use a previous AI output as another dish's factual source. It may guide light or framing only.
Run Five Separate QA Gates
Inspect the source and output at useful size. Record each gate independently:
fidelity: confirm the same dish facts and serving logic.style_consistency: confirm camera family, angle tolerance, scale, crop, surface, light and grade.appetite_optimization: confirm the planned brightness, color, browning and cleanup improved the food without changing facts.ai_tells: reject plastic shine, repetition, impossible effects, malformed geometry and synthetic rendering cues.website_readiness: confirm aspect ratio, useful crop, negative space, no baked-in text and consistency with the set.
Register the result and exact imagegen timing:
python3 <food-image-skill>/scripts/register_output.py \
--manifest <image-manifest.json> \
--dish-id <dish-id> \
--output <selected-image> \
--camera-family three-quarter-tabletop \
--angle-degrees 40 \
--aspect-ratio 4:3 \
--generation-started-at <ISO-8601> \
--generation-completed-at <ISO-8601> \
--fidelity-status passed --fidelity-note <note> \
--style-consistency-status passed --style-consistency-note <note> \
--appetite-optimization-status passed --appetite-optimization-note <note> \
--ai-tells-status passed --ai-tells-note <note> \
--website-readiness-status passed --website-readiness-note <note>
Register failed outputs too. The review stage may retain a failed comparison, but the demo stage rejects any non-passing gate.
The registrar fully decodes JPEG, PNG or WebP pixels, saves the decoded width and height, and rejects a real pixel ratio that differs from the Photography System by more than 1.5%. Editing the recorded dimensions or replacing the file makes later validation fail.
Retain The Comparison And Release
Create the canonical source-versus-designed-photo sheet and record it automatically:
python3 <food-image-skill>/scripts/make_contact_sheet.py \
--manifest <image-manifest.json> \
--stage review \
--out <work-order>/review/source-vs-output.svg
python3 <food-image-skill>/scripts/record_review.py \
--manifest <image-manifest.json> \
--dish-id <dish-id> \
--gate output \
--status recorded \
--reviewer workflow \
--notes <five-gate-summary>
Run validate_manifest.py --stage demo immediately before website integration. Canonical SVGs are regenerated from the current Manifest and compared byte-for-byte. Any changed source, output, route, Photography System, prompt, timing, presentation or QA data invalidates the prior record.
Treat recorded as automatic evidence retention, not human approval. Do not wait for a human decision before generation or private-Demo integration. Let a later changes-requested decision block the asset. Keep owner_confirmation and publication_status separate. Require owner accuracy confirmation and cleared rights or replacement assets before public launch.
Handoff
Report the source index, untouched sources, Manifest, Photography System, Style Lock, source sheet, prompts, selected outputs, generation timing, five QA results, comparison sheet, current validation stage and publication blockers. Do not publish or contact the restaurant without explicit authorization.