# Recipe Manager — Agent Instructions

**Purpose:** How agents should approach development on this project  
**Last Updated:** 2026-03-23

---

## Core Principles

### 1. Orientation First
Every time you wake up (new session):

**PRE-FLIGHT GUARD (mandatory):**
- Verify these files exist at absolute path `/home/paulh/.openclaw/workspace/projects/recipe-manager/`:
  - `AGENT_INSTRUCTIONS.md`
  - `TODO.md`
- If either is missing, stop immediately and report:
  - `STUCK: bad working dir or missing harness files at /home/paulh/.openclaw/workspace/projects/recipe-manager`

Then continue orientation:
1. Read `PROJECT.md` — What are we building?
2. Read `ARCHITECTURE.md` — How are we building it?
3. Read `ROADMAP.md` — What's next?
4. Read `git log --oneline -10` — What happened recently?
5. Check `TODO.md` (if exists) — Any pending tasks?

**Never start coding without context.**

---

## Development Loop

### The Agent Workflow (Single Iteration)

```
┌─────────────────────────────────────────────────┐
│ 1. ORIENT    Read context files, git log        │
└────────────┬────────────────────────────────────┘
             │
┌────────────┴────────────────────────────────────┐
│ 2. PLAN      Pick ONE task from roadmap         │
│              Break into <1hr subtasks if needed  │
└────────────┬────────────────────────────────────┘
             │
┌────────────┴────────────────────────────────────┐
│ 3. IMPLEMENT Write code + tests                 │
│              Follow architecture patterns        │
└────────────┬────────────────────────────────────┘
             │
┌────────────┴────────────────────────────────────┐
│ 4. VERIFY    Run tests, lint, manual check      │
│              Does it meet acceptance criteria?   │
└────────────┬────────────────────────────────────┘
             │
┌────────────┴────────────────────────────────────┐
│ 5. COMMIT    Conventional commit message        │
│              Update docs (README, ADR, etc.)     │
└────────────┬────────────────────────────────────┘
             │
┌────────────┴────────────────────────────────────┐
│ 6. REPORT    Summarize what you did + what's    │
│              next (or escalate if blocked)       │
└─────────────────────────────────────────────────┘
```

**One loop = one commit.** Don't try to do everything at once.

---

## Task Selection Rules

### What to Work On

1. **Check TODO.md first** — treat it as the authoritative queue
2. **Pick the first unchecked task** in the current active phase section
3. **If all phase tasks are done,** report completion and request milestone transition
4. **Do not jump to backlog phases** unless TODO explicitly marks the new phase active

### How to Break Down Tasks

**Good task (1-4 hours):**
- "Implement recipe list API endpoint with pagination"
- "Add tag filtering to search UI"
- "Write E2E test for cook mode"

**Bad task (too big):**
- "Build entire recipe import system"
- "Finish frontend"

**If task feels big (>4 hours),** break it into subtasks and commit each one.

---

## Code Quality Standards

### TypeScript
- ✅ Strict mode enabled
- ✅ No `any` types (use `unknown` if needed)
- ✅ All public APIs have JSDoc comments
- ✅ Interfaces for all data models

### Testing
- ✅ Unit test new business logic (services, utilities)
- ✅ Integration test API endpoints
- ✅ E2E test critical user flows (cook mode, search)
- ✅ Aim for >80% coverage on core logic

### Commits
- ✅ Conventional Commits format: `type(scope): description`
  - `feat:` new feature
  - `fix:` bug fix
  - `docs:` documentation only
  - `test:` test additions/changes
  - `refactor:` code restructure (no behavior change)
  - `chore:` tooling, dependencies
- ✅ Descriptive messages (not "fix stuff" or "wip")
- ✅ Commit working code only (tests pass)

### Documentation
- ✅ Update README when setup changes
- ✅ Add ADR (Architecture Decision Record) in `docs/` for significant choices
  - Format: `ADR-001-why-sqlite.md`, `ADR-002-recipe-scraping-strategy.md`
- ✅ Update API docs when endpoints change
- ✅ Keep TODO.md current (add new tasks, remove completed)

---

## Common Patterns

### API Endpoint Template

```typescript
// src/routes/recipes.ts
import { Router } from 'express';
import { z } from 'zod';
import { RecipeService } from '../services/RecipeService';

const router = Router();
const recipeService = new RecipeService();

// Validation schema
const createRecipeSchema = z.object({
  title: z.string().min(1),
  ingredients: z.array(z.string()),
  instructions: z.array(z.string()),
  // ...
});

router.post('/recipes', async (req, res) => {
  try {
    const data = createRecipeSchema.parse(req.body);
    const recipe = await recipeService.create(data);
    res.json({ success: true, data: recipe });
  } catch (error) {
    if (error instanceof z.ZodError) {
      res.status(400).json({ success: false, error: error.errors });
    } else {
      res.status(500).json({ success: false, error: 'Internal error' });
    }
  }
});

export default router;
```

### React Component Template

```typescript
// src/components/RecipeCard.tsx
import { Recipe } from '../types/recipe';

interface RecipeCardProps {
  recipe: Recipe;
  onEdit: (id: number) => void;
  onDelete: (id: number) => void;
}

export function RecipeCard({ recipe, onEdit, onDelete }: RecipeCardProps) {
  return (
    <div className="border rounded-lg p-4 shadow-sm">
      <h3 className="text-lg font-bold">{recipe.title}</h3>
      <p className="text-gray-600">{recipe.description}</p>
      {/* ... */}
    </div>
  );
}
```

### Database Query Template

