Skip to content

Goldie's Food Discovery - Build Handoff

This document contains everything needed to build the Goldie Food Discovery system from scratch. It should be handed to a Claude Code agent who will execute the build. The agent should read this entire document before starting, then work through it sequentially.

Build Progress

Step Status Notes
1. Repo structure Done All directories and .gitkeep files created
2. CLAUDE.md Done Implemented exactly as specified
3. /inbox command Done .claude/commands/inbox.md created
4. Tracker files Done foods.md and allergens.md initialised with empty tables
5. learnings.md Done Created with empty sections
6. site/index.html Done "Story" concept - children's book journal aesthetic. Light-mode only (no dark mode). Italic serif headings, coral accent, warm cream background. Deployed to surge for preview.
7. Cloudflare Worker Done Deployed to goldie-food-worker.halsarj.workers.dev. Whisper v3-turbo needs base64 audio (not number array). Worker code at ~/goldie-food-worker/.
8. Cloudflare Pages Done Live at goldie-food.pages.dev. Auto-deploys from main. Connected to HalSarj/goldie-food repo, build output: site/.
9. iPhone Shortcut Done Simplified to 3 actions (Record Audio, POST to worker, Show Notification). No offline queue - iCloud storage was full so queue approach didn't work. Added apple-touch-icon for Home Screen.
10. End-to-end test Done Full pipeline tested: iPhone shortcut -> worker transcription -> GitHub inbox -> /inbox processing -> diary + trackers + site updated -> Cloudflare Pages auto-deploy. First real entry: broccoli, 14 Feb 2026.

