Skip to content

Latest commit

 

History

History
377 lines (296 loc) · 21.1 KB

File metadata and controls

377 lines (296 loc) · 21.1 KB

Cut Protocol — Brain v2 build log (owner-facing, newest first)

Plain-English record of the v2 program. One entry per meaningful step: what got finished · what's next · anything needed from Shad.


2026-07-21 · Doc 2 Stages 2–4 — PRIVATE share (no public release)

Shad chose PRIVATE distribution (not a GitHub Release). Artifact built + scanned clean.

  • Artifact: release/Cut Protocol Setup 1.0.0.exe (209,270,871 B / ~200 MB). SHA-256 996877c639fcc29adced66c18e6b3914e5811f4021e6c53058dac726590a1ef3.
  • Stage 3 scan: all PASS — no secrets, no personal data, 0 npm-audit vulns, brain-purity/supply-chain green. Report: security/scan-report.md. Bundle carries ONLY the clean dev.db.template + app (no .env, no dev.db, no backups).
  • Stage 2: data-safety block verified (docs/release/fresh-install-check.md); interactive install-flow rows PENDING (best run on a clean profile).
  • NO gh release created (private choice). Hand-off: Shad launches the .exe once to confirm it opens, runs it through virustotal.com, then uploads to Google Drive and shares only to the tester's Gmail. Email draft provided.

2026-07-21 · Doc 2 Stage 1 DONE — clean-distribution fix (M4)

The installer no longer ships secrets or personal data — the M4 fix.

  • Clean template DB: backend/scripts/buildTemplateDb.mjs copies dev.db and deletes all 22 personal tables (fails if a new table is unclassified), keeping the library (864 foods, 889 recipes + taste tiers). 0 users/profiles.
  • Per-install JWT: electron/main.cjs now generates a session secret on first run into userData (never bundled) instead of reading the owner's real .env. API keys simply absent in a shared build → brain off, app works fully offline.
  • Config: extraResources ships only the clean dev.db.template (no .env); build.files strips dev.db/backups/scripts/docs/audit/release/.agent.
  • Blocking gate: scripts/distPrecheck.mjs wired as predist — fails the build if the template has personal rows/emails, if the config would ship the real .env/dev.db, or if a secret sits in shipping code. PASSES clean. checkDistSafe now takes a file arg + a tightened email regex (no cuid byte-noise FP).