```typescript
// src/repositories/RecipeRepository.ts
import Database from 'better-sqlite3';
import { Recipe } from '../types/recipe';

export class RecipeRepository {
  constructor(private db: Database.Database) {}

  findAll(): Recipe[] {
    const stmt = this.db.prepare('SELECT * FROM recipes ORDER BY created_at DESC');
    return stmt.all() as Recipe[];
  }

  findById(id: number): Recipe | undefined {
    const stmt = this.db.prepare('SELECT * FROM recipes WHERE id = ?');
    return stmt.get(id) as Recipe | undefined;
  }

  // ...
}
```

---

## Error Handling

### When Things Go Wrong

1. **Build errors:** Fix immediately, don't commit broken code
2. **Test failures:** Investigate, fix, re-run
3. **Stuck on implementation (>30 min):** 
   - Document what you tried
   - Explain the blocker
   - Ask Paul for guidance
4. **Unclear requirements:** Propose 2-3 options, ask Paul to choose

### Never Guess

If PROJECT.md or ARCHITECTURE.md doesn't specify:
- **Good:** "Should recipe images be stored in SQLite or filesystem? I recommend filesystem for simpler backups."
- **Bad:** Just implementing without asking

---

## Error Signals (CRITICAL)

If you encounter a blocker or error, **DO NOT fail silently**. Include one of these signals in your response:

### STUCK Signal
```markdown
⚠️ **STUCK:** Cannot complete task "[task name]"

**Attempted:**
- [what you tried]
- [what you tried]

**Error/Blocker:**
[exact error message or description of the problem]

**Need from Paul:**
[specific question or decision needed]
```

### ERROR Signal
```markdown
❌ **ERROR:** Build/test failure

**Command:** `[exact command that failed]`

**Error output:**
```
[paste last 20 lines of error]
```

**Context:** [what you were trying to do]
```

### ALL_TASKS_COMPLETE Signal
```markdown
🎉 **ALL_TASKS_COMPLETE**

[summary of what was built]
[deployment instructions]
```

---

## Communication Protocol

### Progress Updates (After Each Commit)

```markdown
✅ **Completed:** Added recipe list API endpoint with pagination
- Implemented GET /api/recipes with offset/limit
- Added integration tests (100% coverage)
- Updated API docs

**Next up:** Recipe detail view UI component
**ETA:** 1-2 hours
```

### Milestone Completion

```markdown
🎉 **MVP Complete!**

All MVP features implemented:
- ✅ Manual recipe entry
- ✅ Recipe CRUD operations
- ✅ Tagging & search
- ✅ Cook mode with wake lock
- ✅ Docker deployment

**Test results:** 47/47 passing  
**Documentation:** README, API docs, user guide updated  
**Deployment:** Tested locally, ready for paje.ca

**Awaiting approval** to start v1.0 milestone (recipe scraping).
```

### Escalation (Blocked)

```markdown
⚠️ **Blocked:** Recipe scraping strategy unclear

**Context:** Working on browser extension for recipe import. Need decision on:

1. **Puppeteer vs Cheerio?**
   - Puppeteer: Handles JS-rendered sites, heavier
   - Cheerio: Fast, static HTML only
   
2. **Where to run scraping?**
   - Client-side (extension scrapes, sends JSON to API)
   - Server-side (extension sends URL, server scrapes)

**Recommendation:** Cheerio for v1 (80% of sites), Puppeteer later if needed. Server-side scraping for easier updates.

**Action needed:** Paul, which approach do you prefer?
```

---

## Anti-Patterns (Don't Do This)

❌ **Committing without testing**  
❌ **Changing architecture without documenting (ADR)**  
❌ **Working on multiple unrelated tasks in one commit**  
❌ **Ignoring linting errors "to fix later"**  
❌ **Hardcoding values that should be env vars**  
❌ **Skipping documentation updates**  
❌ **Assuming requirements without asking**  

---

## Quick Reference

### Starting a new feature
```bash
git pull origin main
git checkout -b feat/recipe-scaling
# ... code ...
npm test
git add .
git commit -m "feat: add recipe serving size scaling"
git push origin feat/recipe-scaling
```

### Running tests
```bash
npm test                 # All tests
npm test -- RecipeService  # Specific file
npm run test:coverage     # Coverage report
```

### Building & deploying
```bash
docker-compose build      # Build containers
docker-compose up -d      # Start services
docker-compose logs -f    # Watch logs
```

---

## Success Metrics

You're doing it right if:
- ✅ Every commit is small, focused, tested
- ✅ Paul wakes up to completed features, not questions
- ✅ Tests pass consistently
- ✅ Documentation stays current
- ✅ Code is readable (you're writing for future-you)

---

## OpenClaw Environment Notes

### File Access
- Working directory: `/home/paulh/.openclaw/workspace/projects/recipe-manager`
- **CRITICAL:** Use absolute paths in all exec commands
- The `~` shorthand does NOT work in exec — use `/home/paulh/` instead

### Build Commands
- Use `cd /absolute/path && command` pattern
- Example: `cd /home/paulh/.openclaw/workspace/projects/recipe-manager && npm test`
- Never rely on implicit working directory

### Git
- Commit after each completed task
- Use conventional commit format: `feat(scope): description`
- Don't push — Paul will review and push

### Exit Signals
- Include **ALL_TASKS_COMPLETE** when all TODO.md tasks are checked
- Include **STUCK:** or **ERROR:** if blocked (see Error Signals above)
- Always exit after ONE commit (don't chain multiple tasks)

---

_Remember: You're not just writing code—you're building a product Paul's family will use. Quality matters._
