Skip to content

A Day with LumenFlow

This walkthrough follows a realistic day of development using LumenFlow, showing both AI-assisted and traditional developer workflows side by side.

# AI agent checks recent signals
pnpm mem:inbox --since 30m

# Review backlog
cat docs/04-operations/tasks/backlog.md

Today we’ll work on WU-042: “Add email validation to user signup”.

# docs/04-operations/tasks/wu/WU-042.yaml
id: WU-042
title: Add email validation to user signup
lane: 'Framework: Core'
status: ready
acceptance:
  - Email field validates format on blur
  - Invalid emails show error message
  - Valid emails allow form submission
  - Unit tests cover validation logic with 90% coverage
code_paths:
  - packages/@lumenflow/core/src/validation/email.ts
  - packages/@lumenflow/core/src/__tests__/validation/email.test.ts
# Agent claims with full context
pnpm wu:claim --id WU-042 --lane "Framework: Core"
cd worktrees/framework-core-wu-042

# Agent loads relevant skills
# /skill tdd-workflow
# /skill code-quality

# Start agent session for memory tracking
pnpm agent:session --wu WU-042 --tier 2

Review the acceptance criteria:

  1. Email field validates format on blur - Need validation function
  2. Invalid emails show error message - Need error handling
  3. Valid emails allow form submission - Need success path
  4. Unit tests cover validation logic - TDD approach

The AI agent follows TDD workflow skill and writes tests first:

// packages/@lumenflow/core/src/__tests__/validation/email.test.ts
import { describe, it, expect } from 'vitest';
import { validateEmail } from '../../validation/email';

describe('validateEmail', () => {
  it('should accept valid email formats', () => {
    expect(validateEmail('user@example.com').valid).toBe(true);
    expect(validateEmail('user.name@domain.co.uk').valid).toBe(true);
    expect(validateEmail('user+tag@example.com').valid).toBe(true);
  });

  it('should reject invalid email formats', () => {
    expect(validateEmail('invalid').valid).toBe(false);
    expect(validateEmail('missing@domain').valid).toBe(false);
    expect(validateEmail('@nodomain.com').valid).toBe(false);
    expect(validateEmail('spaces in@email.com').valid).toBe(false);
  });

  it('should return error message for invalid emails', () => {
    const result = validateEmail('invalid');
    expect(result.valid).toBe(false);
    expect(result.error).toBe('Please enter a valid email address');
  });

  it('should handle edge cases', () => {
    expect(validateEmail('').valid).toBe(false);
    expect(validateEmail('   ').valid).toBe(false);
  });
});
pnpm test --filter @lumenflow/core
# Expected: 4 tests fail (module not found)

Agent implements just enough to pass tests:

// packages/@lumenflow/core/src/validation/email.ts
export interface EmailValidationResult {
  valid: boolean;
  error?: string;
}

const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

export function validateEmail(email: string): EmailValidationResult {
  const trimmed = email.trim();

  if (!trimmed) {
    return { valid: false, error: 'Please enter a valid email address' };
  }

  if (!EMAIL_REGEX.test(trimmed)) {
    return { valid: false, error: 'Please enter a valid email address' };
  }

  return { valid: true };
}
pnpm test --filter @lumenflow/core
# Expected: 4 tests pass
pnpm test --filter @lumenflow/core -- --coverage
# Verify >= 90% coverage on new code

Agent improves code quality while keeping tests green:

// packages/@lumenflow/core/src/validation/email.ts

// Extract constants
const VALIDATION_MESSAGES = {
  INVALID_EMAIL: 'Please enter a valid email address',
} as const;

// More robust regex from established library pattern
const EMAIL_REGEX = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;

export interface EmailValidationResult {
  valid: boolean;
  error?: string;
}

export function validateEmail(email: string): EmailValidationResult {
  const trimmed = email.trim();

  if (!trimmed || !EMAIL_REGEX.test(trimmed)) {
    return {
      valid: false,
      error: VALIDATION_MESSAGES.INVALID_EMAIL,
    };
  }

  return { valid: true };
}
pnpm test --filter @lumenflow/core
# All tests still pass

While the core work is stable, we knock out a small documentation WU in parallel.

# Claim a docs WU
pnpm wu:claim --id WU-077 --lane "Content: Documentation"
cd worktrees/content-documentation-wu-077

# Make doc edits...

# Run docs-only gates
pnpm wu:prep --id WU-077 --docs-only

# Complete from main
cd /path/to/main
pnpm wu:done --id WU-077
# Agent runs gates in worktree
pnpm wu:prep --id WU-042

# Output:
# [wu-prep] Running format check...
# [wu-prep] Running lint...
# [wu-prep] Running typecheck...
# [wu-prep] Running tests...
# [wu-prep] Gates passed
# Stage changes
git add packages/@lumenflow/core/src/validation/
git add packages/@lumenflow/core/src/__tests__/validation/

# Commit with WU reference
git commit -m "wu(wu-042): add email validation with tests

- Add validateEmail function with format validation
- Return error messages for invalid inputs
- 100% test coverage on validation logic"
# Agent signals completion
pnpm mem:signal "Implementation complete, gates passing" --wu WU-042

# Return to main and complete
cd /home/user/project
pnpm wu:done --id WU-042

# Output:
# [wu:done] Merging to main (fast-forward)...
# [wu:done] Creating stamp...
# [wu:done] Cleaning up worktree...
# [wu:done] WU-042 completed successfully
# Verify stamp exists
ls .lumenflow/stamps/WU-042.done

# Check git log
git log --oneline -3
# abc1234 wu(wu-042): done - add email validation
# def5678 wu(wu-042): claim for framework-core lane
# ...
# End agent session
pnpm agent:session-end

# Create checkpoint for context recovery
pnpm mem:checkpoint --wu WU-042
TimeActivityCommands
9:00Review backlogcat docs/04-operations/tasks/backlog.md
9:15Claim WU-042pnpm wu:claim --id WU-042
9:20cd to worktreecd worktrees/framework-core-wu-042
10:00Write failing testsTDD RED phase
10:30Run tests (fail)pnpm test
11:00Implement featureTDD GREEN phase
11:30Run tests (pass)pnpm test
12:30Claim docs WU-077pnpm wu:claim --id WU-077 --lane "Content: Documentation"
13:00Docs gatespnpm wu:prep --id WU-077 --docs-only
13:15Complete WU-077pnpm wu:done --id WU-077
14:00RefactorTDD REFACTOR phase
14:30Check coveragepnpm test -- --coverage
15:00Run gatespnpm wu:prep --id WU-042
15:30Commit changesgit commit
16:00Complete WU-042pnpm wu:done --id WU-042
pnpm format
git add -A
git commit --amend --no-edit
pnpm wu:prep --id WU-042

If you made changes in main instead of worktree:

# Check where changes are
git status

# If in main, move changes into the worktree
git diff > /tmp/main-changes.patch
cd worktrees/framework-core-wu-042
git apply /tmp/main-changes.patch
cd /path/to/main
git restore .
ERROR: WRONG_LOCATION - wu:done must be run from main checkout

FIX: cd /home/user/project && pnpm wu:done --id WU-042

Claim then cd

Always cd into the worktree immediately after claiming.

Test first

Write failing tests before implementation (RED-GREEN-REFACTOR).

Gates before done

Run pnpm wu:prep --id WU-XXX in the worktree before wu:done.

Complete from main

Run pnpm wu:done from the main checkout, not the worktree.