From 04d7bc0f0857b8e8e4bcb4547e134c0208794652 Mon Sep 17 00:00:00 2001 From: koH Date: Mon, 24 Aug 2026 03:22:03 -0500 Subject: [PATCH 1/4] feat(yuhm): rename WXL:FOOD to yuhm network MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit WXL:FOOD ("W Xtra Love") becomes yuhm — yum with the om at its center, Austin's regenerative food network. The om carries the whole cycle the app already runs: rescue, table, compost, soil, food again. - Directory wxl/ -> yuhm/, package wxl-food -> yuhm-network, python worker wxl_food_worker -> yuhm_food_worker, CI workflow renamed - Brand copy: wordmark "yuhm", tagline "the om in yum" / "el om en el ñam", landing title "Food, shared full circle" EN/ES - Browser storage keys wxl:* -> yuhm:* with a one-time migration in main.tsx so language/mode prefs survive - Host cutover to yuhm.handprotocol.org; wxl.handprotocol.org kept as alias with a forced 301 in public/_redirects and netlify.toml - Env: functions read YUHM_RESEND_AUDIENCE_ID (set on the site) - Applied Supabase migrations keep their NNN_wxl_* filenames; DB identifiers were already food_* and are untouched; historical plans and dated docs keep their names Co-Authored-By: Claude Fable 5 --- .github/workflows/{wxl-ci.yml => yuhm-ci.yml} | 14 ++-- wxl/public/_redirects | 1 - .../src/wxl_food_worker/__init__.py | 1 - wxl/src/SourceBoard.tsx | 29 ------- wxl/src/main.tsx | 14 ---- wxl/src/vite-env.d.ts | 3 - {wxl => yuhm}/.env.example | 2 +- {wxl => yuhm}/DEPLOY.md | 43 +++++----- {wxl => yuhm}/HANDOFF.md | 84 ++++++++++--------- .../_handoff-2026-08-11-network-upgrade.md | 0 {wxl => yuhm}/docs/COORDINATION-PROTOCOL.md | 8 +- {wxl => yuhm}/docs/DELIVERY-READINESS.md | 14 ++-- {wxl => yuhm}/docs/FOOD-SOURCE-AGENT.md | 6 +- {wxl => yuhm}/docs/LIVING-DOCS.md | 56 ++++++------- ...OVE-SESSION-CREDITS-AND-ACCOMPLISHMENTS.md | 0 .../docs/WXLOVE-THEME-OPTIMIZATION.md | 0 {wxl => yuhm}/index.html | 4 +- {wxl => yuhm}/netlify.toml | 9 +- .../netlify/functions/food-alert.mjs | 8 +- .../netlify/functions/subscribe-updates.mjs | 18 ++-- {wxl => yuhm}/package-lock.json | 4 +- {wxl => yuhm}/package.json | 2 +- {wxl => yuhm}/public/_headers | 0 yuhm/public/_redirects | 3 + .../public/architecture/architecture.js | 18 ++-- {wxl => yuhm}/public/architecture/index.html | 8 +- .../services/coordination-api/Dockerfile | 0 .../services/coordination-api/README.md | 4 +- .../services/coordination-api/openapi.yaml | 4 +- .../services/coordination-api/src/app.ts | 2 +- .../services/coordination-api/src/auth.ts | 0 .../services/coordination-api/src/config.ts | 0 .../coordination-api/src/contracts.test.ts | 0 .../coordination-api/src/contracts.ts | 2 +- .../services/coordination-api/src/database.ts | 0 .../coordination-api/src/event-worker.ts | 0 .../coordination-api/src/location.test.ts | 0 .../services/coordination-api/src/location.ts | 0 .../coordination-api/src/money.test.ts | 0 .../services/coordination-api/src/money.ts | 0 .../coordination-api/src/payment-worker.ts | 0 .../coordination-api/src/policy.test.ts | 0 .../services/coordination-api/src/policy.ts | 0 .../coordination-api/src/retention-worker.ts | 0 .../services/coordination-api/src/server.ts | 2 +- .../coordination-api/src/stripe.test.ts | 0 .../services/coordination-api/src/stripe.ts | 0 .../services/coordination-api/src/tools.ts | 0 .../services/coordination-api/src/types.ts | 0 .../coordination-api/src/voice.test.ts | 0 .../services/coordination-api/src/voice.ts | 0 .../services/coordination-api/tsconfig.json | 0 .../services/matching-worker/Dockerfile | 2 +- .../services/matching-worker/README.md | 4 +- .../services/matching-worker/pyproject.toml | 4 +- .../src/yuhm_food_worker/__init__.py | 1 + .../src/yuhm_food_worker}/main.py | 2 +- .../src/yuhm_food_worker}/models.py | 0 .../src/yuhm_food_worker}/optimizer.py | 0 .../src/yuhm_food_worker}/policy.py | 0 .../src/yuhm_food_worker}/repository.py | 0 .../src/yuhm_food_worker}/routing.py | 0 .../matching-worker/tests/test_optimizer.py | 4 +- .../matching-worker/tests/test_policy.py | 4 +- .../matching-worker/tests/test_routing.py | 4 +- {wxl => yuhm}/src/AddSpotModal.test.tsx | 0 {wxl => yuhm}/src/App.test.tsx | 58 ++++++------- {wxl => yuhm}/src/App.tsx | 2 +- {wxl => yuhm}/src/AppRealtime.test.tsx | 2 +- {wxl => yuhm}/src/AppRouting.test.tsx | 8 +- {wxl => yuhm}/src/AuthProvider.tsx | 0 {wxl => yuhm}/src/CommunityBoard.test.tsx | 0 {wxl => yuhm}/src/CommunityBoard.tsx | 6 +- {wxl => yuhm}/src/CommunityContactWidget.tsx | 14 ++-- {wxl => yuhm}/src/CommunityTools.tsx | 0 {wxl => yuhm}/src/ContributorBoard.tsx | 6 +- {wxl => yuhm}/src/DashboardApp.tsx | 18 ++-- {wxl => yuhm}/src/DropoffBoard.tsx | 0 {wxl => yuhm}/src/FoodAlertBanner.tsx | 0 {wxl => yuhm}/src/FoodMap.test.tsx | 0 {wxl => yuhm}/src/FoodMap.tsx | 0 {wxl => yuhm}/src/HarvestRunBoard.tsx | 2 +- {wxl => yuhm}/src/InventoryBoard.tsx | 2 +- {wxl => yuhm}/src/LandingPage.tsx | 2 +- {wxl => yuhm}/src/LoginScreen.tsx | 16 ++-- {wxl => yuhm}/src/MapPinPicker.tsx | 0 {wxl => yuhm}/src/ProtocolBoard.tsx | 0 {wxl => yuhm}/src/RescueBoard.tsx | 8 +- {wxl => yuhm}/src/SimpleExperience.tsx | 20 ++--- yuhm/src/SourceBoard.tsx | 29 +++++++ {wxl => yuhm}/src/foodLocations.test.ts | 0 {wxl => yuhm}/src/foodLocations.ts | 0 {wxl => yuhm}/src/i18n.tsx | 26 +++--- {wxl => yuhm}/src/lib/auth.test.ts | 6 +- {wxl => yuhm}/src/lib/auth.ts | 4 +- {wxl => yuhm}/src/lib/coordinationApi.ts | 0 {wxl => yuhm}/src/lib/engagement.ts | 6 +- {wxl => yuhm}/src/lib/feedback.test.ts | 4 +- {wxl => yuhm}/src/lib/feedback.ts | 18 ++-- {wxl => yuhm}/src/lib/foodRepository.test.ts | 2 +- {wxl => yuhm}/src/lib/foodRepository.ts | 72 ++++++++-------- {wxl => yuhm}/src/lib/updates.test.ts | 0 {wxl => yuhm}/src/lib/updates.ts | 2 +- {wxl => yuhm}/src/lib/useFoodAlerts.ts | 2 +- yuhm/src/main.tsx | 27 ++++++ {wxl => yuhm}/src/map-lab/MapLab.tsx | 14 ++-- {wxl => yuhm}/src/map-lab/map-lab.css | 0 {wxl => yuhm}/src/prompts.tsx | 2 +- {wxl => yuhm}/src/router.tsx | 0 {wxl => yuhm}/src/sampleData.ts | 0 {wxl => yuhm}/src/styles.css | 0 {wxl => yuhm}/src/testSetup.ts | 0 {wxl => yuhm}/src/useDialogMotion.test.tsx | 0 {wxl => yuhm}/src/useDialogMotion.ts | 0 yuhm/src/vite-env.d.ts | 3 + {wxl => yuhm}/tests/foodAlertFunction.test.ts | 0 .../tests/subscribeUpdatesFunction.test.ts | 4 +- {wxl => yuhm}/tsconfig.json | 0 {wxl => yuhm}/vite.config.ts | 2 +- {wxl => yuhm}/vitest.config.ts | 2 +- 120 files changed, 401 insertions(+), 376 deletions(-) rename .github/workflows/{wxl-ci.yml => yuhm-ci.yml} (69%) delete mode 100644 wxl/public/_redirects delete mode 100644 wxl/services/matching-worker/src/wxl_food_worker/__init__.py delete mode 100644 wxl/src/SourceBoard.tsx delete mode 100644 wxl/src/main.tsx delete mode 100644 wxl/src/vite-env.d.ts rename {wxl => yuhm}/.env.example (96%) rename {wxl => yuhm}/DEPLOY.md (78%) rename {wxl => yuhm}/HANDOFF.md (91%) rename {wxl => yuhm}/_handoff-2026-08-11-network-upgrade.md (100%) rename {wxl => yuhm}/docs/COORDINATION-PROTOCOL.md (90%) rename {wxl => yuhm}/docs/DELIVERY-READINESS.md (93%) rename {wxl => yuhm}/docs/FOOD-SOURCE-AGENT.md (97%) rename {wxl => yuhm}/docs/LIVING-DOCS.md (89%) rename {wxl => yuhm}/docs/WXLOVE-SESSION-CREDITS-AND-ACCOMPLISHMENTS.md (100%) rename {wxl => yuhm}/docs/WXLOVE-THEME-OPTIMIZATION.md (100%) rename {wxl => yuhm}/index.html (84%) rename {wxl => yuhm}/netlify.toml (78%) rename {wxl => yuhm}/netlify/functions/food-alert.mjs (93%) rename {wxl => yuhm}/netlify/functions/subscribe-updates.mjs (84%) rename {wxl => yuhm}/package-lock.json (99%) rename {wxl => yuhm}/package.json (98%) rename {wxl => yuhm}/public/_headers (100%) create mode 100644 yuhm/public/_redirects rename {wxl => yuhm}/public/architecture/architecture.js (97%) rename {wxl => yuhm}/public/architecture/index.html (98%) rename {wxl => yuhm}/services/coordination-api/Dockerfile (100%) rename {wxl => yuhm}/services/coordination-api/README.md (93%) rename {wxl => yuhm}/services/coordination-api/openapi.yaml (98%) rename {wxl => yuhm}/services/coordination-api/src/app.ts (99%) rename {wxl => yuhm}/services/coordination-api/src/auth.ts (100%) rename {wxl => yuhm}/services/coordination-api/src/config.ts (100%) rename {wxl => yuhm}/services/coordination-api/src/contracts.test.ts (100%) rename {wxl => yuhm}/services/coordination-api/src/contracts.ts (98%) rename {wxl => yuhm}/services/coordination-api/src/database.ts (100%) rename {wxl => yuhm}/services/coordination-api/src/event-worker.ts (100%) rename {wxl => yuhm}/services/coordination-api/src/location.test.ts (100%) rename {wxl => yuhm}/services/coordination-api/src/location.ts (100%) rename {wxl => yuhm}/services/coordination-api/src/money.test.ts (100%) rename {wxl => yuhm}/services/coordination-api/src/money.ts (100%) rename {wxl => yuhm}/services/coordination-api/src/payment-worker.ts (100%) rename {wxl => yuhm}/services/coordination-api/src/policy.test.ts (100%) rename {wxl => yuhm}/services/coordination-api/src/policy.ts (100%) rename {wxl => yuhm}/services/coordination-api/src/retention-worker.ts (100%) rename {wxl => yuhm}/services/coordination-api/src/server.ts (97%) rename {wxl => yuhm}/services/coordination-api/src/stripe.test.ts (100%) rename {wxl => yuhm}/services/coordination-api/src/stripe.ts (100%) rename {wxl => yuhm}/services/coordination-api/src/tools.ts (100%) rename {wxl => yuhm}/services/coordination-api/src/types.ts (100%) rename {wxl => yuhm}/services/coordination-api/src/voice.test.ts (100%) rename {wxl => yuhm}/services/coordination-api/src/voice.ts (100%) rename {wxl => yuhm}/services/coordination-api/tsconfig.json (100%) rename {wxl => yuhm}/services/matching-worker/Dockerfile (81%) rename {wxl => yuhm}/services/matching-worker/README.md (87%) rename {wxl => yuhm}/services/matching-worker/pyproject.toml (68%) create mode 100644 yuhm/services/matching-worker/src/yuhm_food_worker/__init__.py rename {wxl/services/matching-worker/src/wxl_food_worker => yuhm/services/matching-worker/src/yuhm_food_worker}/main.py (91%) rename {wxl/services/matching-worker/src/wxl_food_worker => yuhm/services/matching-worker/src/yuhm_food_worker}/models.py (100%) rename {wxl/services/matching-worker/src/wxl_food_worker => yuhm/services/matching-worker/src/yuhm_food_worker}/optimizer.py (100%) rename {wxl/services/matching-worker/src/wxl_food_worker => yuhm/services/matching-worker/src/yuhm_food_worker}/policy.py (100%) rename {wxl/services/matching-worker/src/wxl_food_worker => yuhm/services/matching-worker/src/yuhm_food_worker}/repository.py (100%) rename {wxl/services/matching-worker/src/wxl_food_worker => yuhm/services/matching-worker/src/yuhm_food_worker}/routing.py (100%) rename {wxl => yuhm}/services/matching-worker/tests/test_optimizer.py (93%) rename {wxl => yuhm}/services/matching-worker/tests/test_policy.py (97%) rename {wxl => yuhm}/services/matching-worker/tests/test_routing.py (89%) rename {wxl => yuhm}/src/AddSpotModal.test.tsx (100%) rename {wxl => yuhm}/src/App.test.tsx (93%) rename {wxl => yuhm}/src/App.tsx (97%) rename {wxl => yuhm}/src/AppRealtime.test.tsx (98%) rename {wxl => yuhm}/src/AppRouting.test.tsx (92%) rename {wxl => yuhm}/src/AuthProvider.tsx (100%) rename {wxl => yuhm}/src/CommunityBoard.test.tsx (100%) rename {wxl => yuhm}/src/CommunityBoard.tsx (94%) rename {wxl => yuhm}/src/CommunityContactWidget.tsx (93%) rename {wxl => yuhm}/src/CommunityTools.tsx (100%) rename {wxl => yuhm}/src/ContributorBoard.tsx (98%) rename {wxl => yuhm}/src/DashboardApp.tsx (93%) rename {wxl => yuhm}/src/DropoffBoard.tsx (100%) rename {wxl => yuhm}/src/FoodAlertBanner.tsx (100%) rename {wxl => yuhm}/src/FoodMap.test.tsx (100%) rename {wxl => yuhm}/src/FoodMap.tsx (100%) rename {wxl => yuhm}/src/HarvestRunBoard.tsx (99%) rename {wxl => yuhm}/src/InventoryBoard.tsx (99%) rename {wxl => yuhm}/src/LandingPage.tsx (95%) rename {wxl => yuhm}/src/LoginScreen.tsx (50%) rename {wxl => yuhm}/src/MapPinPicker.tsx (100%) rename {wxl => yuhm}/src/ProtocolBoard.tsx (100%) rename {wxl => yuhm}/src/RescueBoard.tsx (97%) rename {wxl => yuhm}/src/SimpleExperience.tsx (87%) create mode 100644 yuhm/src/SourceBoard.tsx rename {wxl => yuhm}/src/foodLocations.test.ts (100%) rename {wxl => yuhm}/src/foodLocations.ts (100%) rename {wxl => yuhm}/src/i18n.tsx (97%) rename {wxl => yuhm}/src/lib/auth.test.ts (94%) rename {wxl => yuhm}/src/lib/auth.ts (97%) rename {wxl => yuhm}/src/lib/coordinationApi.ts (100%) rename {wxl => yuhm}/src/lib/engagement.ts (94%) rename {wxl => yuhm}/src/lib/feedback.test.ts (84%) rename {wxl => yuhm}/src/lib/feedback.ts (87%) rename {wxl => yuhm}/src/lib/foodRepository.test.ts (99%) rename {wxl => yuhm}/src/lib/foodRepository.ts (90%) rename {wxl => yuhm}/src/lib/updates.test.ts (100%) rename {wxl => yuhm}/src/lib/updates.ts (90%) rename {wxl => yuhm}/src/lib/useFoodAlerts.ts (89%) create mode 100644 yuhm/src/main.tsx rename {wxl => yuhm}/src/map-lab/MapLab.tsx (97%) rename {wxl => yuhm}/src/map-lab/map-lab.css (100%) rename {wxl => yuhm}/src/prompts.tsx (95%) rename {wxl => yuhm}/src/router.tsx (100%) rename {wxl => yuhm}/src/sampleData.ts (100%) rename {wxl => yuhm}/src/styles.css (100%) rename {wxl => yuhm}/src/testSetup.ts (100%) rename {wxl => yuhm}/src/useDialogMotion.test.tsx (100%) rename {wxl => yuhm}/src/useDialogMotion.ts (100%) create mode 100644 yuhm/src/vite-env.d.ts rename {wxl => yuhm}/tests/foodAlertFunction.test.ts (100%) rename {wxl => yuhm}/tests/subscribeUpdatesFunction.test.ts (95%) rename {wxl => yuhm}/tsconfig.json (100%) rename {wxl => yuhm}/vite.config.ts (85%) rename {wxl => yuhm}/vitest.config.ts (85%) diff --git a/.github/workflows/wxl-ci.yml b/.github/workflows/yuhm-ci.yml similarity index 69% rename from .github/workflows/wxl-ci.yml rename to .github/workflows/yuhm-ci.yml index f96a9bf..9a7d66d 100644 --- a/.github/workflows/wxl-ci.yml +++ b/.github/workflows/yuhm-ci.yml @@ -1,15 +1,15 @@ -name: WXL CI +name: yuhm CI on: pull_request: paths: - - "wxl/**" - - ".github/workflows/wxl-ci.yml" + - "yuhm/**" + - ".github/workflows/yuhm-ci.yml" push: branches: [main] paths: - - "wxl/**" - - ".github/workflows/wxl-ci.yml" + - "yuhm/**" + - ".github/workflows/yuhm-ci.yml" workflow_dispatch: jobs: @@ -18,14 +18,14 @@ jobs: runs-on: ubuntu-latest defaults: run: - working-directory: wxl + working-directory: yuhm steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 22 cache: npm - cache-dependency-path: wxl/package-lock.json + cache-dependency-path: yuhm/package-lock.json - name: Install dependencies run: npm ci - name: Run tests diff --git a/wxl/public/_redirects b/wxl/public/_redirects deleted file mode 100644 index ad37e2c..0000000 --- a/wxl/public/_redirects +++ /dev/null @@ -1 +0,0 @@ -/* /index.html 200 diff --git a/wxl/services/matching-worker/src/wxl_food_worker/__init__.py b/wxl/services/matching-worker/src/wxl_food_worker/__init__.py deleted file mode 100644 index 28fd7c0..0000000 --- a/wxl/services/matching-worker/src/wxl_food_worker/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Deterministic WXL:FOOD matching and routing worker.""" diff --git a/wxl/src/SourceBoard.tsx b/wxl/src/SourceBoard.tsx deleted file mode 100644 index 9531319..0000000 --- a/wxl/src/SourceBoard.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { useState } from 'react' -import { CheckCircle2, Plus, Warehouse } from 'lucide-react' -import { nominateFoodSource } from './lib/foodRepository' - -export function SourceBoard({ notify, dbConfigured, canWrite, verifiedCount, onAuthRequired }: { notify: (message: string) => void; dbConfigured: boolean; canWrite: boolean; verifiedCount: number; onAuthRequired: () => void }) { - const [sourceName, setSourceName] = useState('') - const [sourceType, setSourceType] = useState('Food pantry') - const [neighborhood, setNeighborhood] = useState('East Austin') - const [notes, setNotes] = useState('') - const [nominated, setNominated] = useState([]) - - const submitNomination = () => { - if (!sourceName.trim() || !notes.trim()) return - if (!canWrite) { onAuthRequired(); return } - const input = { source_name: sourceName.trim(), source_type: sourceType, neighborhood, notes: notes.trim() } - if (dbConfigured) { - nominateFoodSource(input).then(({ error }) => { - if (error) { notify(error.message); return } - setNominated((current) => [sourceName.trim(), ...current]) - setSourceName(''); setNotes(''); notify('Food source nomination sent for review') - }) - } else { - setNominated((current) => [sourceName.trim(), ...current]) - setSourceName(''); setNotes(''); notify('Food source nomination added to the review queue') - } - } - - return <>

Community-vetted source registry

Partner network

Nominate a local food source. WXL:FOOD reviews it before it becomes part of the public map.

{verifiedCount}verified {verifiedCount === 1 ? 'source' : 'sources'} on the map

How the registry works

People closest to the work keep the map honest.

Anyone in the network can nominate a pantry, fridge, farm, kitchen, church, school program, market, or mutual-aid group. A coordinator confirms the source, its hours, and what it can actually offer.

01Nominate a source
02Verify the details
03Connect it to requests

Add to the network

Nominate a food source