diff --git a/.cursor/rules/zest-project.mdc b/.cursor/rules/zest-project.mdc new file mode 100644 index 0000000..4eadcbc --- /dev/null +++ b/.cursor/rules/zest-project.mdc @@ -0,0 +1,51 @@ +--- +description: Zest repository agent context and guardrails +alwaysApply: true +--- + +# Zest Agent Context + +Read these first: + +- `documentation/13-agent-brief.md` +- `documentation/14-decision-log.md` +- The subsystem doc linked from the agent brief for the files you are changing. + +Hard rules: + +- No runtime rule-based NOVA fallback. +- No AI image upload; OCR stays on device and backend receives text only. +- No user AI API keys; Gemini calls go through the backend proxy. +- No persistence or logging of scan images, OCR text, ingredients, results, chat, usage, failures, prompts, requests, or responses. +- Keep `/analyze` and `/chat` separate with separate backend-owned prompts. +- Android must not send prompt text, schemas, or model instructions. +- Keep allergens separate from ultra-processing markers. +- Keep module versions in root `module_versions.json`, root `VERSION_LOG.md`, and `documentation/12-module-versioning.md`. + +Change governance: + +- For every change, summarize what changed in the relevant documentation. +- Extract durable philosophy/architecture decisions and update `documentation/14-decision-log.md`. +- Update `documentation/13-agent-brief.md` when future agents need different guidance. +- Update root `module_versions.json` and root `VERSION_LOG.md` when behavior, contracts, prompts, build/release rules, documentation modules, or agent guidance changes. +- If no version bump is needed, explain why in the final response. + +Current defaults: + +- Android: Kotlin + Jetpack Compose. +- Backend: FastAPI on Cloud Run, Vertex AI service-account auth. +- Model: `gemini-3.5-flash`. +- Storage: session-only scan data; former Room/history code is archived under `documentation/code-archive/session_only_storage/`. + +Verification: + +```bash +./gradlew :app:verifySourceTreeForBuild :app:compileDebugKotlin +./gradlew :app:testDebugUnitTest +.venv/bin/python -m pytest backend/tests/test_app.py backend/tests/test_benchmark_analyze.py -q +git diff --check +``` + +Known caution: + +Public Cloud Run `/analyze` and `/chat` access is acceptable only for testing or limited rollout. Broad production needs abuse controls. diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..5f2dec3 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,55 @@ +# Zest Agent Instructions + +Start every repo task by reading: + +1. `documentation/13-agent-brief.md` +2. `documentation/14-decision-log.md` +3. The subsystem document linked from the brief for the area you are changing. + +## Non-Negotiable Rules + +- Do not add rule-based NOVA classification or fallback paths to runtime code. +- Do not send captured or imported images to any AI provider. OCR runs on device; the backend receives text only. +- Do not persist scan images, OCR text, normalized ingredients, results, chat, usage, or failures. +- Do not log OCR text, prompts, model requests/responses, user questions, or result context. +- Do not ask users for AI model API keys. Gemini calls go through the backend proxy using Cloud Run Vertex auth. +- Keep analysis and chat prompts backend-owned. Android must not send prompt text or schemas. +- Keep `/analyze` and `/chat` separate backend endpoints with separate prompts. +- Keep allergens separate from processing markers in UI and contracts. +- Keep module versions tracked in root `module_versions.json`, logged in root `VERSION_LOG.md`, and documented in `documentation/12-module-versioning.md`. + +## Change Governance + +Every change must leave a compact handoff trail: + +- Summarize what changed in the relevant documentation. +- Extract the design philosophy or architecture decision behind the change and update `documentation/14-decision-log.md` when it creates or changes a durable decision. +- Update `documentation/13-agent-brief.md` when the change affects how future agents should approach the repo. +- Update root `module_versions.json` and root `VERSION_LOG.md` whenever behavior, public contracts, prompts, build/release rules, documentation modules, or agent guidance changes. +- If no version bump is needed, say why in the final response. + +## Current Runtime Shape + +- Android app: native Kotlin + Jetpack Compose. +- Image path: camera/gallery image -> on-device ML Kit OCR -> text-only backend `/analyze`. +- Barcode path: USDA lookup when configured -> backend `/analyze`. +- Chat path: current result + current session chat history -> backend `/chat`. +- Backend: FastAPI on Cloud Run, Vertex AI via service-account identity, default model `gemini-3.5-flash`. +- Storage: session-only scan data; former Room/history code is archived under `documentation/code-archive/session_only_storage/`. + +## Verification Commands + +Use the smallest relevant set first: + +```bash +./gradlew :app:verifySourceTreeForBuild :app:compileDebugKotlin +./gradlew :app:testDebugUnitTest +.venv/bin/python -m pytest backend/tests/test_app.py backend/tests/test_benchmark_analyze.py -q +git diff --check +``` + +Gradle may need access to `~/.gradle` caches. If sandboxed execution fails on Gradle lock files, rerun with the approved Gradle command outside the sandbox. + +## Known Production Caution + +The deployed Cloud Run `/analyze` and `/chat` endpoints are documented as a temporary limited-rollout posture if publicly callable. Broad production needs an abuse-control layer such as Firebase App Check / Play Integrity, Firebase Auth, API Gateway/IAM, Cloud Armor, quotas, or rate limiting. diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..682e296 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,19 @@ +# Backend Cloud Run image. Build from the repository root so module_versions.json is packaged. +FROM python:3.12-slim + +ENV PYTHONUNBUFFERED=1 \ + PYTHONDONTWRITEBYTECODE=1 \ + PORT=8080 + +WORKDIR /app + +COPY backend/requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +COPY backend/main.py backend/prompt.py module_versions.json ./ +COPY backend/prompts ./prompts + +EXPOSE 8080 + +# Cloud Run sets PORT; default to 8080 locally. +CMD ["sh", "-c", "uvicorn main:app --host 0.0.0.0 --port ${PORT:-8080}"] diff --git a/VERSION_LOG.md b/VERSION_LOG.md new file mode 100644 index 0000000..052fd2d --- /dev/null +++ b/VERSION_LOG.md @@ -0,0 +1,35 @@ +# Version Log + +This is the repo-level change log for Zest module and release versions. Every code, prompt, architecture, documentation, or agent-guidance change must either add an entry here or explicitly state that no version bump was required. + +Entries can represent coordinated product releases or independently versioned modules. + +## 1.0.3 + +Date: 2026-07-13 + +- Optimized the backend full-analysis prompt contract for single-call NOVA decisioning, lower latency, and benchmark-driven accuracy. + +## 1.0.2 + +Date: 2026-07-13 + +- Moved the module version manifest source of truth to the repo root: `module_versions.json`. +- Added repo-level version logging in `VERSION_LOG.md`. +- Added agent governance requiring every future change to summarize implementation, extract decisions/philosophy, and update the relevant documentation or decision file. +- Added documentation and agent-context modules to version tracking. +- Updated backend packaging to use the repo-root Docker build context and packaged root manifest for `/version`. + +## 1.0.1 + +Date: 2026-07-13 + +- Switched the backend and Android model defaults from Gemini 2.5 Flash to `gemini-3.5-flash`. +- Updated backend deployment documentation and Android proxy fixtures for the Gemini 3.5 Flash default. +- Added module-version tracking and source-tree verification guard. + +## 1.0.0 + +Date: 2026-07-13 + +- Baseline documented release after backend proxy, session-only storage, backend-owned prompts, separate `/analyze` and `/chat`, and no-user-AI-key architecture were established. diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 61c983c..d211c93 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -13,9 +13,9 @@ fun String.asBuildConfigStringLiteral(): String = val releaseVersionCode = providers.gradleProperty("ZEST_VERSION_CODE") .map(String::toInt) - .orElse(2) + .orElse(3) val releaseVersionName = providers.gradleProperty("ZEST_VERSION_NAME") - .orElse("1.0.1") + .orElse("1.0.2") val localProperties = Properties().apply { val localPropertiesFile = rootProject.layout.projectDirectory.file("local.properties").asFile if (localPropertiesFile.isFile) { @@ -245,11 +245,15 @@ val verifyModuleVersionManifest = tasks.register("verifyModuleVersionManifest") group = "verification" description = "Fails if a Zest module is missing from the production version manifest or docs." doLast { - val manifestFile = rootProject.file("backend/module_versions.json") + val manifestFile = rootProject.file("module_versions.json") + val versionLogFile = rootProject.file("VERSION_LOG.md") val documentationFile = rootProject.file("documentation/12-module-versioning.md") if (!manifestFile.isFile) { throw GradleException("Missing module version manifest: ${manifestFile.relativeTo(rootDir)}") } + if (!versionLogFile.isFile) { + throw GradleException("Missing repo version log: ${versionLogFile.relativeTo(rootDir)}") + } if (!documentationFile.isFile) { throw GradleException( "Missing module version documentation: ${documentationFile.relativeTo(rootDir)}" @@ -271,6 +275,10 @@ val verifyModuleVersionManifest = tasks.register("verifyModuleVersionManifest") } val moduleIds = mutableSetOf() val docsText = documentationFile.readText() + val versionLogText = versionLogFile.readText() + if (!versionLogText.contains("## $releaseVersion")) { + throw GradleException("VERSION_LOG.md is missing release entry: $releaseVersion") + } fun moduleValue(module: Map<*, *>, key: String): String = module[key] as? String @@ -293,6 +301,9 @@ val verifyModuleVersionManifest = tasks.register("verifyModuleVersionManifest") "Module version documentation is missing module $id version $version." ) } + if (!versionLogText.contains(version)) { + throw GradleException("VERSION_LOG.md is missing module version $version for $id.") + } if (kind != "android-gradle-module" && path.startsWith(":")) { throw GradleException("Only android-gradle-module entries can use Gradle paths: $id") } @@ -312,7 +323,7 @@ val verifyModuleVersionManifest = tasks.register("verifyModuleVersionManifest") val missingGradleModules = actualGradlePaths - manifestGradlePaths if (missingGradleModules.isNotEmpty()) { throw GradleException( - "Gradle modules missing from backend/module_versions.json: " + + "Gradle modules missing from module_versions.json: " + missingGradleModules.joinToString() ) } diff --git a/backend/Dockerfile b/backend/Dockerfile index d30e1f1..eb2fdd6 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,3 +1,5 @@ +# Backend Cloud Run image. Build with repository root as the Docker context: +# docker build -f backend/Dockerfile . FROM python:3.12-slim ENV PYTHONUNBUFFERED=1 \ @@ -6,11 +8,11 @@ ENV PYTHONUNBUFFERED=1 \ WORKDIR /app -COPY requirements.txt . +COPY backend/requirements.txt . RUN pip install --no-cache-dir -r requirements.txt -COPY main.py prompt.py module_versions.json ./ -COPY prompts ./prompts +COPY backend/main.py backend/prompt.py module_versions.json ./ +COPY backend/prompts ./prompts EXPOSE 8080 diff --git a/backend/README.md b/backend/README.md index b1551c3..e59d5ce 100644 --- a/backend/README.md +++ b/backend/README.md @@ -178,7 +178,7 @@ Corpus source: Open Food Facts public database and API. ```bash gcloud run deploy ultraprocessed-ai-proxy \ - --source backend \ + --source . \ --project b2-ultra-processed \ --region us-east1 \ --service-account up-app-service@b2-ultra-processed.iam.gserviceaccount.com \ @@ -188,6 +188,8 @@ gcloud run deploy ultraprocessed-ai-proxy \ The service account must have Vertex AI access (e.g. `roles/aiplatform.user`) on the project. +Deploy from the repository root so the root `Dockerfile` and root `module_versions.json` are packaged into the backend image for `GET /version`. If using `backend/Dockerfile` directly, build with the repository root as the Docker context: `docker build -f backend/Dockerfile .`. + ## Security notes - **Known deferred risk:** `--allow-unauthenticated` leaves `/analyze` and `/chat` publicly callable. This is diff --git a/backend/main.py b/backend/main.py index 78385a3..c5d966b 100644 --- a/backend/main.py +++ b/backend/main.py @@ -52,11 +52,17 @@ for origin in os.getenv("CORS_ALLOWED_ORIGINS", "").split(",") if origin.strip() ] -MODULE_VERSION_MANIFEST_PATH = Path(__file__).with_name("module_versions.json") +MODULE_VERSION_MANIFEST_PATHS = ( + Path(__file__).resolve().parent.parent / "module_versions.json", + Path(__file__).with_name("module_versions.json"), +) def load_module_version_manifest() -> dict[str, Any]: - with MODULE_VERSION_MANIFEST_PATH.open(encoding="utf-8") as manifest_file: + manifest_path = next((path for path in MODULE_VERSION_MANIFEST_PATHS if path.is_file()), None) + if manifest_path is None: + raise RuntimeError("module version manifest not found") + with manifest_path.open(encoding="utf-8") as manifest_file: manifest = json.load(manifest_file) if not isinstance(manifest, dict): raise RuntimeError("module version manifest must be a JSON object") diff --git a/documentation/07-testing-release.md b/documentation/07-testing-release.md index 6d5c4de..efbd5bb 100644 --- a/documentation/07-testing-release.md +++ b/documentation/07-testing-release.md @@ -92,7 +92,8 @@ flowchart TB - Unit tests pass. - `verifySourceTreeForBuild` passes. -- `backend/module_versions.json` contains every Gradle module, top-level Android package module, backend service, and backend prompt contract. +- Root `module_versions.json` contains every Gradle module, top-level Android package module, backend service, backend prompt contract, documentation module, and agent-context module. +- Root `VERSION_LOG.md` contains the current release entry and the module versions changed by the release. - Release APK assembles with signing environment variables present. - Android test APK assembles. - `rg "BuildConfig|local.properties|USDA_API_KEY" app/src/main app/build.gradle.kts` shows no embedded key source. diff --git a/documentation/12-module-versioning.md b/documentation/12-module-versioning.md index 590e2c4..4e5c9b2 100644 --- a/documentation/12-module-versioning.md +++ b/documentation/12-module-versioning.md @@ -3,17 +3,18 @@ Zest tracks module versions through one machine-readable manifest: ```text -backend/module_versions.json +module_versions.json +VERSION_LOG.md ``` -That file is the production source of truth. It is packaged with the Cloud Run backend, exposed through `GET /version`, and checked by the Android release guard so new source modules cannot be added without an explicit version entry. +The root manifest is the production source of truth. The root version log records why release and module versions changed. The manifest is packaged with the Cloud Run backend, exposed through `GET /version`, and checked by the Android release guard so new source, documentation, or agent-guidance modules cannot be added without an explicit version entry. ## Current Module Versions | Module ID | Kind | Path | Version | Runtime Surface | | --- | --- | --- | --- | --- | -| `android-app` | android-gradle-module | `:app` | `1.0.1` | Android `BuildConfig.VERSION_NAME` | -| `backend-proxy` | cloud-run-service | `backend` | `1.0.1` | FastAPI `app.version` and `GET /version` | +| `android-app` | android-gradle-module | `:app` | `1.0.2` | Android `BuildConfig.VERSION_NAME` | +| `backend-proxy` | cloud-run-service | `backend` | `1.0.2` | FastAPI `app.version` and `GET /version` | | `analysis` | android-package | `app/src/main/java/com/b2/ultraprocessed/analysis` | `1.0.1` | module version manifest | | `barcode` | android-package | `app/src/main/java/com/b2/ultraprocessed/barcode` | `1.0.0` | module version manifest | | `camera` | android-package | `app/src/main/java/com/b2/ultraprocessed/camera` | `1.0.0` | module version manifest | @@ -24,6 +25,8 @@ That file is the production source of truth. It is packaged with the Cloud Run b | `storage` | android-package | `app/src/main/java/com/b2/ultraprocessed/storage` | `1.0.0` | module version manifest | | `ui` | android-package | `app/src/main/java/com/b2/ultraprocessed/ui` | `1.0.1` | module version manifest | | `backend-prompts` | backend-contract-assets | `backend/prompts` | `1.0.3` | backend-owned prompt files | +| `documentation` | repo-documentation | `documentation` | `1.0.0` | repo documentation and handoff docs | +| `agent-context` | repo-agent-guidance | `AGENTS.md` | `1.0.0` | `AGENTS.md` and `.cursor/rules/zest-project.mdc` | ## Production Tracking Contract @@ -31,13 +34,16 @@ That file is the production source of truth. It is packaged with the Cloud Run b - Every top-level Android package under `app/src/main/java/com/b2/ultraprocessed` must have one manifest entry with `kind = android-package`. - Every deployable backend service must have one manifest entry with a runtime endpoint that can report the deployed version. - Backend prompt contracts are versioned separately from the backend service because prompt changes can alter model behavior without changing API transport. +- Documentation and agent guidance are versioned because they are now production handoff surfaces for future agents. - Documentation must include each manifest module ID and version. +- `VERSION_LOG.md` must include the current `releaseVersion` and the module versions changed by that release. ## Verification Android `verifySourceTreeForBuild` runs `verifyModuleVersionManifest`. The task fails when: -- `backend/module_versions.json` is missing or invalid, +- root `module_versions.json` is missing or invalid, +- root `VERSION_LOG.md` is missing the current release or changed module versions, - a top-level Android package exists without a version entry, - a version entry points to a missing path, - a Gradle module exists without a manifest entry, @@ -55,5 +61,9 @@ Backend tests verify: - Bump `backend-proxy` when changing request validation, endpoint behavior, model configuration, response contracts, deployment config, auth, or observability. - Bump `backend-prompts` when changing prompt instructions, schemas, examples, model-output expectations, or chat safety behavior. - Bump an Android package module when changing public behavior owned by that package. +- Bump `documentation` when changing production docs, handoff docs, architecture guidance, or testing/release instructions. +- Bump `agent-context` when changing `AGENTS.md`, Cursor rules, or other agent bootstrap instructions. + +Every change must also update the relevant documentation summary and extract any durable philosophy or architecture decision into `documentation/14-decision-log.md`. If the change affects how future agents should work, update `documentation/13-agent-brief.md`. All module versions use semantic versioning. For coordinated releases, `releaseVersion` should match the app version shipped to users. Individual modules can move faster only when a change is internal and does not require a full app release. diff --git a/documentation/13-agent-brief.md b/documentation/13-agent-brief.md new file mode 100644 index 0000000..60f19f6 --- /dev/null +++ b/documentation/13-agent-brief.md @@ -0,0 +1,78 @@ +# Agent Brief + +This is the short handoff for agents working in Zest. Use it as the first read, then open the linked subsystem document only when your task touches that area. + +## Product And Architecture + +Zest is a native Android app that helps grocery shoppers understand packaged-food ingredient labels. It shows a NOVA-style classification, corrected ingredient list, ultra-processed markers, allergens, confidence, warnings, and result-scoped chat. + +Runtime flow: + +- Camera/gallery image scans run ML Kit OCR on device. +- Images never go to an AI provider. +- Android sends extracted ingredient text, barcode/product hints, or current result chat context to the backend. +- Backend runs Gemini through Vertex AI using Cloud Run service-account auth. +- The default backend model is `gemini-3.5-flash`. +- `/analyze` and `/chat` are separate endpoints with separate backend-owned prompts. +- Scan data is session-only and is not persisted by the app. + +## Core Decisions To Preserve + +- API-only analysis: no rule-based NOVA fallback in runtime. +- Backend proxy: users do not enter AI API keys. +- Backend-owned prompts: Android never sends prompts, schemas, or model instructions. +- Single-call analysis: `/analyze` returns NOVA, corrected ingredients, ultra-processed markers, allergens, usage, and model id in one structured response. +- Result chat: `/chat` receives the current result, current-session chat history, and one user question; it must stay scan-scoped. +- Privacy: do not persist or log scan images, OCR text, ingredients, results, chat, usage, or failures. +- Storage archive: former Room/history code stays under `documentation/code-archive/session_only_storage/` and must not be restored without a product privacy decision. +- UI: allergens are separate from processing markers; ingredient bubbles are based on corrected ingredient names and ultra-processed marker matches. +- Production risk: public unauthenticated backend endpoints are a known deferred risk and require abuse controls before broad launch. + +## Where To Look + +- Product scope: `documentation/00-product-requirements.md` +- Architecture: `documentation/01-architecture.md` +- UI/navigation: `documentation/02-ui-navigation.md` +- Camera/OCR/barcode: `documentation/03-camera-ocr-barcode.md` +- Analysis pipeline: `documentation/04-classification-analysis.md` +- Storage/security: `documentation/06-storage-security.md` +- Testing/release: `documentation/07-testing-release.md` +- LLM contracts: `documentation/08-llm-api-contracts.md` +- Roadmap/cautions: `documentation/09-todo-roadmap.md` +- Maintenance: `documentation/11-maintenance-plan.md` +- Module versioning: `documentation/12-module-versioning.md` +- Decision log: `documentation/14-decision-log.md` +- Backend: `backend/README.md` + +## Implementation Guardrails + +- Prefer existing package boundaries: `ui`, `analysis`, `network/llm`, `network/usda`, `ocr`, `camera`, `storage/preferences`, and `storage/secrets`. +- Keep prompts in `backend/prompts/`. +- Keep benchmark data in backend-owned benchmark files, not app runtime code. +- Keep transient image cleanup intact after success, failure, result close, teardown, and relaunch cleanup. +- Do not add persistent diagnostics unless they are privacy-safe and contain no user scan content. +- Any new module or top-level Android package must be added to root `module_versions.json`, root `VERSION_LOG.md`, and `documentation/12-module-versioning.md`. +- Every change must update the relevant summary documentation, extract durable decisions into `documentation/14-decision-log.md`, and update this brief when future agents need the new guidance. +- Version-affecting changes must update root `module_versions.json`, root `VERSION_LOG.md`, and `documentation/12-module-versioning.md`. + +## Verification Defaults + +Run the smallest relevant set: + +```bash +./gradlew :app:verifySourceTreeForBuild :app:compileDebugKotlin +./gradlew :app:testDebugUnitTest +.venv/bin/python -m pytest backend/tests/test_app.py backend/tests/test_benchmark_analyze.py -q +git diff --check +``` + +For backend latency/NOVA checks against a deployed service: + +```bash +python backend/benchmark_analyze.py \ + https://ultraprocessed-ai-proxy-894254677159.us-east1.run.app \ + --iterations 1 \ + --details +``` + +Use `--strict-nova` only when you want benchmark mismatches to fail the command. diff --git a/documentation/14-decision-log.md b/documentation/14-decision-log.md new file mode 100644 index 0000000..817767c --- /dev/null +++ b/documentation/14-decision-log.md @@ -0,0 +1,20 @@ +# Decision Log + +This file summarizes the decisions most likely to guide future agent work. Detailed background remains in the linked subsystem docs. + +| Decision | Status | Rationale | Consequence | Sources | +| --- | --- | --- | --- | --- | +| Use API-only NOVA analysis, with no runtime rule-based fallback. | Active | Food classification should stay model-contract driven and testable through backend responses. | If the backend or model fails, the app fails explicitly instead of inventing a result. | `documentation/01-architecture.md`, `documentation/08-llm-api-contracts.md` | +| Use a Cloud Run backend proxy for AI calls. | Active | Users should not supply AI API keys; Vertex auth belongs to the runtime service account. | Android sends text/context only and never stores Gemini credentials. | `backend/README.md`, `documentation/08-llm-api-contracts.md` | +| Keep `/analyze` and `/chat` as separate endpoints. | Active | Analysis and result chat have different prompts, schemas, validation, and safety scope. | Do not multiplex chat through `/analyze`; keep backend-owned prompts separate. | `backend/README.md`, `documentation/08-llm-api-contracts.md` | +| Keep prompts backend-owned. | Active | Prompt/schema changes should deploy with backend contract control, not mobile releases or user input. | Android must not send prompt text, schemas, or model instructions. | `backend/README.md`, `documentation/08-llm-api-contracts.md` | +| Use one structured Gemini call for full analysis. | Active | The previous staged prompt stack added latency and parsing risk. | `/analyze` must produce NOVA, corrected ingredients, markers, and allergens in one structured response. | `backend/README.md`, `documentation/performance_benchmark.md` | +| Default to `gemini-3.5-flash`. | Active | It is the current stable Gemini Flash model selected for production tracking. | Cloud Run `GEMINI_MODEL` should be `gemini-3.5-flash`; benchmarks should record model changes. | `backend/README.md`, `documentation/12-module-versioning.md` | +| Enforce no human data storage beyond session. | Active | The product promise excludes retained scan content and logs. | Do not persist scan images, OCR, results, chat, usage, failures, or diagnostic request bodies. | `documentation/00-product-requirements.md`, `documentation/06-storage-security.md` | +| Archive, do not delete, former Room/history capability. | Active | The code remains useful reference material but conflicts with the current privacy policy. | Archived files live under `documentation/code-archive/session_only_storage/` and are outside Android source sets. | `documentation/06-storage-security.md` | +| Keep captured/imported images transient. | Active | Images are needed for OCR and optional active-result display, but not beyond the session. | Image cleanup must run after success, failure, result close, teardown, and relaunch cleanup. | `documentation/03-camera-ocr-barcode.md`, `documentation/06-storage-security.md` | +| Keep allergens separate from processing markers. | Active | Allergen detection is not the same signal as ultra-processing. | Do not color ingredients red because they are allergens; show allergens in their own block. | `documentation/04-classification-analysis.md`, `documentation/08-llm-api-contracts.md` | +| Track module versions in the repo root. | Active | Agents and releases need an objective production version surface that is not hidden inside the backend service directory. | Update root `module_versions.json`, root `VERSION_LOG.md`, and `documentation/12-module-versioning.md` when module behavior changes. | `documentation/12-module-versioning.md`, `app/build.gradle.kts` | +| Require every change to leave a summarized handoff trail. | Active | Future agents need the decision philosophy, not only the code diff. | Each change must update relevant docs, decision log, agent brief, and version log when applicable. | `AGENTS.md`, `.cursor/rules/zest-project.mdc` | +| Treat public unauthenticated backend access as deferred risk. | Open caution | Current Cloud Run deployment can be public during testing/limited rollout, but broad production needs abuse controls. | Add App Check / Play Integrity, auth/IAM gateway, Cloud Armor, quotas, rate limits, or equivalent before broad launch. | `backend/README.md`, `documentation/09-todo-roadmap.md` | +| Prefer compact agent bootstrap docs over duplicated handbook content. | Active | Long-form docs already exist; agents need a fast route into current constraints. | Keep `documentation/13-agent-brief.md`, this log, `AGENTS.md`, and Cursor rules short and link outward. | `documentation/README.md` | diff --git a/documentation/README.md b/documentation/README.md index 04f1e22..e8b1b8e 100644 --- a/documentation/README.md +++ b/documentation/README.md @@ -4,6 +4,8 @@ This folder is the handoff surface for Zest. Each document explains one producti If you are not an Android developer, start with [00-android-app-guide.md](00-android-app-guide.md). It explains the project with diagrams, file maps, and plain-language Android concepts. +Repo-level agent and version entrypoints live at [../AGENTS.md](../AGENTS.md), [../module_versions.json](../module_versions.json), and [../VERSION_LOG.md](../VERSION_LOG.md). + ## Document Map - [00-product-requirements.md](00-product-requirements.md) - product problem, scope, scan-session definition, requirements, and acceptance criteria. @@ -19,7 +21,9 @@ If you are not an Android developer, start with [00-android-app-guide.md](00-and - [09-todo-roadmap.md](09-todo-roadmap.md) - engineering and product backlog, including centralized navigation stack work for v2. - [10-responsible-ai-review.md](10-responsible-ai-review.md) - concise review of harmful gender, language, geographic, and socioeconomic behavior. - [11-maintenance-plan.md](11-maintenance-plan.md) - post-launch ownership, cadence, incident handling, patch policy, rollback, and support operations. -- [12-module-versioning.md](12-module-versioning.md) - module version manifest, production tracking contract, and verification rules. +- [12-module-versioning.md](12-module-versioning.md) - root module version manifest, root version log, production tracking contract, and verification rules. +- [13-agent-brief.md](13-agent-brief.md) - short first-read handoff for agents and new contributors. +- [14-decision-log.md](14-decision-log.md) - summarized architecture and product decisions that future agents must preserve. - [performance_benchmark.md](performance_benchmark.md) - deployed backend response-time measurements, bottleneck analysis, and latency improvement plan. ## Current Product Contract @@ -110,15 +114,17 @@ flowchart TB ## Reading Order For A New Engineer -1. Read [00-product-requirements.md](00-product-requirements.md). -2. Read [00-android-app-guide.md](00-android-app-guide.md). -3. Read [01-architecture.md](01-architecture.md). -4. Read [02-ui-navigation.md](02-ui-navigation.md). -5. Read [04-classification-analysis.md](04-classification-analysis.md). -6. Read [06-storage-security.md](06-storage-security.md). -7. Read [07-testing-release.md](07-testing-release.md). -8. Read [09-todo-roadmap.md](09-todo-roadmap.md) before planning v2 work. -9. Read [11-maintenance-plan.md](11-maintenance-plan.md) when preparing a release or handling an operational issue. +1. Read [13-agent-brief.md](13-agent-brief.md). +2. Read [14-decision-log.md](14-decision-log.md). +3. Read [00-product-requirements.md](00-product-requirements.md). +4. Read [00-android-app-guide.md](00-android-app-guide.md). +5. Read [01-architecture.md](01-architecture.md). +6. Read [02-ui-navigation.md](02-ui-navigation.md). +7. Read [04-classification-analysis.md](04-classification-analysis.md). +8. Read [06-storage-security.md](06-storage-security.md). +9. Read [07-testing-release.md](07-testing-release.md). +10. Read [09-todo-roadmap.md](09-todo-roadmap.md) before planning v2 work. +11. Read [11-maintenance-plan.md](11-maintenance-plan.md) when preparing a release or handling an operational issue. ## What To Avoid diff --git a/backend/module_versions.json b/module_versions.json similarity index 83% rename from backend/module_versions.json rename to module_versions.json index 01b33a8..53d0d44 100644 --- a/backend/module_versions.json +++ b/module_versions.json @@ -1,20 +1,20 @@ { "schemaVersion": 1, "product": "Zest", - "releaseVersion": "1.0.1", + "releaseVersion": "1.0.2", "modules": [ { "id": "android-app", "kind": "android-gradle-module", "path": ":app", - "version": "1.0.1", + "version": "1.0.2", "runtimeSurface": "Android BuildConfig.VERSION_NAME" }, { "id": "backend-proxy", "kind": "cloud-run-service", "path": "backend", - "version": "1.0.1", + "version": "1.0.2", "runtimeSurface": "FastAPI app.version and GET /version" }, { @@ -86,6 +86,20 @@ "path": "backend/prompts", "version": "1.0.3", "runtimeSurface": "backend-owned prompt files" + }, + { + "id": "documentation", + "kind": "repo-documentation", + "path": "documentation", + "version": "1.0.0", + "runtimeSurface": "repo documentation and handoff docs" + }, + { + "id": "agent-context", + "kind": "repo-agent-guidance", + "path": "AGENTS.md", + "version": "1.0.0", + "runtimeSurface": "AGENTS.md and .cursor/rules/zest-project.mdc" } ] }