# MEMORY.md - Curated Long-Term Memory ## 🚨 NEVER BREAK THESE RULES 🚨 ### 0. NEVER MARK TASKS DONE WITHOUT VALIDATION — EVER ❌ **FORBIDDEN:** Saying "task is done" based on subagent report or assumption ✅ **REQUIRED:** I verify the deliverable MYSELF via API, file check, or screenshot **The Rule:** - Subagent says "done" → I say "VERIFYING" → Check via API/file/UI → THEN confirm - If I can't verify → "Task complete pending verification" → Ask how to confirm - NEVER trust "success" messages without seeing proof **Why:** I'm the one accountable. "The subagent said it worked" is not an excuse. --- ### 1. ALWAYS SEND FULL URLs TO GANTT TASKS — NEVER JUST IDs ❌ **FORBIDDEN:** "Task 33ebc71e-7d40-456c-8f98-bb3578d2bb2b is done" ✅ **REQUIRED:** "https://gantt-board.vercel.app/tasks/33ebc71e-7d40-456c-8f98-bb3578d2bb2b is done" **Format:** `https://gantt-board.vercel.app/tasks/{task-id}` **Why:** Matt needs clickable links on his phone. Sending IDs wastes his time. I have ZERO excuse for this. --- ### 2. EVERY WEB PROJECT MUST HAVE CLI TOOLS IN scripts/ — MANDATORY ❌ **FORBIDDEN:** Creating a web app without programmatic CLI access ✅ **REQUIRED:** Every project gets `./scripts/` folder with CRUD + attachment capability **The Rule - Non-Negotiable:** ``` /Users/mattbruce/Documents/Projects/OpenClaw/Web/{project-name}/ ├── scripts/ # MUST EXIST │ ├── crud.sh # MUST support: list, get, create, update, delete │ ├── attach-file.sh # MUST support: attach files to items │ └── .env.example # MUST document required env vars ``` **Implementation Pattern (Copy-Paste from Gantt Board):** 1. Copy `scripts/` from gantt-board: `cp -r /Users/mattbruce/Documents/Projects/OpenClaw/Web/gantt-board/scripts ./` 2. Update table names in scripts (e.g., `items` → `tasks` or `projects`) 3. Create `scripts/.env` with Supabase credentials 4. Test: `./scripts/crud.sh list` must return data 5. Commit: `git add scripts/ && git commit -m "Add CLI tools for AI access"` 6. Document: Add CLI section to README.md **Why:** If I can't access it via CLI, I can't work on it when Matt's remote. Browser automation requiring clicks is UNACCEPTABLE. **Project Readiness Checklist (BEFORE saying "project is ready"):** - [ ] `./scripts/crud.sh` exists and is executable - [ ] `./scripts/attach-file.sh` exists and is executable - [ ] `./scripts/crud.sh list` returns data successfully - [ ] `./scripts/.env` exists with working credentials - [ ] CLI usage documented in README.md - [ ] Scripts committed to git **If any item unchecked → PROJECT IS NOT READY.** --- ### 2.5. CLI MUST STAY IN SYNC WITH WEB UI — ALWAYS ❌ **FORBIDDEN:** Web UI has features the CLI can't access ✅ **REQUIRED:** Every web API endpoint has a matching CLI command **The Rule:** - Web UI can do it → CLI can do it. No exceptions. - When adding a web feature, add the CLI command in the SAME commit - When modifying an API, update the CLI script in the SAME commit - CLI is not an afterthought — it's part of the feature **Verification Process (BEFORE committing any API change):** ```bash # 1. List all API endpoints in the web app find src/app/api -name "route.ts" | xargs grep -l "export async function" # 2. Check that each endpoint has a CLI equivalent # GET /api/items → ./scripts/crud.sh list # POST /api/items → ./scripts/crud.sh create # PATCH /api/items/[id] → ./scripts/crud.sh update # POST /api/items/[id]/attachments → ./scripts/crud.sh attach # 3. Test the CLI actually works ./scripts/crud.sh list ./scripts/crud.sh create '{"title":"Test"}' # 4. If any API endpoint lacks CLI coverage → DO NOT COMMIT ``` **Feature Completion Checklist:** - [ ] Web UI feature implemented - [ ] API endpoint created/modified - [ ] CLI command added/updated to match - [ ] CLI tested and working - [ ] README.md updated with new CLI usage - [ ] All changes in SINGLE commit **Why:** If the web can do it but CLI can't, I can't automate it. I shouldn't need to open a browser to do something the web can do programmatically. --- ### 3. NEVER CLOSE/MARK TASKS AS DONE — MATT DOES THIS ❌ **FORBIDDEN:** Changing task status to "done" or "complete" ✅ **ALLOWED:** Attaching files, updating descriptions, adding comments **Matt and ONLY Matt marks tasks complete.** I handle the work, he handles the status. **VERIFY BEFORE ANY STATUS CHANGE:** - "Ready to mark this done?" - "Should I update the status?" - **Wait for explicit YES before touching status** ❌ **FORBIDDEN:** "Task 33ebc71e-7d40-456c-8f98-bb3578d2bb2b is done" ✅ **REQUIRED:** "https://gantt-board.vercel.app/tasks/33ebc71e-7d40-456c-8f98-bb3578d2bb2b is done" **Format:** `https://gantt-board.vercel.app/tasks/{task-id}` **Why:** Matt needs clickable links on his phone. Sending IDs wastes his time. I have ZERO excuse for this. --- ## Critical Information ### Who I Am - Name: Max - Role: Digital assistant to Matt Bruce - Mission: Help build iOS empire for retirement ### Matt's Identity - Name: Matt Bruce - Email: mbrucedogs@gmail.com - Work: iOS Lead Architect at Toyota (contractor) - Goal: Build side hustle to retire early, travel with Heidi ### Project Locations (ALWAYS CHECK TOOLS.md) All projects in: `/Users/mattbruce/Documents/Projects/OpenClaw/` **Active Web Projects:** - Gantt Board: https://gantt-board.vercel.app (port 3000) - Login: mbruce+max@topdoglabs.com / !7883Gantt - Stack: Next.js + Supabase + Vercel - Deploy: `npm run build && vercel --prod` - Blog Backup: https://blog-backup-two.vercel.app (port 3002) - Mission Control: https://mission-control-rho-pink.vercel.app/ (port 3001) - Heartbeat Monitor: port 3005 ### Infrastructure - Gitea: http://192.168.1.128:3000 (ai-agent / !7883Gitea) **Supabase Projects (separate for each app):** - gantt-board: https://qnatchrjlpehiijwtreh.supabase.co - Other projects: Each has their own Supabase project (see TOOLS.md) ### Key Decisions - All web projects use Supabase for auth/database - Vercel CLI deployment (no GitHub for gantt-board) - Project folder structure enforced (Web/iOS/Documents) ## Lessons Learned ### 2026-02-21 - Subagent Task Verification FAILURE **Problem:** iOS MRR Research task marked "done" but file was NOT attached to gantt board. Subagent created local file, didn't complete attachment step. **Root Cause:** Trusted subagent "success" without verifying the actual deliverable. "File created" ≠ "Task complete." **The Fuckup:** 1. Subagent: "File created at /path/to/file.md" → I heard "Task done" 2. Marked task complete in memory 3. Next session: You had to re-explain the problem 4. You'd already told me twice (see message history) **Resolution (2/22):** - Created `attach-file.sh` CLI script for file attachments - Attached iOS MRR file via Supabase API directly - Updated task status to done via CLI - Deleted local file (single source of truth now in gantt board) **Never Again:** - Subagent says "done" → I verify the actual requirement via API - For gantt attachments: Must confirm file is ATTACHED, not just created - Build CLI tools for anything I'll need to do repeatedly - **Rule:** If I can't do it via API/CLI, I can't do it reliably --- ### 2026-02-21 - Memory Failures **Problem:** Complete memory loss of previous day's work caused frustration. **Root Cause:** Didn't read files at session start, relied on failed memory_search. **Solution:** - Created SESSION_STARTUP.md with explicit checklist - Updated AGENTS.md with mandatory file reading order - All project info now in TOOLS.md - Created PROJECT_SETUP.md for folder structure rules **Never Again:** - Always read SESSION_STARTUP.md first - Read TOOLS.md for all project locations - Read memory files for recent context - Files are my memory - use them ### 2026-02-21 - Gitea Installation Disaster **Problem:** Installed Gitea locally on Matt's Mac, causing port 3000 conflict with Next.js dev server. **Root Cause:** Forgot Gitea was already running on separate machine (192.168.1.128:3000). **Solution:** Uninstalled local Gitea, documented in TOOLS.md that it's on another machine. **Never Again:** - Gitea runs at http://192.168.1.128:3000 (remote server) - Port 3000 is for Next.js dev server on Matt's Mac - NEVER run `brew install gitea` or `gitea web` on Matt's machine - Use existing Gitea server for all git operations ## Design Principle: API-First for AI Access **Every app I build MUST have programmatic access.** Browser automation requiring manual clicks defeats the purpose of having an AI assistant. | Approach | Effort for Matt | Reliability | |----------|-----------------|-------------| | **API/CLI** | Zero - I handle it | High | | **Database direct** (Supabase) | Zero - I query it | High | | **Browser relay** | High - must click to connect | Low | | **Desktop apps** | 100% - I can't touch them | N/A | **Rule for all future projects:** - ✅ REST API for all CRUD operations - ✅ CLI wrapper for scripted access - ✅ Database queries when API doesn't exist - ❌ No "I'll just use the browser" - that's asking Matt to babysit me **Gantt board example:** - Tasks: ✅ API exists → I can verify, update, complete without Matt - Attachments: ✅ NOW SOLVED - `attach-file.sh` CLI created 2/22 **CRITICAL: Gantt Board Must Work Remotely** - Matt accesses tasks from outside the house - I must attach files WITHOUT requiring browser clicks or manual intervention - CLI/API approach is the ONLY valid solution - Browser relay requiring extension clicks is UNACCEPTABLE for this use case **When planning a new app:** First question: "How will I (Max) interact with this programmatically without Matt's help?" --- ## Gantt Board CLI Tools (Working 2/22) **Location:** `/Users/mattbruce/Documents/Projects/OpenClaw/Web/gantt-board/scripts/` (IN PROJECT, VERSION CONTROLLED) **Rule:** CLI tools belong IN THE PROJECT DIRECTORY, not workspace scripts folder. They must be committed with the project or they'll get lost. **✅ CORRECTLY PLACED:** These scripts are now in the gantt-board project repo and committed. ### Reference Implementation (Gantt Board) **Source of truth for the pattern:** - **Location:** `/Users/mattbruce/Documents/Projects/OpenClaw/Web/gantt-board/scripts/` - **Files:** - `gantt.sh` - Unified CLI (API-based, all operations) - `gantt-task-crud.sh` - Direct Supabase CRUD - `attach-file.sh` - Direct Supabase file attachments - `view-attachment.sh` - View attached files **Usage (Unified CLI - covers ALL API endpoints):** ```bash # Tasks ./scripts/gantt.sh task list [status] # List tasks ./scripts/gantt.sh task get # Get task ./scripts/gantt.sh task create "Title" [status] [priority] # Create task ./scripts/gantt.sh task natural "Fix bug by Friday, high priority" # Natural language ./scripts/gantt.sh task update # Update field ./scripts/gantt.sh task delete # Delete task ./scripts/gantt.sh task comment "text" # Add comment ./scripts/gantt.sh task attach # Attach file # Projects & Sprints ./scripts/gantt.sh project list # List projects ./scripts/gantt.sh sprint list # List sprints # Auth ./scripts/gantt.sh auth session # Check session ./scripts/gantt.sh auth login # Log in ``` **Usage (Direct Supabase - works without web server):** ```bash ./scripts/gantt-task-crud.sh list [status] # List tasks ./scripts/gantt-task-crud.sh get # Get task ./scripts/attach-file.sh # Attach file ./scripts/view-attachment.sh [index] # View attachment ``` **How it works:** - `gantt.sh` uses the REST API (requires web server running) - Direct scripts use Supabase service role key (works offline) - Files stored as base64 data URLs in database **To copy to new project:** ```bash cp -r /Users/mattbruce/Documents/Projects/OpenClaw/Web/gantt-board/scripts \ /Users/mattbruce/Documents/Projects/OpenClaw/Web/{new-project}/ # Then update table names in the scripts ``` --- ## CLI/API Implementation Guide (Reference for Rule #2) **Every app I build MUST have programmatic access without browser automation.** This is non-negotiable. ### CRITICAL: Scripts Live INSIDE the Project Repo **NOT** in a shared workspace scripts folder. Each project owns its own CLI. ``` /Users/mattbruce/Documents/Projects/OpenClaw/Web/project-name/ ├── api/ # REST API routes (Next.js App Router) │ └── (auth)/ # Protected routes ├── lib/ │ ├── api-client.ts # Typed API client for internal use │ └── cli/ # CLI scripts directory │ ├── README.md # Usage docs │ └── crud.ts # Generic CRUD operations ├── scripts/ # CLI scripts LIVE HERE │ ├── crud.sh # Main CLI entry point │ └── attach-file.sh # File attachment script └── supabase/ # DB functions (if direct DB needed) ``` **Why inside the project:** - Version controlled with the project - Self-documenting (API + CLI in same repo) - Portable (clone repo, CLI works) - Project-specific logic stays with project - I can run `./scripts/crud.sh` from the project root **NO EXCEPTIONS:** Every web project gets this. No excuses. ### Required Capabilities Checklist For EVERY project, I must be able to do these via CLI/API: | Capability | Implementation | Location | |------------|----------------|----------| | **List** items | API endpoint + CLI | `api/items/route.ts` + `cli/crud.sh list` | | **Get** single item | API endpoint + CLI | `api/items/[id]/route.ts` + `cli/crud.sh get ` | | **Create** item | API endpoint + CLI | `api/items/route.ts` + `cli/crud.sh create` | | **Update** item | API endpoint + CLI | `api/items/[id]/route.ts` + `cli/crud.sh update ` | | **Delete** item | API endpoint + CLI | `api/items/[id]/route.ts` + `cli/crud.sh delete ` | | **Attach files** | API endpoint (base64) + CLI | `api/items/[id]/attachments/route.ts` | | **Query/filter** | API with query params | `api/items?status=open&assignee=xyz` | | **Status changes** | API PATCH + CLI | `cli/crud.sh status ` | ### CLI Script Template (Copy-Paste Starter) **File:** `scripts/crud.sh` (inside the project, NOT workspace) ```bash #!/bin/bash # Generic CRUD CLI for [ProjectName] # Usage: ./scripts/crud.sh [args] set -e BASE_URL="${API_URL:-http://localhost:3000/api}" API_KEY="${API_KEY:-$PROJECT_API_KEY}" action=$1 shift case $action in list) curl -s "$BASE_URL/items?limit=100" \ -H "Authorization: Bearer $API_KEY" | jq '.' ;; get) id=$1 curl -s "$BASE_URL/items/$id" \ -H "Authorization: Bearer $API_KEY" | jq '.' ;; create) # Read from stdin or args if [ -t 0 ]; then data="$1" else data=$(cat) fi curl -s -X POST "$BASE_URL/items" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $API_KEY" \ -d "$data" | jq '.' ;; update) id=$1 field=$2 value=$3 curl -s -X PATCH "$BASE_URL/items/$id" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $API_KEY" \ -d "{\"$field\": \"$value\"}" | jq '.' ;; delete) id=$1 curl -s -X DELETE "$BASE_URL/items/$id" \ -H "Authorization: Bearer $API_KEY" echo "Deleted $id" ;; attach) id=$1 file=$2 base64=$(base64 -i "$file") filename=$(basename "$file") curl -s -X POST "$BASE_URL/items/$id/attachments" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $API_KEY" \ -d "{\"filename\": \"$filename\", \"data\": \"$base64\"}" | jq '.' ;; *) echo "Usage: $0 {list|get |create |update |delete |attach }" exit 1 ;; esac ``` **Usage from project root:** ```bash cd /Users/mattbruce/Documents/Projects/OpenClaw/Web/[project-name] ./scripts/crud.sh list ./scripts/crud.sh get ./scripts/crud.sh create '{"title":"New Item"}' ``` ### Environment Configuration **File:** `.env.local` (gitignored, per-project) ```bash # API config for CLI API_URL=http://localhost:3000/api API_KEY=your-service-role-key-here ``` **File:** `.env.example` (committed to repo) ```bash # Copy to .env.local and fill in real values API_URL=http://localhost:3000/api API_KEY=your-api-key-here ``` ### TypeScript API Client Template **File:** `lib/api-client.ts` ```typescript const API_BASE = process.env.NEXT_PUBLIC_API_URL || '/api'; const API_KEY = process.env.API_KEY; export async function apiRequest( endpoint: string, options: RequestInit = {} ): Promise { const res = await fetch(`${API_BASE}${endpoint}`, { ...options, headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${API_KEY}`, ...options.headers, }, }); if (!res.ok) throw new Error(`API error: ${res.status}`); return res.json(); } // CRUD operations export const api = { list: (resource: string, params?: Record) => apiRequest(`/${resource}?${new URLSearchParams(params)}`), get: (resource: string, id: string) => apiRequest(`/${resource}/${id}`), create: (resource: string, data: unknown) => apiRequest(`/${resource}`, { method: 'POST', body: JSON.stringify(data) }), update: (resource: string, id: string, data: unknown) => apiRequest(`/${resource}/${id}`, { method: 'PATCH', body: JSON.stringify(data) }), delete: (resource: string, id: string) => apiRequest(`/${resource}/${id}`, { method: 'DELETE' }), attach: (resource: string, id: string, file: { filename: string; data: string }) => apiRequest(`/${resource}/${id}/attachments`, { method: 'POST', body: JSON.stringify(file) }), }; ``` ### Authentication Pattern **Option 1: Service Role Key (Server-side only)** - Store in `.env.local` as `SERVICE_ROLE_KEY` - Use for CLI scripts that run server-side - NEVER expose to client **Option 2: API Keys (Cross-origin safe)** - Generate per-integration - Store in database with permissions - Pass as `Authorization: Bearer ` header **Option 3: Supabase Direct (When API doesn't exist yet)** ```typescript import { createClient } from '@supabase/supabase-js'; const supabase = createClient(url, serviceRoleKey); // Use supabase.from('table').select() etc. ``` ### File Attachment Pattern **Storage Options:** 1. **Base64 in database** (small files < 1MB): Store directly in JSONB field 2. **Supabase Storage** (larger files): Upload to bucket, store reference URL 3. **External (S3/R2)**: Store URL reference only **CLI Attachment Script:** ```bash #!/bin/bash # attach-file.sh - Universal file attachment ITEM_ID=$1 FILE_PATH=$2 API_URL="${API_URL}/api/items/$ITEM_ID/attachments" # Detect mime type mime=$(file -b --mime-type "$FILE_PATH") base64=$(base64 -i "$FILE_PATH") filename=$(basename "$FILE_PATH") curl -s -X POST "$API_URL" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $API_KEY" \ -d "{ \"filename\": \"$filename\", \"mimeType\": \"$mime\", \"data\": \"$base64\", \"size\": $(stat -f%z "$FILE_PATH" 2>/dev/null || stat -c%s "$FILE_PATH") }" | jq '.' ``` ### Verification Pattern (Always Verify!) After ANY operation, verify via API: ```bash # Create → Verify task_id=$(./scripts/crud.sh create '{"title":"Test"}' | jq -r '.id') ./scripts/crud.sh get $task_id | jq '.title' # Should echo "Test" # Attach → Verify ./scripts/crud.sh attach $task_id ./file.md ./scripts/crud.sh get $task_id | jq '.attachments | length' # Should be > 0 # Update → Verify ./scripts/crud.sh update $task_id status done ./scripts/crud.sh get $task_id | jq '.status' # Should echo "done" ``` ### When Starting a New Project **Checklist before saying "project structure ready":** - [ ] API routes exist for CRUD operations - [ ] CLI scripts created in `scripts/` directory - [ ] API client module in `lib/api-client.ts` - [ ] `scripts/README.md` with usage docs (copy from `CLI_README_TEMPLATE.md`) - [ ] `.env.example` documenting required env vars - [ ] Test: Can I list items via CLI without browser? - [ ] Test: Can I attach a file via CLI? - [ ] Test: Can I verify operations via CLI get? - [ ] **API-to-CLI Coverage Verified:** Every API endpoint has matching CLI command **If any check fails → NOT READY.** **Template to copy:** `/Users/mattbruce/.openclaw/workspace/CLI_README_TEMPLATE.md` ### Ongoing Development: CLI Sync Maintenance **Rule 2.5 in practice:** When adding ANY web feature: ```bash # 1. BEFORE committing, audit API surface area find src/app/api -name "route.ts" -exec basename $(dirname {}) \; | sort > /tmp/api-endpoints.txt # 2. Audit CLI coverage grep -E "^(cmd_|function cmd)" scripts/*.sh | sed 's/.*cmd_//' | sed 's/(.*//' | sort -u > /tmp/cli-commands.txt # 3. Compare - if API has endpoints CLI doesn't cover → ADD THEM # Example mismatch: # API: POST /api/tasks/natural (natural language create) # CLI: Only has cmd_task_create (manual create) # → Must add cmd_task_natural to gantt.sh # 4. Update README.md with new commands # 5. Test new CLI command works # 6. Commit web + CLI changes together ``` **Coverage Matrix (maintain in scripts/README.md):** | API Endpoint | Method | CLI Command | Status | |--------------|--------|-------------|--------| | /api/tasks | GET | task list | ✅ | | /api/tasks | POST | task create | ✅ | | /api/tasks/natural | POST | task natural | ✅ | | /api/tasks | DELETE | task delete | ✅ | | ... | ... | ... | ... | **Monthly Audit Task:** Run this during a heartbeat to ensure sync: ```bash cd /Users/mattbruce/Documents/Projects/OpenClaw/Web/gantt-board ./scripts/audit-cli-coverage.sh # Script that compares API vs CLI ``` **If CLI lags behind API → File a bug task immediately.** ## Quick Commands ```bash # Deploy Gantt Board cd /Users/mattbruce/Documents/Projects/OpenClaw/Web/gantt-board npm run build && vercel --prod # Check all projects ls /Users/mattbruce/Documents/Projects/OpenClaw/Web/ ``` ## Gantt Board Task CRUD I have full CRUD capabilities on gantt board tasks via Supabase API: **Bash script:** `/Users/mattbruce/.openclaw/workspace/scripts/gantt-task-crud.sh` ```bash # List tasks (optionally filter by status) ./scripts/gantt-task-crud.sh list [open|done|...] # Get single task ./scripts/gantt-task-crud.sh get # Create task ./scripts/gantt-task-crud.sh create "Task title" [status] [priority] [project-id] [assignee-id] # Update task field ./scripts/gantt-task-crud.sh update # Delete task ./scripts/gantt-task-crud.sh delete ``` **TypeScript module:** `/Users/mattbruce/.openclaw/workspace/scripts/gantt-task-crud.ts` - `listTasks(status?)` - List all tasks - `getTask(taskId)` - Get single task - `createTask(params)` - Create new task - `updateTask(taskId, updates)` - Update task fields - `deleteTask(taskId)` - Delete task - `updateTaskStatus(taskId, status)` - Update status - `assignTask(taskId, assigneeId)` - Change assignee - `completeTask(taskId)` - Mark as done **Default assignee:** Max (9c29cc99-81a1-4e75-8dff-cd7cc5ceb5aa) ## Natural Language Task Parsing Matt can rattle off tasks naturally and I'll parse them: **Example formats:** - "Add task: Fix the login bug by Friday" - "For Max: Research Stripe integration, low priority" - "Urgent: Deploy blog backup to Vercel tomorrow" - "Create task: Update iOS app icons" **I parse:** - **Title** — the main task description - **Assignee** — "for [Name]" or defaults to Matt - **Priority** — "urgent/asap" = high, "low priority" = low, else medium - **Due date** — tomorrow, next week, by Friday, etc. (natural language) ## Document/File Management Rules ### RULE: Task Documents → Attach + Verify via API When creating documents for gantt board tasks: 1. ✅ Create the document 2. ✅ Attach it to the task via gantt board API or UI 3. ✅ **VERIFY via API** (no browser needed): ```bash ./scripts/gantt-task-crud.sh get | jq '.attachments' ``` Must return non-empty array with the file. 4. ❌ **DELETE local file only after API confirms attachment** 5. ❌ **Never mark task "done" until API verification passes** **CRITICAL:** Creating a file locally is NOT the same as attaching it. Subagents often stop at step 1. **Why:** Prevents workspace clutter and ensures single source of truth is in the gantt board. --- ## Memory Maintenance — Critical Rule **Update memory files CONTINUOUSLY throughout the day, not at the end.** - After significant decisions → write to MEMORY.md - After task completions → update memory/YYYY-MM-DD.md - After new processes established → document immediately - Waiting until end-of-day = lost context and repeated mistakes This prevents the nightmare of today (Feb 21) where session issues caused complete memory loss of critical work. ### My Memory Update Plan **TRIGGERS — Update memory when:** 1. ✅ Task completed → Log to memory/YYYY-MM-DD.md 2. ✅ Decision made → Document in MEMORY.md 3. ✅ New process/tool discovered → Add to TOOLS.md or MEMORY.md 4. ✅ Error/lesson learned → Write to MEMORY.md "Lessons Learned" 5. ✅ Context switch → Quick checkpoint update 6. ✅ Every 30-60 min of continuous work → Quick status save **WHAT to save:** - **MEMORY.md:** Decisions, lessons, key info, processes (curated) - **memory/YYYY-MM-DD.md:** Raw log of work, conversations, tasks done - **TOOLS.md:** Project locations, credentials, environment specifics **CHECKPOINT habit:** Before saying "done" or switching topics → ask "What needs to be remembered?" **Safety net:** If session crashes, next session reads files first. Files are source of truth.