From 9afa26ed5c7b5b2711c51cbb78ddbef3102535a4 Mon Sep 17 00:00:00 2001 From: Cody Menefee Date: Wed, 4 Feb 2026 11:19:44 -0600 Subject: [PATCH 1/5] docs: align env examples and centralize env setup guidance --- CONTRIBUTING.md | 14 ++- README.md | 18 +++- app/.env.example | 55 ++++++---- app/README.md | 19 ++-- .../content/getting-started/installation.ts | 18 +++- app/src/vite-env.d.ts | 3 + docs/environment.md | 100 ++++++++++++++++++ src/ingestion/.env.example | 53 ++++++---- 8 files changed, 224 insertions(+), 56 deletions(-) create mode 100644 docs/environment.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 077e50a..a584c60 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -42,13 +42,13 @@ npm install ### 2. Configure Environment -Copy the example environment file: +Copy the app example environment file: ```bash -cp .env.example .env.local +cp app/.env.example app/.env.local ``` -Edit `.env.local` with your values: +Edit `app/.env.local` with your values: ```bash # Convex - Get from your Convex dashboard @@ -62,6 +62,14 @@ VITE_CLERK_PUBLISHABLE_KEY=pk_test_your_key_here VITE_DEV_AUTH=true ``` +If you work on ingestion/pipeline code, also copy: + +```bash +cp src/ingestion/.env.example src/ingestion/.env.local +``` + +For the complete env matrix (including Convex Dashboard server-side vars like `ANTHROPIC_API_KEY`), see [docs/environment.md](docs/environment.md). + ### 3. Set Up Convex If you haven't already, create a Convex project: diff --git a/README.md b/README.md index 46ce78e..78a54bd 100644 --- a/README.md +++ b/README.md @@ -107,11 +107,22 @@ Common scripts: ### Environment Variables -The following environment variables are required for full functionality: +Environment setup is documented in [docs/environment.md](docs/environment.md). -- `BRAINTRUST_API_KEY` - API key for Braintrust observability platform. Required for agent behavior tracking and debugging. Get your API key from [Braintrust](https://www.braintrust.dev). Set this in your Convex dashboard environment variables for production, or in `.env.local` for local development. +Quick start: - Without this key, agent logging will be disabled but the application will continue to function. +```bash +cp app/.env.example app/.env.local +cp src/ingestion/.env.example src/ingestion/.env.local +``` + +Set server-side keys (for Convex backend actions) in Convex Dashboard environment variables: + +- `ANTHROPIC_API_KEY` (required for AI recommendations) +- `BRAINTRUST_API_KEY` (optional observability) +- `BRAINTRUST_PROJECT_NAME` (optional, defaults to `grazing-agent`) +- `GITHUB_TOKEN` (optional, enables GitHub issue creation from reports) +- `CONVEX_DEBUG` (optional backend debug logging) ## Tech Stack @@ -143,6 +154,7 @@ The following environment variables are required for full functionality: - [Development Phasing](docs/phasing.md) - How we build this incrementally - [Technical Architecture](docs/architecture.md) - System design and data flow - [Domain Knowledge](docs/domain.md) - Remote sensing and vegetation science primer +- [Environment Setup](docs/environment.md) - Required and optional variables by runtime ## Contributing diff --git a/app/.env.example b/app/.env.example index 4202d89..fcf520b 100644 --- a/app/.env.example +++ b/app/.env.example @@ -1,17 +1,14 @@ # ============================================================================= -# Convex Configuration +# App Runtime (Vite, read from app/.env.local) # ============================================================================= -# Get your Convex URL from the Convex dashboard after setting up your project +# REQUIRED +# Where used: app/src/main.tsx +# Acquire: Convex Dashboard -> Deployments -> Settings -> URL and Deploy Key VITE_CONVEX_URL=https://your-project.convex.cloud -# Convex deploy key (for server-side API calls) -# Generate from Convex dashboard → Settings → Deploy Keys -CONVEX_DEPLOY_KEY=prod:your_deploy_key_here - -# ============================================================================= -# Clerk Authentication -# ============================================================================= -# Get from Clerk dashboard → API Keys +# OPTIONAL when using development auth bypass. +# Where used: app/src/lib/auth/index.tsx +# Acquire: Clerk Dashboard -> API Keys -> Publishable key (pk_test_* or pk_live_*) VITE_CLERK_PUBLISHABLE_KEY=pk_test_your_key_here # Clerk JWT template required by ConvexProviderWithClerk. @@ -28,14 +25,14 @@ CLERK_WEBHOOK_SECRET=whsec_your_webhook_secret_here # Example with custom Clerk domain: https://clerk.themodernstrategy.com CLERK_JWT_ISSUER_DOMAIN= -# ============================================================================= -# Development Mode -# ============================================================================= -# Set to "true" to bypass Clerk auth during local development +# OPTIONAL, defaults to false. +# Where used: app/src/lib/auth/index.tsx and demo onboarding routes +# true = bypass Clerk auth locally VITE_DEV_AUTH=false -# Set to "true" to disable the subscription paywall (useful for dev) -# Paywall is enabled by default in production +# OPTIONAL, defaults to false. +# Where used: app/src/routes/app.tsx and app/src/routes/subscribe.tsx +# true = disable subscription paywall checks VITE_PAYWALL_DISABLED=false # ============================================================================= @@ -48,9 +45,29 @@ VITE_POSTHOG_KEY=phc_your_project_api_key VITE_POSTHOG_HOST=https://us.i.posthog.com # ============================================================================= -# Braintrust Observability (Optional) +# Convex Server Runtime (set in Convex Dashboard env vars, not Vite-exposed) # ============================================================================= -# For agent tracing and observability -# Get from Braintrust dashboard → Settings → API Keys +# REQUIRED for AI recommendations in Convex actions. +# Where used: app/convex/grazingAgentDirect.ts via Anthropic SDK +# Acquire: Anthropic Console -> API Keys +ANTHROPIC_API_KEY=sk-ant-api03-your-key-here + +# OPTIONAL observability. +# Where used: app/lib/braintrust.ts +# Acquire: Braintrust Settings -> Organization -> API keys BRAINTRUST_API_KEY=your_braintrust_api_key + +# OPTIONAL, defaults to "grazing-agent" if omitted. +# Where used: app/lib/braintrust.ts BRAINTRUST_PROJECT_NAME=grazing-agent + +# OPTIONAL, enables automatic GitHub issue creation from bug/feature reports. +# Where used: app/convex/bugReportsAction.ts and app/convex/featureRequestsAction.ts +# Acquire: GitHub -> Settings -> Developer settings -> Personal access tokens +# Recommended: fine-grained token with Issues: Read and write on this repository. +GITHUB_TOKEN=github_pat_your_token_here + +# OPTIONAL, defaults to false. +# Where used: app/convex/lib/logger.ts +# true = enable debug/info logging in Convex backend logger +CONVEX_DEBUG=false diff --git a/app/README.md b/app/README.md index a22c47a..f25bc54 100644 --- a/app/README.md +++ b/app/README.md @@ -13,13 +13,20 @@ npm run dev ## Environment -Required env vars (set in `app/.env.local`): +Copy and fill the app env template: -- `VITE_CONVEX_URL` - Convex deployment URL -- `VITE_DEV_AUTH=true` - bypass Clerk sign-in locally -- `VITE_CLERK_PUBLISHABLE_KEY` - required when `VITE_DEV_AUTH` is not set -- `CLERK_JWT_ISSUER_DOMAIN` (or `CLERK_FRONTEND_API_URL`) - Clerk issuer domain used by `convex/auth.config.ts` -- Clerk JWT template named `convex` with audience `convex` - required for `ConvexProviderWithClerk` +```bash +cp .env.example .env.local +``` + +Primary app variables: + +- `VITE_CONVEX_URL` - required +- `VITE_DEV_AUTH=true` - optional local auth bypass +- `VITE_CLERK_PUBLISHABLE_KEY` - required when `VITE_DEV_AUTH=false` +- `VITE_PAYWALL_DISABLED=true` - optional local paywall bypass + +Server-side Convex variables (`ANTHROPIC_API_KEY`, `BRAINTRUST_API_KEY`, etc.) are documented in [docs/environment.md](../docs/environment.md) and should be set in Convex Dashboard env vars. ## Scripts diff --git a/app/src/lib/docs/content/getting-started/installation.ts b/app/src/lib/docs/content/getting-started/installation.ts index 6d9f153..d480eee 100644 --- a/app/src/lib/docs/content/getting-started/installation.ts +++ b/app/src/lib/docs/content/getting-started/installation.ts @@ -29,7 +29,10 @@ npm install`, }, { heading: 'Environment Variables', - content: `Create a \`.env.local\` file with the following variables: + content: `Copy \`app/.env.example\` to \`app/.env.local\` and fill in values. +The complete variable matrix (including ingestion and Convex dashboard-only keys) is in \`docs/environment.md\`. + +App-local keys: **Required:** - \`VITE_CONVEX_URL\` - Your Convex deployment URL (e.g., https://your-deployment.convex.cloud) @@ -38,14 +41,19 @@ npm install`, - \`VITE_CLERK_PUBLISHABLE_KEY\` - For Clerk authentication in production - \`VITE_DEV_AUTH=true\` - For development mode without authentication -**Optional:** -- \`BRAINTRUST_API_KEY\` - For agent observability (set in Convex dashboard) -- \`BRAINTRUST_PROJECT_NAME\` - Defaults to 'grazing-agent'`, +**Optional app key:** +- \`VITE_PAYWALL_DISABLED=true\` - Disable paywall checks locally + +**Set in Convex dashboard (server-side):** +- \`ANTHROPIC_API_KEY\` - Required for AI recommendations +- \`BRAINTRUST_API_KEY\` - Optional agent observability +- \`BRAINTRUST_PROJECT_NAME\` - Optional, defaults to 'grazing-agent'`, codeExample: { language: 'bash', filename: '.env.local', code: `VITE_CONVEX_URL=https://your-deployment.convex.cloud -VITE_DEV_AUTH=true`, +VITE_DEV_AUTH=true +VITE_PAYWALL_DISABLED=false`, }, }, { diff --git a/app/src/vite-env.d.ts b/app/src/vite-env.d.ts index aad6263..1972185 100644 --- a/app/src/vite-env.d.ts +++ b/app/src/vite-env.d.ts @@ -2,6 +2,9 @@ interface ImportMetaEnv { readonly VITE_CONVEX_URL?: string + readonly VITE_DEV_AUTH?: string + readonly VITE_CLERK_PUBLISHABLE_KEY?: string + readonly VITE_PAYWALL_DISABLED?: string } interface ImportMeta { diff --git a/docs/environment.md b/docs/environment.md new file mode 100644 index 0000000..683787a --- /dev/null +++ b/docs/environment.md @@ -0,0 +1,100 @@ +# Environment Variables + +This is the single source of truth for environment configuration across the repo. + +## App Local Env (`app/.env.local`) + +From repo root: + +```bash +cp app/.env.example app/.env.local +``` + +Frontend (Vite) variables: + +- `VITE_CONVEX_URL` (required) +- `VITE_DEV_AUTH` (optional, defaults to `false`) +- `VITE_CLERK_PUBLISHABLE_KEY` (required when `VITE_DEV_AUTH=false`) +- `VITE_PAYWALL_DISABLED` (optional, defaults to `false`) + +## Ingestion Local Env (`src/ingestion/.env.local`) + +From repo root: + +```bash +cp src/ingestion/.env.example src/ingestion/.env.local +``` + +Minimum required for Convex writeback: + +- `CONVEX_DEPLOYMENT_URL` +- `CONVEX_API_KEY` + +Provider/storage variables are optional and depend on enabled integrations. + +## Convex Dashboard Env Vars (Server-side only) + +Set these in Convex Dashboard for backend actions: + +1. Open [Convex Dashboard](https://dashboard.convex.dev/) +2. Select your deployment +3. Go to `Deployment Settings` -> `Environment Variables` +4. Add/update keys below + +Required: + +- `ANTHROPIC_API_KEY` + +Optional: + +- `BRAINTRUST_API_KEY` +- `BRAINTRUST_PROJECT_NAME` +- `GITHUB_TOKEN` +- `CONVEX_DEBUG` + +These are server-side only. Do not prefix them with `VITE_`. + +## Variable Matrix + +| Variable | Scope | Required | Default | Where Used | Acquisition | +|---|---|---|---|---|---| +| `VITE_CONVEX_URL` | Vite | Yes | none | `app/src/main.tsx` | Convex deployment URL from [Deployment Settings](https://docs.convex.dev/dashboard/deployments/deployment-settings) | +| `VITE_DEV_AUTH` | Vite | No | `false` | `app/src/lib/auth/index.tsx` | Local toggle, no external provider needed | +| `VITE_CLERK_PUBLISHABLE_KEY` | Vite | Conditional (`VITE_DEV_AUTH=false`) | none | `app/src/lib/auth/index.tsx` | Clerk dashboard publishable key per [Clerk env docs](https://clerk.com/docs/deployments/clerk-environment-variables) | +| `VITE_PAYWALL_DISABLED` | Vite | No | `false` | `app/src/routes/app.tsx` | Local toggle, no external provider needed | +| `ANTHROPIC_API_KEY` | Convex | Yes (AI path) | none | `app/convex/grazingAgentDirect.ts` | Anthropic console key per [Anthropic getting started](https://docs.anthropic.com/en/api/getting-started) | +| `BRAINTRUST_API_KEY` | Convex | No | none | `app/lib/braintrust.ts` | Braintrust org API key per [Braintrust API intro](https://www.braintrust.dev/docs/api-reference/introduction) | +| `BRAINTRUST_PROJECT_NAME` | Convex | No | `grazing-agent` | `app/lib/braintrust.ts` | Optional name from [Braintrust projects](https://www.braintrust.dev/docs/core/projects) | +| `GITHUB_TOKEN` | Convex | No | none | `app/convex/bugReportsAction.ts` and `app/convex/featureRequestsAction.ts` | GitHub PAT per [token docs](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) | +| `CONVEX_DEBUG` | Convex | No | `false` | `app/convex/lib/logger.ts` | Local/Convex toggle, no provider key | +| `CONVEX_DEPLOYMENT_URL` | Ingestion | Yes (writeback path) | none | `src/ingestion/writer.py` | Convex deployment URL from [Deployment Settings](https://docs.convex.dev/dashboard/deployments/deployment-settings) | +| `CONVEX_API_KEY` | Ingestion | Yes (writeback path) | none | `src/ingestion/writer.py` and `src/ingestion/scheduler.py` | Convex deploy key per [deploy key docs](https://docs.convex.dev/cli/deploy-key-types) | +| `COPERNICUS_CLIENT_ID` | Ingestion | No | none | `src/ingestion/providers/copernicus.py` | CDSE OAuth client per [CDSE auth docs](https://documentation.dataspace.copernicus.eu/APIs/SentinelHub/Overview/Authentication.html) | +| `COPERNICUS_CLIENT_SECRET` | Ingestion | No | none | `src/ingestion/providers/copernicus.py` | CDSE OAuth secret from same client setup | +| `PL_API_KEY` | Ingestion | No | none | `src/ingestion/providers/planet_scope.py` | Planet API key per [Planet auth docs](https://docs.planet.com/develop/authentication/) | +| `PL_CLIENT_ID` | Ingestion | No | none | `src/ingestion/providers/planet_scope.py` | Planet OAuth client credentials (optional) per [Planet auth docs](https://docs.planet.com/develop/authentication/) | +| `PL_CLIENT_SECRET` | Ingestion | No | none | `src/ingestion/providers/planet_scope.py` | Planet OAuth client credentials (optional) per [Planet auth docs](https://docs.planet.com/develop/authentication/) | +| `R2_ACCOUNT_ID` | Ingestion | No | none | `src/ingestion/storage/r2.py` | Cloudflare account ID per [R2 S3 token docs](https://developers.cloudflare.com/r2/api/s3/tokens/) | +| `R2_ACCESS_KEY_ID` | Ingestion | No | none | `src/ingestion/storage/r2.py` | Cloudflare R2 S3 access key per [R2 get started](https://developers.cloudflare.com/r2/get-started/cli/) | +| `R2_SECRET_ACCESS_KEY` | Ingestion | No | none | `src/ingestion/storage/r2.py` | Cloudflare R2 S3 secret key per [R2 get started](https://developers.cloudflare.com/r2/get-started/cli/) | +| `R2_BUCKET_NAME` | Ingestion | No | `grazing-satellite-tiles` | `src/ingestion/storage/r2.py` | Existing/new R2 bucket name | +| `R2_PUBLIC_URL_BASE` | Ingestion | No | none | `src/ingestion/storage/r2.py` | Optional public/custom domain URL | +| `COMPOSITE_WINDOW_DAYS` | Ingestion | No | `21` | `src/ingestion/config.py` | Local tuning value | +| `MAX_CLOUD_COVER` | Ingestion | No | `50` | `src/ingestion/config.py` | Local tuning value | +| `MIN_CLOUD_FREE_PCT` | Ingestion | No | `0.3` | `src/ingestion/config.py` | Local tuning value | +| `DEFAULT_PROVIDER` | Ingestion | No | `sentinel2` | `src/ingestion/config.py` | Local tuning value (`copernicus` or `sentinel2`) | +| `ENABLE_PLANET_SCOPE` | Ingestion | No | `false` | `src/ingestion/config.py` | Local toggle for PlanetScope integration | +| `WRITE_TO_CONVEX` | Ingestion | No | `true` | `src/ingestion/config.py` | Local toggle for writeback | +| `OUTPUT_DIR` | Ingestion | No | `output` | `src/ingestion/config.py` | Local filesystem path | +| `LOG_LEVEL` | Ingestion | No | `INFO` | `src/ingestion/config.py` | Local logging config | + +## Convex CLI Parity + +Reference: [Convex env docs](https://docs.convex.dev/production/environment-variables). + +```bash +npx convex env list +npx convex env get ANTHROPIC_API_KEY +npx convex env set ANTHROPIC_API_KEY "your_value" +npx convex env remove CONVEX_DEBUG +``` diff --git a/src/ingestion/.env.example b/src/ingestion/.env.example index 9faad74..dffaa87 100644 --- a/src/ingestion/.env.example +++ b/src/ingestion/.env.example @@ -3,46 +3,53 @@ # ============================================================================= # ============================================================================= -# Convex Connection +# 1) REQUIRED: Convex Writeback # ============================================================================= -# Your Convex deployment URL +# Where used: writer.py, scheduler.py +# Acquire: Convex Dashboard -> Deployments -> Settings -> URL and Deploy Key CONVEX_DEPLOYMENT_URL=https://your-project.convex.cloud -# Convex deploy key for API mutations -# Generate from Convex dashboard → Settings → Deploy Keys +# Deploy key used for Convex HTTP mutations CONVEX_API_KEY=prod:your_deploy_key_here # ============================================================================= -# Copernicus Data Space (Sentinel-2 Imagery) +# 2) Sentinel-2 Provider Auth (Copernicus Data Space) # ============================================================================= -# Register at: https://dataspace.copernicus.eu/ -# Create OAuth client at: Dashboard → OAuth Clients -# Use "client_credentials" grant type +# Where used: imagery_checker.py, providers/copernicus.py +# Acquire: +# 1) Register account at https://dataspace.copernicus.eu/ +# 2) Create OAuth client (client_credentials) in CDSE dashboard COPERNICUS_CLIENT_ID=your_client_id_here COPERNICUS_CLIENT_SECRET=your_client_secret_here # ============================================================================= -# Cloudflare R2 Storage (For Paid Tiers) +# 3) OPTIONAL: Planet Provider Auth (premium/professional tiers) # ============================================================================= -# Get from Cloudflare dashboard → R2 → Manage R2 API Tokens +# Where used: providers/planet_scope.py, providers/__init__.py +# Preferred for Planet Data API access: +PL_API_KEY=your_planet_api_key + +# Optional OAuth credentials (Sentinel Hub / future provider flows) +PL_CLIENT_ID=your_planet_client_id +PL_CLIENT_SECRET=your_planet_client_secret + +# ============================================================================= +# 4) OPTIONAL: Cloudflare R2 Storage +# ============================================================================= +# Where used: storage/r2.py +# Acquire: Cloudflare Dashboard -> R2 -> API tokens (S3 compatible keys) R2_ACCOUNT_ID=your_cloudflare_account_id R2_ACCESS_KEY_ID=your_r2_access_key_id R2_SECRET_ACCESS_KEY=your_r2_secret_access_key R2_BUCKET_NAME=grazing-satellite-tiles -# Optional: Public URL base for R2 bucket (if using custom domain) -# R2_PUBLIC_URL_BASE=https://tiles.yourdomain.com +# Optional if you serve tiles via public/custom domain +R2_PUBLIC_URL_BASE=https://tiles.yourdomain.com # ============================================================================= -# Planet Labs (Optional - For Premium Tiers) -# ============================================================================= -# Get from Planet dashboard → Account Settings → API Key -# Only needed for professional/enterprise tiers -PL_API_KEY=your_planet_api_key - -# ============================================================================= -# Pipeline Settings (Optional - Defaults shown) +# 5) OPTIONAL: Pipeline Tuning (defaults shown) # ============================================================================= +# Where used: config.py # Number of days to look back for composite imagery COMPOSITE_WINDOW_DAYS=21 @@ -55,8 +62,14 @@ MIN_CLOUD_FREE_PCT=0.3 # Default satellite provider ("copernicus" or "sentinel2" for Planetary Computer) DEFAULT_PROVIDER=copernicus +# Enable PlanetScope integration in pipeline configuration +ENABLE_PLANET_SCOPE=false + # Whether to write results to Convex WRITE_TO_CONVEX=true # Output directory for local files OUTPUT_DIR=output + +# Logging level: DEBUG, INFO, WARNING, ERROR +LOG_LEVEL=INFO From b94fb4681423a054823da23af22de0c9884b0b89 Mon Sep 17 00:00:00 2001 From: Cody Menefee Date: Wed, 4 Feb 2026 11:24:27 -0600 Subject: [PATCH 2/5] chore: ignore codex local workspace state --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 47f7917..b5da942 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ Thumbs.db # IDE .idea/ .vscode/ +.codex/ *.swp *.swo From b354dff3e3c317b0402d12fa95ae5c2b31128105 Mon Sep 17 00:00:00 2001 From: Cody Menefee Date: Sun, 22 Feb 2026 15:38:06 -0600 Subject: [PATCH 3/5] docs: consolidate product thesis into single vision.md All thesis, philosophy, and mission content is now sourced from docs/vision.md. Duplicate claims removed from README, agents.md, app/CLAUDE.md, CONTRIBUTING.md, and docs/phasing.md. Each now references vision.md rather than restating the thesis. Also adds start.sh for running Convex + Vite dev servers concurrently. Co-Authored-By: Claude Sonnet 4.6 --- CONTRIBUTING.md | 2 +- README.md | 42 ++++------------------------------- agents.md | 33 +--------------------------- app/CLAUDE.md | 2 +- docs/phasing.md | 2 +- docs/vision.md | 58 +++++++++++++++++++++++++++++++++++++++++++++++++ start.sh | 23 ++++++++++++++++++++ 7 files changed, 89 insertions(+), 73 deletions(-) create mode 100644 docs/vision.md create mode 100755 start.sh diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a584c60..261fa7f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributing to OpenPasture -Thanks for helping improve OpenPasture! This project focuses on the Morning Farm Brief experience and adaptive grazing intelligence. +Thanks for helping improve OpenPasture! See [docs/vision.md](docs/vision.md) for the product thesis before diving in. ## Table of Contents diff --git a/README.md b/README.md index 78a54bd..0301f86 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,6 @@ # OpenPasture -An open-source intelligence and orchestration layer for adaptive grazing. This system translates satellite-derived land signals into clear daily grazing decisions. - -## Overview - -Grass is dynamic. Fences are static. Modern sensing allows us to understand land conditions daily - what's been missing is software that turns those signals into actionable guidance. - -This project provides the **decision-making brain** that tells farmers: - -> "Here is the current state of your land, and here is the best grazing action for today." - -## The Morning Farm Brief - -The core experience is a daily ritual: - -1. **Open the app** each morning -2. **Receive a status report** on your farm's pasture conditions -3. **Review the recommended grazing plan** for today -4. **Approve or adjust** using natural language feedback -5. **Get execution instructions** ready for your virtual fencing system or manual workflow - -This is decision support - you stay in control. +An open-source intelligence layer for adaptive grazing. See [docs/vision.md](docs/vision.md) for the thesis and product philosophy. ## Features @@ -57,8 +37,6 @@ We use publicly available satellite imagery (primarily Sentinel-2) to compute ve - Frequent revisits (daily to every few days) - Historical archive for trend analysis -Satellite cadence aligns with biological reality - grazing decisions are daily or multi-day decisions, not minute-by-minute. - ### Vegetation Indices | Index | Purpose | @@ -77,17 +55,6 @@ Satellite cadence aligns with biological reality - grazing decisions are daily o 6. Score pasture readiness using transparent rules 7. Generate recommendation with confidence level -## What This Is Not - -To maintain focus, this demo does not include: - -- Real-time livestock tracking -- Custom hardware or collars -- Automated fence actuation -- Drone-based sensing - -These are future integration points, not current scope. - ## Getting Started The web app lives in `app/`. Prerequisites: Node.js 18+ and npm. @@ -143,6 +110,7 @@ Set server-side keys (for Convex backend actions) in Convex Dashboard environmen │ ├── src/ │ └── ... ├── docs/ +│ ├── vision.md # Thesis and product philosophy │ ├── architecture.md # Technical architecture details │ ├── domain.md # Remote sensing domain knowledge │ └── phasing.md # Development phases @@ -151,9 +119,10 @@ Set server-side keys (for Convex backend actions) in Convex Dashboard environmen ## Documentation -- [Development Phasing](docs/phasing.md) - How we build this incrementally +- [Vision](docs/vision.md) - Thesis and product philosophy - [Technical Architecture](docs/architecture.md) - System design and data flow - [Domain Knowledge](docs/domain.md) - Remote sensing and vegetation science primer +- [Development Phasing](docs/phasing.md) - How we build this incrementally - [Environment Setup](docs/environment.md) - Required and optional variables by runtime ## Contributing @@ -168,6 +137,3 @@ If you discover a vulnerability, see [SECURITY.md](SECURITY.md). Licensed under the Apache License, Version 2.0. See [LICENSE](LICENSE) and [NOTICE](NOTICE). ---- - -*OpenPasture - Building the intelligence layer for regenerative grazing.* diff --git a/agents.md b/agents.md index cfd9660..8ae0a3d 100644 --- a/agents.md +++ b/agents.md @@ -3,23 +3,7 @@ > This file is the primary reference for AI agents working on this codebase. > Read this first before making any changes. -## What This Project Is - -A **daily decision intelligence system for adaptive grazing**, powered by satellite data and human-in-the-loop AI. The core product is called the **Morning Farm Brief** - a daily ritual where farmers receive land status and recommended grazing actions. - -**Core thesis:** Grass is dynamic, fences are static. Satellite sensing lets us understand land conditions daily. We build the software brain that translates land signals into clear daily grazing decisions. - -## What This Project Is NOT - -Do not build or propose: -- Livestock collar integration or firmware -- Real-time livestock tracking/movement -- Custom hardware -- Automated actuation systems -- Drone-based sensing -- Real-time autonomous herding - -This is a **decision support system**, not an automation or control system. +For the product thesis and philosophy, read [docs/vision.md](docs/vision.md) first. ## Core User Flow @@ -118,14 +102,6 @@ These rules are intentionally simple and explainable for farmer trust. - **Format:** Cloud-Optimized GeoTIFFs (COGs) - **API:** STAC (SpatioTemporal Asset Catalog) -## Design Principles - -1. **Plain language over charts** - Briefs should read like a farmer talking to a farmer -2. **Transparency over magic** - Show assumptions and confidence, not black box scores -3. **Daily cadence is sufficient** - Satellite refresh aligns with biological reality -4. **Cloud cover is manageable** - Use rolling composites and multiple sources -5. **Collar-agnostic output** - Generate geometry and copy-ready instructions, no direct integration - ## File Structure Convention ``` @@ -144,13 +120,6 @@ These rules are intentionally simple and explainable for farmer trust. └── ... ``` -## Success Metrics - -The demo succeeds when: -- A farmer says: "This matches how I think about my land." -- An investor says: "This has a clear wedge and expansion path." -- A collar company says: "This would make our product more valuable." - ## Questions to Ask Before Building 1. Does this feature support the Morning Farm Brief flow? diff --git a/app/CLAUDE.md b/app/CLAUDE.md index 7130041..e0d6297 100644 --- a/app/CLAUDE.md +++ b/app/CLAUDE.md @@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Project Overview -OpenPasture - an open-source AI-powered decision support system that translates satellite-derived vegetation data into daily grazing recommendations. The core experience is a "Morning Farm Brief" that recommends which pasture to graze today. +OpenPasture - an open-source adaptive grazing intelligence platform. See [docs/vision.md](../docs/vision.md) for the product thesis. ## Commands diff --git a/docs/phasing.md b/docs/phasing.md index 437b163..4c78991 100644 --- a/docs/phasing.md +++ b/docs/phasing.md @@ -119,7 +119,7 @@ python src/ingestion/pipeline.py --dev --write-convex --output /tmp/pan_output ### Why This Phase Matters -The product IS the Morning Farm Brief. If this experience isn't crisp, nothing else matters. Skipping this results in UI rework loops later. +The recommendation UI is the primary farmer touchpoint. If it isn't crisp, nothing else matters. Skipping this results in UI rework loops later. --- diff --git a/docs/vision.md b/docs/vision.md new file mode 100644 index 0000000..99ac77d --- /dev/null +++ b/docs/vision.md @@ -0,0 +1,58 @@ +# Vision + +## The Real Bottleneck + +The limiting factor in regenerative grazing is not data. Farmers don't say they're blocked by lack of soil sensors or nutrient analysis. The real bottleneck is time on pasture — the attention required to physically observe land conditions and make daily movement decisions across a whole farm. + +Soil analysis and dense sensor networks feel like solutions, but they address a problem farmers don't actually have. Threading the needle means avoiding two failure modes: + +- **Over-indexing on trackable metrics** reduces a complex living system to numbers, repeating the reductionist mistakes regenerative agriculture was built to correct. +- **Over-indexing on physical observation** doesn't scale. A farmer cannot be everywhere every day. + +The optimal solution scales the farmer's visual monitoring capability without replacing their judgment. + +## Thesis + +A farmer needs two things to make a movement decision: + +1. **Accumulated industry knowledge** — the principles developed by practitioners like Greg Judy, Joel Salatin, and Richard Perkins: move at least weekly, ideally daily; don't overgraze; leave residual; rest periods matter; context of the broader ecosystem. +2. **Visual confirmation of pasture health** plus a mental model of prior conditions. + +The first can be captured in text and reasoned over by an LLM. Combined with pasture imagery, this creates a feedback loop capable of generating movement suggestions comparable to farmer intuition. + +## The Product + +Imagine Greg Judy, Joel Salatin, or Richard Perkins staring at images of your farm all day. Every morning they send you a text and a map: *"Move the animals here today."* The suggestion is adjacent to where the animals currently are, timed and measured to benefit both the paddock being vacated and the broader farm system — accounting for forward projections, weather, rest periods, and herd pressure. + +That is what this system builds. + +The recommendation is rendered as a polygon on an orthomosaic representation of the farm. The farmer approves, adjusts, or rejects. That feedback improves future suggestions. + +## What We Need to Build It + +**Starting inputs:** +- Satellite imagery (available today, free, global) +- Farmer field notes, optionally with photos + +These two inputs are sufficient to architect the core decision engine. The digital twin of the farm needs to exist only in imagery — satellite, drone, or fixed camera — not in soil probes or collar telemetry. + +**Optimization path (once the engine exists):** +- Farmer approval rate as a training signal (RLHF) +- Drone imagery for higher resolution +- Soil and moisture monitoring for finer tuning +- Direct push to virtual fencing collars + +## What We Are Not Building + +This is a recommendation engine, not a control system. We are not building: + +- Automated fence actuation +- Livestock tracking or collar firmware +- Soil monitoring infrastructure +- Real-time herd movement systems + +Those are downstream of a working recommendation engine. We build the brain first. + +## Success + +The product succeeds when a farmer says: "This matches how I think about my land" — and they say it without having walked the pasture that morning. diff --git a/start.sh b/start.sh new file mode 100755 index 0000000..d27bbb9 --- /dev/null +++ b/start.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# Start OpenPasture dev environment +# Runs Convex backend + Vite dev server concurrently + +cd "$(dirname "$0")/app" + +cleanup() { + echo "Shutting down..." + kill "$CONVEX_PID" "$VITE_PID" 2>/dev/null + wait "$CONVEX_PID" "$VITE_PID" 2>/dev/null + exit 0 +} + +trap cleanup INT TERM + +npx convex dev & +CONVEX_PID=$! + +pnpm dev & +VITE_PID=$! + +wait "$CONVEX_PID" "$VITE_PID" From 709e8f7fd5a6e9f5a76161ef33350f7ededfd452 Mon Sep 17 00:00:00 2001 From: Cody Menefee Date: Sun, 22 Feb 2026 16:16:55 -0600 Subject: [PATCH 4/5] docs: expand vision with founding principle, value prop, and strategic bets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds sections on the founding philosophical principle, the multiplicative value proposition (stocking density × scale), the directed attention product mechanic, the farmer-as-benchmark trust model, the collar dependency and open-source hardware strategy, and the why-now framing grounded in SpaceX/Blue Origin launch economics and LLM maturity. Co-Authored-By: Claude Sonnet 4.6 --- docs/vision.md | 52 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/docs/vision.md b/docs/vision.md index 99ac77d..3c749ee 100644 --- a/docs/vision.md +++ b/docs/vision.md @@ -1,5 +1,11 @@ # Vision +## Founding Principle + +Complex systems — like nature itself — are best utilized when you work within them, not when you abstract away from them. Regenerative agriculture was built on this insight. This product is built on the same one. + +The decision of when to move animals across pasture is a multi-variable analysis: labor availability, animal stress and condition, the health of the currently grazed paddock, the next paddock, the pasture as a whole, the farm as a whole, projected weather in the near and intermediate term, and the historic performance of the land over time. A farmer with the right training has proven capable of weighing all of this — some of it empirically, much of it intuitively. We seek to augment that decision-making layer by predicting what a trained farmer would do. + ## The Real Bottleneck The limiting factor in regenerative grazing is not data. Farmers don't say they're blocked by lack of soil sensors or nutrient analysis. The real bottleneck is time on pasture — the attention required to physically observe land conditions and make daily movement decisions across a whole farm. @@ -11,6 +17,12 @@ Soil analysis and dense sensor networks feel like solutions, but they address a The optimal solution scales the farmer's visual monitoring capability without replacing their judgment. +## The Value Proposition + +Regenerative grazing increases stocking density — more animals on the same acreage because the land is healthier and more productive. Our system increases operational scale — more acres managed by the same farmer because daily observation and decision-making is handled autonomously. + +These are multiplicative, not additive. A farmer who adopts regenerative practices and uses this system doesn't just farm more profitably — they begin to compete with operations far larger than their own. This is the unlock for the small and mid-size farmer. + ## Thesis A farmer needs two things to make a movement decision: @@ -28,20 +40,40 @@ That is what this system builds. The recommendation is rendered as a polygon on an orthomosaic representation of the farm. The farmer approves, adjusts, or rejects. That feedback improves future suggestions. +Critically, the system does not just receive farmer input — it directs the farmer's observational attention. Each morning report includes a request for the specific field observation that would most reduce uncertainty in that day's recommendation: a grass height sample, a gut read on time left in the current paddock. The farmer spends less time walking the farm randomly and more time collecting targeted signal. This is how the system scales a farmer's attention rather than replacing it. + +## The Farmer as Benchmark + +The farmer is the benchmark of efficiency, not the ceiling. + +The system earns trust by matching farmer judgment. It earns the right to exceed farmer judgment by showing better outcomes — tracked over time through pasture health trends, stocking performance, and land recovery rates. The land itself is the feedback mechanism. + +This design prevents the atrophy risk: a farmer who always defers to the system does not lose their intuition as long as the outcomes confirm the decisions were right. Outcome tracking is how the system proves it is working — and how it surfaces when it isn't. + ## What We Need to Build It **Starting inputs:** -- Satellite imagery (available today, free, global) +- Satellite imagery — daily, global, up to 3m resolution on paid plans, providing NDVI and biomass proxies sufficient for farm and pasture-level health assessment - Farmer field notes, optionally with photos -These two inputs are sufficient to architect the core decision engine. The digital twin of the farm needs to exist only in imagery — satellite, drone, or fixed camera — not in soil probes or collar telemetry. +These two inputs are sufficient to architect the core decision engine. The farm's digital representation lives in imagery — not soil probes or collar telemetry. + +**Known gap:** Satellite cannot reliably assess precise grass height or growth stage at the paddock level. The decision to graze just before seed, taking only the top third of the plant, requires this information. Field notes close this gap initially. Fixed pasture cameras are the likely near-term bridge. Drone imagery or improved satellite analysis resolves it long-term. **Optimization path (once the engine exists):** - Farmer approval rate as a training signal (RLHF) +- Fixed pasture cameras for growth stage visibility - Drone imagery for higher resolution -- Soil and moisture monitoring for finer tuning - Direct push to virtual fencing collars +## The Collar Dependency + +Collar integration is the unlock that converts this system from decision support into autonomous operation. Without it, the system reduces cognitive burden but not labor burden — a harder value proposition to sustain at scale. With it, the farmer's role shifts from daily physical execution to daily review and approval. That is the equivalent shift that coding agents brought to software development. + +The collar market is currently locked behind proprietary software with no open APIs. + +Our strategy: build the decision-making layer aggressively and let its value create pressure on collar companies to integrate. If they don't open their APIs, we will compete at the hardware layer with a cheap, COTS-based, open-source collar design that commoditizes the market and breaks the lock. The brain is the defensible asset. The collar is not. + ## What We Are Not Building This is a recommendation engine, not a control system. We are not building: @@ -53,6 +85,20 @@ This is a recommendation engine, not a control system. We are not building: Those are downstream of a working recommendation engine. We build the brain first. +## Why Now + +Three vectors are converging: + +**Satellite resolution** — SpaceX and Blue Origin dramatically reduced the cost of reaching orbit. Cheaper launch economics enabled commercial operators like Planet Labs to deploy large constellations, increasing revisit frequency and resolution while driving down cost. Daily 3m imagery at commercial prices is a direct downstream effect of the reusable rocket era. + +**LLM and agent maturity** — The ability to reason over complex, multi-variable decisions using codified domain knowledge — and to do so as an autonomous agent operating on a daily loop — has only recently become viable and affordable. + +**Drone accessibility** — Falling hardware costs and loosening regulations make drone imagery a credible near-term input, though it is not required to begin. + +These three vectors arriving simultaneously is what makes the core architecture buildable today. + ## Success The product succeeds when a farmer says: "This matches how I think about my land" — and they say it without having walked the pasture that morning. + +The product wins when a farmer says: "I couldn't run this many acres without it." From 385186bbb4250a44c3012964868203a1548a6524 Mon Sep 17 00:00:00 2001 From: Cody Menefee Date: Sun, 22 Feb 2026 18:35:49 -0600 Subject: [PATCH 5/5] feat(marketing): align site copy with farmer-centric vision Overhaul all marketing copy to match updated vision.md. Remove probability/gradient language throughout. Replace with farmer-judgment framing centered on predicting what a trained farmer would do. Landing page: new hero headline, badges, body copy, showcase sections (morning_report --daily, ndvi health, earn trust), how-it-works steps (observe/reason/decide), beta banner, and CTA. Nav label updated to how-it-works. Investors page: restructured with new sections -- The Value Proposition (multiplicative unlock), The Product (Greg Judy description + directed attention mechanic), The Farmer as Benchmark, Why Now (3 vectors), The Collar Dependency. Platform Vision removes John Deere reference. Moat flywheel line updated. Supporting pages: technology hero subtitle, scoring engine and recommendation AI descriptions, GPS Collars card updated. Research page gets collar strategy sentence and recommendation accuracy bullet. TechnologyConvergence diagram: 4 vectors reduced to 3 (satellite resolution, LLM maturity, drone accessibility). Visual scale: reduced html font-size ramp (13/14/15px) and PageSection default padding (py-12) to fix overly zoomed feel. Greg Judy linked to YouTube video in landing page and investors page. Co-Authored-By: Claude Sonnet 4.6 --- app/index.html | 32 +-- app/src/components/marketing/Footer.tsx | 2 +- .../components/marketing/MarketingHeader.tsx | 2 +- .../diagrams/SystemArchitectureDiagram.tsx | 2 +- .../diagrams/TechnologyConvergence.tsx | 26 +- app/src/components/ui/page-section.tsx | 2 +- app/src/index.css | 8 +- app/src/routes/_public/investors.tsx | 247 +++++++++++++----- app/src/routes/_public/research.tsx | 3 +- app/src/routes/_public/technology.tsx | 12 +- app/src/routes/index.tsx | 72 +++-- 11 files changed, 262 insertions(+), 146 deletions(-) diff --git a/app/index.html b/app/index.html index e4aa675..7bb1d72 100644 --- a/app/index.html +++ b/app/index.html @@ -4,39 +4,35 @@ - + - - + + - - + + + + OpenPasture | Predict What a Trained Farmer Would Do - OpenPasture | AI-Powered Adaptive Grazing -