test-repo/MEMORY.md

29 KiB

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., itemstasks 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):

# 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:

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:

Infrastructure

Supabase Projects (separate for each app):

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 (100% API Coverage)

Location: /Users/mattbruce/Documents/Projects/OpenClaw/Web/gantt-board/scripts/ (IN PROJECT, VERSION CONTROLLED)

Status: Rule 2.5 Compliant - All API endpoints have matching CLI commands
Audit Date: 2026-02-22
Coverage: 13 API endpoints → 13 CLI commands (100%)

Rule: CLI tools belong IN THE PROJECT DIRECTORY, not workspace scripts folder. They must be committed with the project or they'll get lost.

API-to-CLI Coverage Matrix

API Endpoint Method CLI Command Status
Tasks
/api/tasks GET task list
/api/tasks POST task create
/api/tasks DELETE task delete
/api/tasks/natural POST task natural
Projects
/api/projects GET project list
/api/projects/[id] GET project get
/api/projects POST project create
/api/projects PATCH project update
/api/projects DELETE project delete
Sprints
/api/sprints GET sprint list
/api/sprints/[id] GET sprint get
/api/sprints POST sprint create
/api/sprints PATCH sprint update
/api/sprints DELETE sprint delete
Auth
/api/auth/login POST auth login
/api/auth/logout POST auth logout
/api/auth/session GET auth session
/api/auth/register POST auth register
/api/auth/forgot-password POST auth forgot-password
/api/auth/reset-password POST auth reset-password
/api/auth/account PATCH auth account
/api/auth/users GET auth users
Users Admin
/api/users GET user get
/api/users PATCH user update
/api/users DELETE user delete
Meta
/api/meta GET meta list
/api/meta GET meta get
/api/meta POST meta set
/api/meta DELETE meta delete
Debug
/api/debug GET debug
Total 30/30 (100%)

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):

# Tasks
./scripts/gantt.sh task list [status]              # List tasks
./scripts/gantt.sh task get <task-id>              # 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 <id> <field> <val>  # Update field
./scripts/gantt.sh task delete <task-id>           # Delete task
./scripts/gantt.sh task comment <id> "text"        # Add comment
./scripts/gantt.sh task attach <id> <file>         # Attach file

# Projects & Sprints
./scripts/gantt.sh project list                    # List projects
./scripts/gantt.sh project get <id>                # Get specific project
./scripts/gantt.sh project create "Name" [desc] [color]  # Create project
./scripts/gantt.sh project update <id> <field> <val>     # Update project
./scripts/gantt.sh project delete <id>             # Delete project
./scripts/gantt.sh sprint list                     # List sprints
./scripts/gantt.sh sprint get <id>                 # Get specific sprint
./scripts/gantt.sh sprint create "Name" <project-id> [start] [end] [goal]  # Create sprint
./scripts/gantt.sh sprint update <id> <field> <val>      # Update sprint
./scripts/gantt.sh sprint delete <id>              # Delete sprint

# Auth
./scripts/gantt.sh auth session                    # Check session
./scripts/gantt.sh auth login <email> <pass>       # Log in
./scripts/gantt.sh auth logout                     # Log out
./scripts/gantt.sh auth register <email> <pass>    # Register new account
./scripts/gantt.sh auth forgot-password <email>    # Request password reset
./scripts/gantt.sh auth reset-password <tok> <pass> # Reset password
./scripts/gantt.sh auth account <field> <value>    # Update account
./scripts/gantt.sh auth users                      # List users

# User Admin
./scripts/gantt.sh user list                       # List all users
./scripts/gantt.sh user get <user-id>              # Get specific user
./scripts/gantt.sh user update <id> <field> <val>  # Update user
./scripts/gantt.sh user delete <user-id>           # Delete user

# Meta
./scripts/gantt.sh meta list                       # List all meta entries
./scripts/gantt.sh meta get <key>                  # Get meta value
./scripts/gantt.sh meta set <key> <value>          # Set meta value
./scripts/gantt.sh meta delete <key>               # Delete meta entry

# Debug
./scripts/gantt.sh debug                           # Debug endpoint

Usage (Direct Supabase - works without web server):

./scripts/gantt-task-crud.sh list [status]         # List tasks
./scripts/gantt-task-crud.sh get <task-id>         # Get task
./scripts/attach-file.sh <task-id> <file-path>     # Attach file
./scripts/view-attachment.sh <task-id> [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:

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 <id>
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 <id>
Delete item API endpoint + CLI api/items/[id]/route.ts + cli/crud.sh delete <id>
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 <id> <new-status>

CLI Script Template (Copy-Paste Starter)

File: scripts/crud.sh (inside the project, NOT workspace)

#!/bin/bash
# Generic CRUD CLI for [ProjectName]
# Usage: ./scripts/crud.sh <action> [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 <id>|create <json>|update <id> <field> <value>|delete <id>|attach <id> <file>}"
    exit 1
    ;;
esac

Usage from project root:

cd /Users/mattbruce/Documents/Projects/OpenClaw/Web/[project-name]
./scripts/crud.sh list
./scripts/crud.sh get <id>
./scripts/crud.sh create '{"title":"New Item"}'

Environment Configuration

File: .env.local (gitignored, per-project)

# API config for CLI
API_URL=http://localhost:3000/api
API_KEY=your-service-role-key-here

File: .env.example (committed to repo)

# 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

const API_BASE = process.env.NEXT_PUBLIC_API_URL || '/api';
const API_KEY = process.env.API_KEY;

export async function apiRequest<T>(
  endpoint: string,
  options: RequestInit = {}
): Promise<T> {
  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<string, string>) => 
    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 <key> header

Option 3: Supabase Direct (When API doesn't exist yet)

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:

#!/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:

# 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:

# 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:

cd /Users/mattbruce/Documents/Projects/OpenClaw/Web/gantt-board
./scripts/audit-cli-coverage.sh  # Script that compares API vs CLI

Audit Script Template: Copy to new projects:

cp /Users/mattbruce/.openclaw/workspace/scripts/audit-cli-coverage.sh \
   /Users/mattbruce/Documents/Projects/OpenClaw/Web/{new-project}/scripts/

Then customize the CLI_MAP associative array to match your CLI commands.

If CLI lags behind API → File a bug task immediately.

Quick Commands

# 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

# List tasks (optionally filter by status)
./scripts/gantt-task-crud.sh list [open|done|...]

# Get single task
./scripts/gantt-task-crud.sh get <task-id>

# 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 <task-id> <field> <value>

# Delete task
./scripts/gantt-task-crud.sh delete <task-id>

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):
    ./scripts/gantt-task-crud.sh get <task-id> | 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.