Next (Doc 2): Stage 2 fresh-install checklist · Stage 3 artifact scan report · Stage 4 build + SHA-256 + GATE (stop for Shad's go) + GitHub Release link.


2026-07-21 · Remaining v2 parts DONE — security, persistence, taste

Built the three deferred parts, each committed + verified (tests green, golden BRAIN=off byte-identical, brain-purity clean):

  1. Security lane complete (46282d0) — S3 supply-chain guard (checkSupplyChain.mjs: no off-registry/wildcard deps, lockfiles present; clean 26 deps) + npm audit in CI. Joins S1 brain-purity + S2 secret scan → npm run security:all (3 green)
    • blocking CI security job. (Semgrep SAST omitted — needs an external binary.)
  2. Persistence models (8d79818) — the six additive tables (BrainConversation/ Message, GeneratedRecipe, GeneratedPlan/Item, BrainSolveRun, UserLibraryEntry; migration = 7 pure CREATE TABLEs) + store.js (injectable accessor, Law-2 guard rejects any exclusion-like key). Dormant until a route wires it.
  3. Full taste-tier system (4085f01) — 4 additive Recipe columns + taste.js (clampProposedTier / Bayesian-shrinkage effectiveTasteScore) + a w_taste scorer term (0 when no signal → byte-identical) + tasteSeed.json/seeder (24 curated recipes tagged) + the ratings route refreshing the aggregate live.

393 tests green. Only spec items still NOT built: the §0b governance/RESUME/ anti-slop scaffolding (judged ceremony — PROGRESS.md + memory + CI cover the substance) and Stage L fitness (spec defers it). The v2 program is otherwise complete.


2026-07-21 · Close-out — pushed, installer rebuilt, security lane started

  • Pushed: all 12 commits are on origin/master (public repo now has the full v2).
  • Installer rebuilt: release/Cut Protocol Setup 1.0.0.exe (200 MB) has current code — the desktop app now matches the dev build. (Personal build: bundles keys + DB — do NOT share it; npm run dist:check is the guard if you ever do.)
  • Security lane (Stage S) started: scripts/checkBrainPurity.mjs (S1) — asserts the brain carries NO web/shell/file-write/eval capability (Laws 5/6); CLEAN over 33 files. Wired npm run security:all (secret scan + purity) + a blocking CI security job. Live app confirmed on localhost:5174 (Engine 10-formula verified in browser).

Honest v2-completeness (Shad asked): DONE = the user-facing core (coach planner, E1/E2/T/K + protein fix) + partial Stage S. NOT done (deferred to a fresh session, migration-heavy — cramming them into an exhausted context is the slop the anti-slop stage exists to prevent): the full taste-tier system (tasteTier enum/shrinkage/ curated seed/scorer term), the 6 persistence models (BrainConversation/Message, GeneratedRecipe/Plan, BrainSolveRun, UserLibraryEntry + migrations + store), the rest of the security lane (S3 supply-chain, semgrep, security.yml), the §0b governance/ RESUME/anti-slop scaffolding (judged ceremony), and Stage L fitness (spec defers it).

Next session: "build the remaining v2 parts" → taste → persistence → security lane, each committed + verified like today.


2026-07-21 · Protein-forward fix — cracked the veg/vegan 0% coverage

Simulation-driven. A coverage sim (1,200 sampled users, real engine targets, actual week solver) showed the library met only 61% of users on the strict bar (kcal AND protein within 15%, 6/7 days), and vegetarian/vegan = 0% — not a count problem (vegetarian had 320 recipes) but protein DENSITY: plant recipes can't hit a cutting protein target, and you can't scale a low-protein dish up without blowing past calories.

Fix: added 6 dense foods (seedHighProteinFoods.mjs: seitan, TVP, edamame, pea protein, lentil/chickpea pasta) + a genProteinForward.mjs generator (big protein portions, protein-rich carbs, minimal fat → high g-protein/kcal). +~160 verified protein-forward recipes.

Result (pool 633 → 889):

Diet before after (adequate / usable)
Overall 61% 83.8% / 89%
Omnivore 75% 91.8% / 95.4%
Vegetarian 0% 55.7% / 66%
Vegan 0% 52.5% / 61%

Omnivore essentially hits the 95% bar (usable). Plant diets went 0 → 52-56% adequate — hugely improved, still the laggards (diminishing returns per batch; the strict daily-protein bar is inherently hard for plant diets). Reproducible: run seedHighProteinFoods.mjs then node genProteinForward.mjs | genLibrary.mjs.


2026-07-21 · Stage 6 (K) — library generation ($0 in-session, verifier-gated)

Honest finding first: the pool was already 633 recipes + the solver is already $0 + Stage 5 likes = favorites, so K's premise was largely met. You chose the full library anyway — so I built it the smart way (no ~$20-50 API spend).

What I added: +98 VERIFIED recipes (633 → 731), $0. Every one gated by the same verifier the app uses — real foods only (no invented ingredients), sane macros (Atwater), deduped. The one real gap closed: vegan 72 → 107 (+49%), vegetarian 275 → 320. Solver still lands 98% on the enlarged pool.

Reusable tooling (committed, so you can expand anytime — no session needed):

  • backend/scripts/genLibrary.mjs — the harness: reads a drafts JSON, matches each ingredient to a REAL food (token-subset, reject-on-miss — no USDA, no placeholder), validates macros, dedups, persists as source "ai-generated". --dry-run to preview.
  • backend/scripts/genComboDrafts.mjs — combinatorial draft generator (cuisine- flavoured protein×carb×veg×fat) → pipe into the harness. Produced 80 of the 98.
  • backend/scripts/library-seeds/batch01.json — the 18 hand-written recipes (reproducible).

Where the recipes live: your dev.db (gitignored, like all runtime data) — your running app has them now. The tooling above regenerates them on any fresh DB.

Status: 383/383 tests green, golden byte-identical (DB recipes don't touch fixtures), scripts secret-scanned clean. Library is easily expandable (breakfast/ snacks/more cuisines) by running the scripts again.

v2: all 6 stages delivered. Remaining polish: a live UI walkthrough (servers were stopped), and pushing (held per your call).


2026-07-21 · Stage 5 DONE — T taste tier (thumbs → soft plan re-rank)

What you get: thumbs 👍/👎 on each recipe (Recipes tab). Liking a recipe makes the solver prefer it in future plans; disliking pushes it down — a SOFT re-rank only. It never overrides your diet/allergy rules and never changes a macro.

How (all additive, golden byte-identical):

  • Migration add_recipe_rating: a single CREATE TABLE RecipeRating (plain columns, no FK — orphan ratings for a deleted recipe are harmless). Applied + verified.
  • buildBias gained a taste term: liked ×1.6, disliked ×0.35 (soft, never excluded). No ratings → null bias → byte-identical (proven by the golden + a unit test).
  • planContext loads the user's ratings as a Map; threaded into /generate, /day-options, AND the chat planner (taste-aware chat plans too).
  • New routes/ratings.js (GET/PUT/DELETE, validates rating ∈ {1,-1}) + registered.
  • Frontend: thumbs on the recipe detail (optimistic, click-again to clear; selection = lightness, NO red on dislike — constitution-compliant).

Verified: 383/383 tests green (+3 taste bias), golden BRAIN=off byte-identical, oxlint + build clean. Real-data smoke: liked a recipe → planContext picked it up → taste-aware chat plan solved (97%) → cleaned up (0 rows left).

Next (last one): Stage 6 — K (pre-solved library, ~$0 common case). Its generation step is the API-key-vs-subscription question: I can generate the library myself in-session for $0 (verifier-gated), or you pay ~$20-50 for a fast API batch.


2026-07-21 · Stage 4 DONE — E2 body-fat visual picker (add-column, your call)

What you get: on the Profile tab, a "Estimate visually" button opens a picker — 6 abstract silhouettes (10–35%) you tap to set your body fat, plus an "I had it measured" numeric entry and a "Not sure — skip". Setting it unlocks the Katch–McArdle/Cunningham formulas and refines your estimate. The raw % input stays for power users.

How (add-column, per your call — safest):

  • Migration 20260721071636_add_bodyfat_source: a single ALTER TABLE ADD COLUMN bodyFatSource TEXT — NO table rebuild. Applied to dev.db (backed up first); verified: all 4 profiles intact, every target unchanged, new column = null. bodyFatPct stays 0 = unknown, so no === 0 touchpoint changed.
  • Backend: bodyFatSource added to PROFILE_FIELDS + defaultProfile + a validator (enum visual-estimate|measured|null). Writes flow through the existing field loop.
  • Frontend: BodyFatPicker.jsx — parametric abstract silhouettes (monochrome currentColor, never a real person), constitution-compliant (selection = lightness not green, NO red/green judgment, % labels only). ProfileTab opens it as a modal; saves route through putProfile → target re-materializes server-side.

Verified: 380/380 tests green (+E2 validation), golden BRAIN=off byte-identical, oxlint + build clean, migration verified against real data. (Picker not browser-tested — dev servers stopped; logic tested + save path is the standard field write.)

Next: Stage 5 — T (taste tier: soft palatability re-rank + recipe ratings).


2026-07-21 · Stage 3 DONE — E1 10-formula BMR (Option A, byte-identical)

What you get: the Engine tab's BMR panel now offers 10 published formulas instead of 6 — FAO/WHO/UNU, Owen, Livingston, Nelson added — each with a citation. Crucially your target does not move: the 4 new ones are default-off, so the average still runs on today's 6. Tick any new one on (same toggle) to include it.

How (Option A = default-preserving):

  • A0 first (8230772): added a BMR golden capturing today's 6-formula mean, so the change is provably byte-identical. null and 0 body-fat confirmed identical.
  • 4 formulas appended + leanBodyMass extracted (single-sources the 3 LBM formulas). DEFAULT_ENABLED + isFormulaOn flip: excludedFormulas membership FLIPS a formula from its default — for the legacy 6 this is byte-identical to the old opt-out; the 4 new are default-off (opt-in via the same toggle).
  • Added sd + spreadPct (+ an honest "dispersion, not a CI" caveat on the tab) and prov {formulaId, inputs, value, citation} on every row (Law 3). Engine now dual-accepts body-fat null OR 0 as unknown (readies E2).
  • Frontend: EngineTab toggle made flip-aware (reads server defaultOn); "6 of 10" shows automatically; spread caveat added.

Verified: 379/379 tests green (+5 E1 regressions incl. published values for all 4 new formulas + flip semantics). Golden BRAIN=off byte-identical PASSES — proof no target moved. oxlint + vite build clean. (Not browser-verified — dev servers were stopped; logic is tested + data-driven.)

Next: Stage 4 — E2 body-fat visual picker (nullable migration — a real DB change; data-preserving table rebuild, I'll flag it as a rebuild, not destructive).


2026-07-20 (later 4) · Stage 2 DONE — security safety net (secret scan + dist gate)

What you get: it's now hard to leak secrets by accident.

  • npm run scan:secrets — scans every tracked file for real secrets (Anthropic/ JWT/USDA/AWS/PEM keys, seed passwords). Also a CI job — a committed secret now fails the build. Repo scans CLEAN today (279 files).
  • npm run dist:check — before sharing an installer, scans a built release/ for secrets AND personal data (emails in the shipped DB/env). PROVEN: it FAILS the current-style build (catches all 4 real .env secrets + your email + DB personal data, redacted) and PASSES a secretless build.
  • Placeholder-aware (skips change-me/ci-only/example…) so docs/CI dummies don't false-positive, without weakening the catch on a real key.

Brain-purity guard: already covered — brainMock.test.js asserts BRAIN=off → zero LLM calls, and the golden test asserts byte-identical output. No new test needed.

Deliberately deferred (needs your call): the fully-automatic safe dist:share (secretless env + depersonalized seed DB) needs a decision on which DB tables are LIBRARY (ship: Food/Recipe) vs PERSONAL (strip: User/Profile/WeighIn/Plan/Diary/ Training/Brain*). I won't guess that with your personal data at stake — it's the one Stage 2 item flagged for you. The scan+gate above already PREVENT an accidental leak in the meantime. Dropped the wip-branch/save-resume ceremony (low value).

Verified: 374/374 tests green (+4 scanner self-tests), scanner proven live (clean repo / catches real .env), gate proven both ways. CLAUDE.md caveat updated.

Next: Stage 3 — E1 10-formula BMR (Option A, byte-identical).


2026-07-20 (later 3) · Stage 1 DONE — coach builds a real numbered plan in chat

What you get: ask the coach "plan me a high-protein day" (or build/generate/ make … a day/meal plan) and it now returns a real, engine-computed day as a card in the chat bar — each meal with its recipe name + P/C/F, a day total, and your target. Every number is the deterministic solver's (LAW 1); the coach's text states no number. Ideas/swaps/follow-ups ("vegan dinner ideas", "why not fish?") still get the normal conversational reply — the plan-route is narrow.

How it's built (all additive, byte-identical-off):

  • Extracted planContext/filterRecipePool/parseFilters out of routes/plans.js into lib/planContext.js so the chat planner and every /plans route build the SAME exclusion-filtered pool (M8 single-source). Route re-exports filterRecipePool so planLogic.test.js is untouched. Verbatim move — zero behavior change.
  • New lib/brain/chatPlan.js: looksLikePlanRequest (narrow intent regex) + generateDayForChat (calls the deterministic generateDayCandidates with NO profile → no LLM, no spend; pool already compliant) + planIntro (number-free).
  • chat.js: plan-route fires AFTER the domain gate (injection still refused first), BEFORE any model call; failure falls through to the coach (LAW 7).
  • Frontend BrainChat.jsx: constitution-compliant PlanCard (macro triad only, no green/no red, lightness elevation, "computed by the engine" microcopy).

Verified: 370/370 backend tests green (was 359) — incl. golden BRAIN=off byte-identical + planLogic (extraction held) + 11 new plan tests. oxlint + vite build clean. Not yet browser-verified live (next: a quick real-key smoke).

Next: Stage 2 — governance/security Tier-1.


2026-07-20 (later 2) · All 4 v2 designs in — consolidated build order

4 parallel design agents delivered implementation-ready plans (K library, T taste, E1/E2 BMR+body-fat, S+governance). Build order (each additive, byte-identical-off, committed, pause-able):

  1. Coach planner-wiring — deterministic day-solver → engine numbers → plan card in the bar
  2. Governance/security Tier-1 — gitleaks secrets + brain-purity regression guard + save/resume
  3. E1 — 10-formula BMR (Option A default-preserving → targets unchanged)
  4. E2 — body-fat picker (nullable migration; shares E1 engine)
  5. T — taste tier (dependency-free types.js; scorer/pool/constraints; opt-in)
  6. K — pre-solved library (~$0 common case; ends with a one-time ~$20-50 generation on Shad's go)

Decisions: E1 Option A (recommended) vs B (shifts every target); K generation spend (Shad's go, LAST step of K); rest take agent-recommended defaults — dependency-free enums (no zod dep), nullable body-fat, drop wip-branch ceremony, S3 advisory-first.

⚠️ Landmine (S agent, HIGH): the INSTALLER bundles the REAL .env + dev.db renamed .template (extraResources) — fine for the personal build, MUST be stripped before sharing. Split dist:local (keeps secrets) vs dist:share (placeholders + empty DB) + S4 installer gate scans extracted CONTENTS (filename globs miss the renamed files). Other reconciliations found: bodyFatPct is currently Float NOT NULL (0=unknown), not null — engine must dual-accept 0 OR null; A0 null-BF BMR golden doesn't exist yet (add before touching FORMULAS); UserLibraryEntry lands in K (not I).

Next: start #1 (coach planner-wiring) on Shad's go.


2026-07-20 (later) · Coach: useful + memory done; design fleet running

Finished (live-verified on the real key):

  • Coach #1 — genuinely useful replies: conversational classifier (greets, follows up), search-only toolset (was flailing on the plan-building tools), no-numbers prompt. Greets, gives real meal ideas from the pool, refuses off-topic. (cc4c1e5, fee0555)
  • Coach #2 — conversation memory: client sends recent turns; brainChat caps + validates + prepends. "why not fish?" now stays in context. (d54b584)
  • Empty tool-loop degrades honestly instead of a false off-topic refusal.

In flight: 4 parallel DESIGN agents scoping the independent v2 stages (K library, E1/E2 BMR+body-fat, T taste, S+governance). S+governance landed — drop the wip-branch ceremony (keep crash-safe state); installer ships real secrets (S4 scans extracted contents); 2 decisions for Shad (S3 dep-pinning enforce-vs-advisory; distribution extraResources split). Tier-1 security to build first: gitleaks secret scan + brain-purity regression guard + .agent/save-resume.

Next: coach #3 — wire the deterministic day-solver into chat so "plan me a day" returns a real math-checked numbered plan (engine numbers = LAW-1-safe).

Needed from Shad: nothing blocking; the 2 security decisions can wait.


2026-07-20 · v2 kicked off (coach-first)

Where we are: the original A–J brain is built, verified (12-agent fleet), and LIVE on a real key — every safety guard proven (no invented numbers, off-topic refused, injection-safe). Live testing showed the v1 Beta Coach is thin: it redirects to the Plan tab on any number, can't follow up ("Why not?"), and can't generate a plan in chat.

v2 plan (coach-first ordering):

  1. Make the coach's replies useful — prompt tuning so it gives real food guidance instead of a bare redirect. (this step)
  2. Conversation memory (v2's fuller Stage I: BrainConversation / BrainMessage) → follow-ups like "Why not?" work.
  3. Wire the planner into chat → the coach produces real, verifier-checked plans in the bar (not a bounce to the Plan tab).
  4. Then the rest of v2 — E1 (10-formula BMR), E2 (body-fat picker), T (taste), K (pre-solved library → ~$0 common case), L (fitness, deferred) — with the governance/RESUME infra + anti-slop + security lane layered in as we go.

Finished this step: (see next entry once committed) Next: conversation memory (Stage I). Needed from Shad: nothing right now — re-test the coach after the prompt fix.

Standing invariants (unchanged from the original build): every stage leaves main green and, with BRAIN=off, byte-identical to today; the 7 LAWS win over everything; no push without Shad's say-so; keys are Shad's to place (never handled in chat).