Design decisions made: - "Story" concept chosen over 5 other options (Today, Timeline, Fridge Door, Garden, Magazine) via interactive design playground - Light-mode only - storybook aesthetic needs warm cream paper, dark mode removed - Colour palette: warm off-white (#fefcf9), coral accent (#e8806e), warm grey-plum text (#4a4044), rosy muted tones - Georgia serif for headings/narrative, system sans-serif for labels - Preview: https://k7m2x9fp-hal.surge.sh

Temporary files to clean up before committing: - site/design-playground.html (colour picker - no longer needed) - site/design-concepts.html (concept explorer - no longer needed)

Deployment details: - Cloudflare account: Hal_sarjant@hotmail.com - Worker URL: https://goldie-food-worker.halsarj.workers.dev - Site URL: https://goldie-food.pages.dev - Worker secrets: SHARED_SECRET, GITHUB_PAT, GITHUB_OWNER (HalSarj), GITHUB_REPO (goldie-food) - Worker code lives at ~/goldie-food-worker/ (separate from main repo)

Build issues encountered and resolved: - Whisper v3-turbo requires base64-encoded audio, not a number array (caused error 1101). Fixed by importing Buffer from node:buffer and encoding with .toString('base64'). - iPhone Shortcut queue approach failed because iCloud storage was full. Save File action failed silently, Get Contents of Folder returned nothing, notification showed anyway. Simplified to direct POST without local queue. - Cloudflare dashboard "Create application" defaults to Worker, not Pages. Need to click "Looking to deploy Pages? Get started" link at the bottom instead.

What You're Building

A voice-first baby food diary and weaning companion. The user (Leanne, a new mum) records voice notes after feeding her baby (Goldie). The system transcribes the audio, stores it in a GitHub repo, and a Claude Code enrichment layer processes it into a structured food diary with intelligent suggestions. The diary is displayed on a beautiful mobile-first HTML page.

The users: - Leanne (Hal's wife) - records voice notes on her iPhone 12 mini, browses the site on her phone. Non-technical. Never touches GitHub or CLI. - Hal - runs /inbox in Claude Code once daily to process new entries. Manages the system.

Architecture

iPhone 12 mini (Home Screen shortcut - record - upload)
        |
Cloudflare Worker (transcribe via Whisper - commit to GitHub)
        |
GitHub private repo: goldie-food (inbox/ folder)
        |
Hal runs /inbox in Claude Code (daily)
        |
Claude Code: process transcript - update diary - update trackers - update HTML content blocks
        |
git push triggers Cloudflare Pages auto-deploy
        |
Leanne browses site/index.html on her phone

Build Order

  1. Create GitHub repo with file structure and all content files
  2. Write CLAUDE.md
  3. Write the /inbox command
  4. Create tracker files (foods.md, allergens.md)
  5. Create learnings.md
  6. Design and build site/index.html
  7. Deploy Cloudflare Worker for transcription
  8. Set up Cloudflare Pages for site hosting
  9. Build iPhone Shortcut
  10. End-to-end test

Step 1: GitHub Repo Structure

Create a private GitHub repo called goldie-food with this structure:

goldie-food/
├── CLAUDE.md
├── learnings.md
├── inbox/
│   └── .gitkeep
├── diary/
│   └── .gitkeep
├── tracker/
│   ├── foods.md
│   └── allergens.md
├── site/
│   └── index.html
└── .claude/
    └── commands/
        └── inbox.md

Step 2: CLAUDE.md

This is the brain of the system. It tells Claude Code how to behave when processing inbox files.

# Goldie's Food Discovery

You are a weaning companion for Goldie. Your job is to process voice note
transcripts about Goldie's meals, maintain a structured food diary, track
allergen introduction, and provide practical suggestions for upcoming meals.

Your guidance is based on Ella's Kitchen "The First Foods Book" framework,
which Leanne (Goldie's mum) is following.

## Who Goldie Is

- Born August 2025
- Started weaning 14 February 2026 (first food: blended broccoli with breast milk)
- Lives in north London with mum (Leanne) and dad (Hal)

## Family Context

- Leanne's mum has an undiagnosed gluten intolerance. When gluten is
  introduced, flag it clearly and note to watch for signs of discomfort,
  digestive changes, or skin reactions over the following 48-72 hours.
  This is not a medical restriction - just something to be attentive to.
- No other known family food allergies.

## Ella's Kitchen Framework

All enrichment and suggestions follow Ella's Kitchen's staged approach:

### Stage 1: First Tastes (from 6 months)
- Single vegetable purees, super smooth (consistency of pouring cream)
- Veg-first approach: green vegetables emphasised in the first two weeks
- Introduce one new food at a time
- Offer food after the lunchtime milk feed
- A few spoonfuls is plenty
- Expect mess and rejection - both are normal and healthy
- Recommended first vegetables: broccoli, peas, courgette, spinach,
  green beans, sweet potato, carrot, parsnip, squash, butternut squash,
  cauliflower, aubergine, pepper, sweetcorn

### Stage 2: Taking on Texture (from 7 months)
- Combine familiar vegetables together
- Introduce herbs and spices to familiar purees
- Thicker, lumpier textures (mashed rather than blended)
- Finger foods begin (soft cooked veg sticks, ripe fruit pieces)
- Introduce protein: well-cooked eggs, fish, meat, lentils, pulses
- Iron-rich foods become important: dark leafy greens, red meat, lentils

### Stage 3: Time to Chew (from 10 months)
- Proper finger foods with more texture
- Encourage self-feeding and chewing
- More complex meals with multiple ingredients
- Family food adapted (less salt, appropriate texture)

### Stage 4: At the Big Table (from 12 months)
- Transition to eating with the family
- Healthy snacking between meals
- Most family foods are appropriate (still no honey before 12 months,
  no whole nuts, low salt)

### Key Principles (apply across all stages)
- Up to 10 exposures before a baby accepts a new food. Re-offering a
  "rejected" food is expected and encouraged, not a failure.
- Rainbow variety: aim for a range of colours across the week.
- Approximately 600ml of milk daily alongside solids.
- Follow baby's pace. Never force food. Remove and try again another day.
- Messy eating is good - it's sensory exploration.

## Allergen Introduction

The UK recognises 14 major allergens. Introduce them one at a time with
2-3 days between each new allergen to monitor for reactions. Offer each
allergen regularly (once or twice a week) after introduction if no
reaction occurs. Introduce early in the day so you can observe for
several hours.

The 14 allergens to track:
1. Cow's milk and dairy (e.g. yoghurt, cheese in puree)
2. Eggs (well cooked)
3. Peanuts (ground or as smooth peanut butter, never whole)
4. Tree nuts (ground or as smooth butter, never whole)
5. Wheat/gluten (bread, pasta, cereals) - FLAG: family history, monitor closely
6. Soy (soy yoghurt, tofu)
7. Fish (well cooked, no shark/swordfish/marlin)
8. Crustaceans (prawns, crab - well cooked)
9. Molluscs (mussels, oysters - well cooked)
10. Sesame (tahini, ground seeds)
11. Celery and celeriac
12. Mustard
13. Lupin
14. Sulphites (unlikely to be relevant at this age)

Signs of immediate reaction (within 30 minutes): itchy rash or hives
(especially face), swollen lips/face/eyes, stomach pain, vomiting.

Signs of delayed reaction (hours later): recurring stomach pain, vomiting,
reflux, food refusal, loose stools, constipation, body rash, worsening
eczema.

Emergency signs (call 999): swollen tongue, persistent cough, breathing
difficulty, pale/floppy appearance.

If a reaction occurs, note it clearly in the diary entry, update the
allergen tracker, and add a prominent warning to the next-suggestion
content block advising Leanne to speak to her health visitor before
re-introducing that allergen.

## Processing Rules

### When /inbox runs:

1. Read all files in inbox/
2. For each transcript:
   a. Determine the date (from the transcript content or file timestamp)
   b. Create or update the diary file for that date (diary/YYYY-MM-DD.md)
   c. Update tracker/foods.md with any new foods
   d. Update tracker/allergens.md if any allergens were introduced
   e. Update the HTML content blocks in site/index.html
   f. Delete the processed inbox file
   g. Commit with a descriptive message and push

### Diary entries (diary/YYYY-MM-DD.md)

One file per day. If multiple voice notes arrive for the same day, merge
them into a single coherent entry. Format:

    ---
    date: 2026-02-14
    stage: 1
    ---

    # Friday 14 February

    ## Lunch
    **Food:** Blended broccoli with breast milk
    **Texture:** Super smooth puree
    **Reaction:** [whatever Leanne described]
    **Amount:** [whatever Leanne described]
    **Notes:** [any additional context from the voice note]

    ## Afternoon snack
    ...

Keep the language warm and natural. This is a diary, not a medical record.
Preserve Leanne's observations and personality from the transcript.

If Leanne mentions something that isn't a meal (e.g. "Goldie had a bad
night" or "We're visiting the in-laws this weekend"), include it as a
note in the diary entry. Context matters for understanding food reactions
and patterns.

### Tracker: foods.md

A running list of every food Goldie has been offered. Format:

    # Foods Explored

    | Food | First offered | Times offered | Reaction | Notes |
    |------|--------------|---------------|----------|-------|
    | Broccoli | 2026-02-14 | 1 | [reaction] | First ever food! |
    | Sweet potato | 2026-02-15 | 1 | [reaction] | |

Update the "Times offered" count each time a food reappears. Update the
"Reaction" column with the most recent reaction (reactions change over
multiple exposures - that's the point).

### Tracker: allergens.md

Tracks the 14 UK allergens. Format:

    # Allergen Tracker

    ## Introduced

    | Allergen | First introduced | Via food | Reaction | Notes |
    |----------|-----------------|----------|----------|-------|
    | Cow's milk | 2026-02-20 | Yoghurt in puree | None | |

    ## Not yet introduced

    | Allergen | Notes |
    |----------|-------|
    | Wheat/gluten | Family history - monitor closely when introduced |
    | Eggs | |
    | Peanuts | |
    ...

    ## Flagged

    | Allergen | Date | Reaction | Action |
    |----------|------|----------|--------|
    (empty until a reaction occurs)

Move allergens from "Not yet introduced" to "Introduced" when they first
appear. Move to "Flagged" if any reaction occurs.

### HTML content blocks

site/index.html contains marked content blocks. When updating, ONLY
modify content between the markers. Never change anything outside the
markers - no design, layout, styling, or structural changes.

Content block format in the HTML:
    <!-- CONTENT:block-name -->
    ...content here...
    <!-- /CONTENT:block-name -->

**Block: next-suggestion**
The most prominent section. One clear, practical suggestion for the next
meal. Include:
- What food to try and how to prepare it
- Why this food makes sense right now (e.g. "adds a new green veg",
  "time to try a fruit", "re-offering rejected carrot - attempt 3 of 10")
- Any relevant guidance from the current Ella's Kitchen stage
- If an allergen was recently introduced, note to keep offering it
  1-2 times this week

Keep it to 2-3 sentences. Warm, encouraging tone. Think "friendly
health visitor" not "medical textbook".

**Block: recent-meals**
The last 7 days of meals as a timeline. Each entry shows:
- Date and meal name
- What was offered
- Goldie's reaction (use emoji sparingly: loved/okay/rejected)
- Any notable observations

Render as clean HTML. Mobile-first. Easy to scan.

**Block: allergen-tracker**
A visual summary of allergen progress. Show:
- Allergens introduced (with date and any reaction)
- Allergens not yet introduced
- Any flagged allergens with warnings
- Highlight gluten with a note about family history

Use a simple grid or list. Colour-code: green for introduced (no
reaction), amber for flagged, grey for not yet introduced.

**Block: foods-explored**
The full list of foods tried. Show:
- Food name
- Times offered
- Current reaction status
- A visual indicator (e.g. a coloured dot)

Sort by most recently offered. This section grows over time.

## Tone

Everything Leanne reads should feel like advice from a knowledgeable,
warm friend - not a clinical tool or a parenting manual. Celebrate small
wins ("Goldie tried her first fruit today!"). Normalise rejection
("Totally normal - most babies need several tries. Offer it again in a
few days."). Be practical, not preachy.

Never guilt-trip. Never make Leanne feel she's doing it wrong. Weaning
is messy and imperfect and that's fine.

## Foods to Avoid (Safety)

Before 6 months: no solid food at all.
Before 12 months:
- Honey (botulism risk)
- Whole nuts (choking hazard - ground/butter is fine)
- Added salt or sugar
- Shark, swordfish, marlin (mercury)
- Raw or undercooked eggs (unless British Lion stamped)
- Whole grapes, cherry tomatoes (choking - cut lengthways)
- Rice milk (arsenic levels)

If a transcript mentions any of these being offered, add a gentle but
clear safety note to the diary entry and the next-suggestion block.

## Important

- Always push to main after committing. No branches.
- Prefer British English spelling.
- No em dashes or en dashes. Use hyphens or rewrite.
- When updating site/index.html, ONLY modify content within
  <!-- CONTENT:name --> markers. Never touch design, layout, or styling.
- Delete processed inbox files after processing.

Step 3: /inbox Command

Create .claude/commands/inbox.md:

Process all files in the inbox/ folder. For each file:

1. Read the transcript
2. Determine the date (from content or filename timestamp)
3. Create or update the diary entry for that date in diary/
4. Update tracker/foods.md with any new foods mentioned
5. Update tracker/allergens.md if any allergens were introduced
6. Update the four content blocks in site/index.html:
   - next-suggestion (based on current trackers and Ella's Kitchen stage)
   - recent-meals (last 7 days from diary/)
   - allergen-tracker (from tracker/allergens.md)
   - foods-explored (from tracker/foods.md)
7. Delete the processed inbox file
8. Commit with a descriptive message and push to main

Read CLAUDE.md before processing for full enrichment rules, tone
guidance, and formatting instructions.

Step 4: Tracker Files

tracker/foods.md

# Foods Explored

| Food | First offered | Times offered | Reaction | Notes |
|------|--------------|---------------|----------|-------|

No foods logged yet. Tracker will populate as diary entries are processed.

tracker/allergens.md

# Allergen Tracker

## Introduced

| Allergen | First introduced | Via food | Reaction | Notes |
|----------|-----------------|----------|----------|-------|

No allergens introduced yet.

## Not Yet Introduced

| Allergen | Notes |
|----------|-------|
| Cow's milk and dairy | |
| Eggs | |
| Peanuts | |
| Tree nuts | |
| Wheat/gluten | Family history (maternal grandmother) - monitor closely |
| Soy | |
| Fish | |
| Crustaceans | |
| Molluscs | |
| Sesame | |
| Celery and celeriac | |
| Mustard | |
| Lupin | |
| Sulphites | Unlikely to be relevant at this age |

## Flagged

| Allergen | Date | Reaction | Action |
|----------|------|----------|--------|

No reactions flagged.

Step 5: learnings.md

# Learnings

Operational memory for the food diary system. Update when patterns emerge
or when Hal/Leanne corrects a decision.

## Processing

_(No entries yet.)_

## Enrichment

_(No entries yet.)_

## Preferences

_(No entries yet.)_

Step 6: site/index.html

Design a beautiful, mobile-first single-page site. This is the most important deliverable from a user experience perspective - Leanne will look at this page every day.

Design requirements: - Mobile-first (iPhone 12 mini is the primary device, 5.4" screen) - Warm, friendly aesthetic. Think soft colours, rounded edges, clean typography. Not clinical. Not corporate. Not "tech startup". - Consider a palette inspired by baby/food themes - soft greens, warm oranges, gentle purples. Nothing garish. - Easy to scroll through. No complex navigation. Single page. - Use system fonts for fast loading (no external font dependencies). - Self-contained: all CSS inline in the HTML file. No external dependencies. No JavaScript frameworks. Vanilla JS only if needed for interactivity. - Must work well on small screens. Large touch targets. Readable font sizes.

Page structure (top to bottom):

  1. Header - "Goldie's Food Adventure" or similar. Simple, warm. Maybe a small illustration or emoji. Show Goldie's age/stage ("Stage 1: First Tastes").

  2. Next suggestion block (most prominent)

  3. <!-- CONTENT:next-suggestion -->
  4. What to try next, why, and how to prepare it
  5. Visually distinct - this is the thing Leanne checks most often
  6. <!-- /CONTENT:next-suggestion -->

  7. Recent meals timeline

  8. <!-- CONTENT:recent-meals -->
  9. Last 7 days of meals
  10. Each entry: date, food, reaction indicator, brief notes
  11. <!-- /CONTENT:recent-meals -->

  12. Allergen tracker

  13. <!-- CONTENT:allergen-tracker -->
  14. Visual grid or list of the 14 allergens
  15. Colour-coded: green (introduced, no reaction), amber (flagged), grey (not yet introduced)
  16. Gluten highlighted with family history note
  17. <!-- /CONTENT:allergen-tracker -->

  18. Foods explored

  19. <!-- CONTENT:foods-explored -->
  20. Full list of foods tried with reaction indicators
  21. Grows over time
  22. <!-- /CONTENT:foods-explored -->

  23. Footer - "Made with love by Hal" or similar. Minimal.

Important: The content blocks should contain placeholder content that makes it clear this is a template awaiting real data. Something like "Goldie's food journey starts here! Her first meal will appear once it's logged." Not lorem ipsum.

Use the /frontend-design skill or equivalent to create a genuinely beautiful design. This is not a prototype - it's the actual page Leanne will use daily for the next 6 months.


Step 7: Cloudflare Worker

Deploy a Cloudflare Worker that receives audio, transcribes it, and commits the transcript to the GitHub repo.

Worker requirements: - Runtime: Cloudflare Workers with nodejs_compat compatibility flag - AI binding: [ai] in wrangler.toml for Whisper access - Receives: HTTP POST with audio file in the body - Authenticates: shared secret in the Authorization header - Transcribes: Cloudflare Workers AI Whisper Large V3 Turbo (@cf/openai/whisper-large-v3-turbo) - Formats: markdown with YAML frontmatter (source: voice, captured: ISO date) - Commits: to inbox/ folder in the GitHub repo via GitHub Contents API - Filename: voice-{timestamp}-{random}.md for uniqueness - Returns: 200 with confirmation, or appropriate error code - Idempotent: same note ID in the filename means same path, no duplicate

Environment secrets (set via wrangler secret put): - SHARED_SECRET - shared secret for authenticating requests from the iPhone - GITHUB_PAT - classic GitHub Personal Access Token (no expiry, Contents read/write scope) - GITHUB_OWNER - GitHub username (HalSarj) - GITHUB_REPO - repo name (goldie-food)

wrangler.toml:

name = "goldie-food-worker"
main = "src/index.js"
compatibility_date = "2024-09-23"
compatibility_flags = ["nodejs_compat"]

[ai]
binding = "AI"

Worker code pattern:

export default {
  async fetch(request, env) {
    // 1. Verify shared secret
    const authHeader = request.headers.get('Authorization');
    if (authHeader !== `Bearer ${env.SHARED_SECRET}`) {
      return new Response('Unauthorized', { status: 401 });
    }

    // 2. Only accept POST
    if (request.method !== 'POST') {
      return new Response('Method not allowed', { status: 405 });
    }

    // 3. Get audio from request body
    const audioBuffer = await request.arrayBuffer();
    const audioArray = new Uint8Array(audioBuffer);

    // 4. Transcribe with Whisper
    const transcription = await env.AI.run(
      '@cf/openai/whisper-large-v3-turbo',
      { audio: [...audioArray] }
    );

    const text = transcription.text?.trim();
    if (!text) {
      return new Response('No speech detected', { status: 400 });
    }

    // 5. Format as markdown
    const now = new Date();
    const isoDate = now.toISOString().split('T')[0];
    const timestamp = now.toISOString().replace(/[:.]/g, '-');
    const randomSuffix = Math.random().toString(36).substring(2, 6);
    const filename = `voice-${timestamp}-${randomSuffix}.md`;

    const content = `---\nsource: voice\ncaptured: ${isoDate}\n---\n\n${text}\n`;

    // 6. Commit to GitHub
    const githubResponse = await fetch(
      `https://api.github.com/repos/${env.GITHUB_OWNER}/${env.GITHUB_REPO}/contents/inbox/${filename}`,
      {
        method: 'PUT',
        headers: {
          'Authorization': `Bearer ${env.GITHUB_PAT}`,
          'Content-Type': 'application/json',
          'User-Agent': 'goldie-food-worker',
        },
        body: JSON.stringify({
          message: `Add voice note: ${filename}`,
          content: btoa(unescape(encodeURIComponent(content))),
        }),
      }
    );

    if (!githubResponse.ok) {
      const error = await githubResponse.text();
      return new Response(`GitHub commit failed: ${error}`, { status: 502 });
    }

    return new Response(JSON.stringify({ ok: true, filename }), {
      status: 200,
      headers: { 'Content-Type': 'application/json' },
    });
  },
};

Deployment steps: 1. Hal needs a Cloudflare account (free tier is sufficient) 2. npm create cloudflare@latest goldie-food-worker 3. Replace src/index.js with the worker code 4. Update wrangler.toml 5. wrangler secret put SHARED_SECRET (generate a random 32-char string) 6. wrangler secret put GITHUB_PAT (classic PAT, no expiry, Contents read/write) 7. wrangler secret put GITHUB_OWNER (HalSarj) 8. wrangler secret put GITHUB_REPO (goldie-food) 9. wrangler deploy 10. Note the Worker URL (e.g. https://goldie-food-worker.hal.workers.dev)


Step 8: Cloudflare Pages

Host the site/index.html via Cloudflare Pages.

Setup: 1. In Cloudflare dashboard: Pages > Create a project > Connect to Git 2. Select the goldie-food GitHub repo 3. Build settings: - Build command: (leave empty - no build step) - Build output directory: site 4. Deploy

The site will auto-deploy on every push to main. When Claude Code updates the HTML content blocks and pushes, the site updates within seconds.

Give Leanne the Cloudflare Pages URL to bookmark on her Home Screen (Safari > Share > Add to Home Screen). It will look and feel like an app.


Step 9: iPhone Shortcut

Build an Apple Shortcut for Leanne's iPhone 12 mini. The shortcut records audio, saves it locally as a safety net, uploads to the Cloudflare Worker, and shows a confirmation.

Shortcut actions (in order):

  1. Record Audio - quality: normal, start immediately
  2. Set Variable - name: AudioFile, value: (recorded audio)
  3. Generate Random Number - minimum: 1000, maximum: 9999
  4. Set Variable - name: RandomID, value: (random number)
  5. Format Date - format: custom, yyyy-MM-dd-HHmmss
  6. Set Variable - name: Timestamp, value: (formatted date)
  7. Save File - save AudioFile to iCloud Drive/Shortcuts/goldie-queue/voice-{Timestamp}-{RandomID}.m4a (Ask where to save: OFF, overwrite: ON)
  8. Get Contents of Folder - iCloud Drive/Shortcuts/goldie-queue/
  9. Repeat with Each (for each file in the queue): a. Get Contents of URL (POST)
    • URL: https://goldie-food-worker.{your-subdomain}.workers.dev
    • Method: POST
    • Headers: Authorization: Bearer {SHARED_SECRET}
    • Request body: File (the current queue item) b. If (result contains "ok"):
    • Delete File (the current queue item from iCloud Drive)
  10. Show Notification - "Logged! Goldie's food diary will update soon."

Key design decisions: - Save locally FIRST, then upload. If the upload fails (no internet), the file stays in the queue and gets uploaded next time. - Flush the entire queue on every run. This handles offline backlog automatically - no separate sync step needed. - The shared secret is stored in the Shortcut, not ideal but acceptable for a personal tool. The Worker also validates it.

Adding to Home Screen: - In the Shortcuts app, tap the shortcut name > tap the dropdown arrow > "Add to Home Screen" - Choose a nice icon and name it something simple like "Goldie's Food" - It appears on the Home Screen like a regular app

Optional: Back Tap - Settings > Accessibility > Touch > Back Tap - Set Double Tap or Triple Tap to run this Shortcut - Only add this if Leanne finds it useful after using the Home Screen icon


Step 10: End-to-End Test

  1. Record a test voice note via the iPhone Shortcut: "Goldie had blended broccoli with a little breast milk today. It was her very first meal ever! She pulled some funny faces but seemed interested. She had about two spoonfuls."
  2. Verify: file appears in inbox/ on GitHub within ~15 seconds
  3. Run /inbox in Claude Code in the goldie-food repo
  4. Verify: diary/2026-02-14.md created with structured entry
  5. Verify: tracker/foods.md updated with broccoli
  6. Verify: site/index.html content blocks updated
  7. Verify: Cloudflare Pages site shows the update
  8. Check on Leanne's phone - page should be beautiful and readable

Test offline: 1. Put phone in airplane mode 2. Record a voice note 3. Verify: file saved to iCloud Drive/Shortcuts/goldie-queue/ 4. Turn airplane mode off 5. Record another voice note (this triggers queue flush) 6. Verify: both notes appear in inbox/


Notes for the Build Agent

  • This is a real project for a real family. The HTML page must be genuinely beautiful - not a developer prototype. Leanne will use this daily.
  • The CLAUDE.md content above is carefully crafted. Implement it exactly as written - the tone, the allergen guidance, the Ella's Kitchen framework, and the safety information have all been discussed and agreed.
  • Keep everything simple. No build tools, no JavaScript frameworks, no unnecessary dependencies. The whole system should be understandable by reading a handful of files.
  • British English throughout.
  • The Cloudflare Worker and iPhone Shortcut follow the same pattern as the hal-ea voice capture pipeline but are completely separate deployments.
  • Hal will need to do the Cloudflare dashboard steps (connecting the repo to Pages, setting Worker secrets) himself. The build agent should create all the code and config files, and provide clear instructions for the manual Cloudflare steps.