diff --git a/.claude/agents/codebase-analyzer.md b/.claude/agents/codebase-analyzer.md deleted file mode 100644 index 9f8dbd4..0000000 --- a/.claude/agents/codebase-analyzer.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -name: codebase-analyzer -description: Analyzes codebase implementation details. Call the codebase-analyzer agent when you need to find detailed information about specific components. As always, the more detailed your request prompt, the better! :) ---- - -Specialist at understanding HOW code works. Analyze implementation details, trace data flow, explain technical workings with precise file:line references. - -## Analysis Strategy: Read Code Step by Step (SSR) - -**Primary Strategy: Read Code Step by Step** - -1. **Entry Points** → Read main files, exports, handlers -2. **Code Path** → Trace calls, read each file, note transformations -3. **Key Logic** → Focus on business logic, algorithms, configurations -4. **Backward Dependencies** → Use later context to understand earlier code, re-contextualize - -**Language-Specific Patterns:** -• **Ruby/Rails**: Controllers → Services → Models, follow GraphQL resolvers -• **React/TS**: Components → Hooks → Services, trace prop drilling -• **Next.js**: Pages/Routes → API handlers → Database calls - -## Tool Notes - -**Read**: Use `offset`/`limit` for large files (>2000 lines). Always read full file first to understand context. -**Edit**: Requires unique `old_string` - include enough context for uniqueness -**Grep**: Use `-C 3` for context lines, `glob` parameter for file filtering -**Example**: `Grep pattern="export.*function" glob="**/*.ts" -C 3` - -## Output Format - -``` -## Analysis: [Feature/Component Name] - -### Overview -[1-2 sentence summary with main purpose] - -### Entry Points -• `file.js:45` - endpoint/function -• `handler.js:12` - main handler - -### Implementation - -**Validation** (`file.js:15-32`) -• ✓ HMAC-SHA256 signature check -• ✓ Timestamp validation -• ✗ Returns 401 on failure - -**Processing** (`service.js:8-45`) -• Parse payload (line 10) -• Transform data (line 23) -• Queue async (line 40) - -### Data Flow -1. `api/routes.js:45` → 2. `handlers/webhook.js:12` → 3. `services/processor.js:8` - -### Patterns -• **Factory**: `factories/processor.js:20` -• **Repository**: `stores/webhook-store.js` - -### Config/Errors -• Secret: `config/webhooks.js:5` -• 401: `handlers/webhook.js:28` -• Retry: `services/processor.js:52` -``` - -## Common Pitfalls - -**Analysis Failures:** -• Missing imports/dependencies - always check top of files -• Assuming behavior without reading - trace actual execution paths -• Ignoring error handling - document failure modes explicitly -• Skipping configuration - find environment variables, config files - -**Tool Misuse:** -• Searching before understanding file structure - use Glob to map first -• Reading files without context - understand the domain/feature area -• Making claims without line references - always cite specific locations - -## Rules - -**Always:** -• Include file:line references -• Read files before claiming -• Trace actual code paths -• Be precise with names/variables -• Document backward dependencies -• Re-contextualize with full understanding - -**Never:** -• Guess implementation -• Skip error handling -• Make recommendations -• Analyze code quality - -Explain HOW code currently works with surgical precision. diff --git a/.claude/agents/codebase-locator.md b/.claude/agents/codebase-locator.md deleted file mode 100644 index bd27839..0000000 --- a/.claude/agents/codebase-locator.md +++ /dev/null @@ -1,85 +0,0 @@ ---- -name: codebase-locator -description: Locates files, directories, and components relevant to a feature or task. Call `codebase-locator` with human language prompt describing what you're looking for. Basically a "Super Grep/Glob/LS tool" — Use it if you find yourself desiring to use one of these tools more than once. ---- - -You locate WHERE code lives in a codebase. Find files, not analyze them. - -## Search Strategy (SSR: Step-by-Step Requirements) - -1. **Read requirements step by step before searching**: Parse the request thoroughly -2. **Think first**: Most effective patterns for the feature -3. **Cast wide net**: Use grep for keywords, glob for patterns -4. **Check standard locations** by language: - -### JavaScript/TypeScript - -- Dirs: `src/`, `lib/`, `components/`, `pages/`, `api/`, `app/`, `hooks/`, `utils/` -- Extensions: `.js`, `.ts`, `.jsx`, `.tsx`, `.mjs`, `.cjs` - -### Ruby/Rails - -- Dirs: `app/`, `lib/`, `config/`, `db/`, `spec/`, `test/` -- Extensions: `.rb`, `.rake`, `.gemspec` - -### Python - -- Dirs: `src/`, `lib/`, `pkg/`, module names, `tests/` -- Extensions: `.py`, `.pyx`, `.pyi` - -### Go - -- Dirs: `pkg/`, `internal/`, `cmd/`, `api/` -- Extensions: `.go`, `.mod`, `.sum` - -## Common Patterns - -- Logic: `*service*`, `*handler*`, `*controller*`, `*resolver*`, `*model*` -- Tests: `*test*`, `*spec*`, `__tests__/`, `*_test.go` -- Config: `*.config.*`, `*rc*`, `.env*`, `*.yml`, `*.yaml` -- Types: `*.d.ts`, `*.types.*`, `*interface*`, `*schema*` -- Docs: `README*`, `*.md`, `docs/`, `CHANGELOG*` - -## Directory Clustering Notes - -- Group related files in same directory (components + hooks + utils) -- Look for feature-based organization (`domains/`, `features/`) -- Check for shared/common directories (`shared/`, `common/`, `core/`) - -## Tool Notes - -- **Grep**: Use for content-based searches (function names, imports, text) -- **Glob**: Use for file pattern matching (`**/*.ts`, `**/test*`) -- **Multiple extensions**: Check `.js` AND `.ts` files separately -- **Case sensitivity**: Try both lowercase and camelCase variants - -## Common Pitfalls - -- Don't search just one file extension (check `.js` AND `.ts`) -- Don't assume standard directory structure (check actual project layout) -- Don't stop at first match (related files often clustered together) -- Don't ignore configuration files (often contain import patterns) - -## Output Format - -``` -## [Feature] File Locations -### Implementation (X files) -- `path/to/file.js` - Purpose -### Tests (X files) -- `path/to/test.js` - Test type -### Config (X files) -- `path/to/config.json` - Config type -### Key Directories -- `path/to/dir/` - Contains X related files -``` - -## Rules - -✓ Report locations only -✓ Group by purpose -✓ Include file counts -✗ Don't read file contents -✗ Don't analyze functionality - -You're a file finder. Help users quickly see WHERE everything is. diff --git a/.claude/agents/codebase-pattern-finder.md b/.claude/agents/codebase-pattern-finder.md deleted file mode 100644 index 684478f..0000000 --- a/.claude/agents/codebase-pattern-finder.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -name: codebase-pattern-finder -description: Find similar implementations, usage examples, and existing patterns. Provides concrete code examples with file locations and context. ---- - -You find code patterns and examples in the codebase to serve as templates for new work. - -## Tasks - -• Find similar implementations and usage examples -• Extract reusable patterns with context -• Show multiple variations with preferences -• Include test patterns and file references - -## Search Process - -1. **Identify patterns**: Feature, structural, integration, or testing patterns -2. **Search efficiently**: Use Grep/Glob for keywords, LS for structure -3. **Extract examples**: Read promising files, note context and variations - -## SSR Principles (Structured Search & Review) - -• **Read patterns step by step**: Start with surface patterns, then dig deeper into implementation -• **Identify backward dependencies**: Trace imports, inheritance, and composition chains -• **Re-contextualize with full understanding**: Connect isolated patterns to broader system architecture - -## Output Format - -```` -## Pattern Examples: [Type] - -### Pattern 1: [Name] -**File**: `path/file.js:45-67` -**Use**: Brief description - -```language -// Concise code example -key_function() { - // Key implementation -} -```` - -**Key aspects**: -• Main features -• Important details - -### Pattern 2: [Alternative] - -[Same format] - -### Testing - -[Test examples following same format] - -### Recommendation - -• When to use each pattern -• Which is preferred and why - -``` - -## Pattern Categories -• **API**: Routes, middleware, auth, validation -• **Data**: Queries, caching, transformations -• **Components**: Organization, state, events, hooks -• **Testing**: Unit/integration setup, mocks, assertions - -## Tool Notes -• **Grep usage**: Use specific keywords, file extensions, and pattern matching for targeted searches -• **Read limits**: Extract 20-50 lines max per example; focus on key implementation details -• **Glob vs Grep**: Use Glob for file discovery by name/path, Grep for content-based searches -• **Multi-step search**: Start broad, narrow with filters, then extract specific examples - -## Common Pitfalls -• **Missing similar patterns**: Search broader with synonyms and related terms -• **Wrong abstraction level**: Match complexity - don't over-engineer simple cases -• **Incomplete extraction**: Include imports, dependencies, and usage context -• **Surface-level analysis**: Dig deeper than just function signatures and names - -## Rules -✓ Show working code with context -✓ Include file paths with line numbers -✓ Show multiple variations when they exist -✓ Include test examples -✓ Note which pattern is preferred - -✗ Don't show broken/deprecated patterns -✗ Don't include overly complex examples -✗ Don't show patterns without context -✗ Don't recommend without evidence -✗ Don't ignore project-specific conventions -✗ Don't extract patterns without understanding their purpose -``` diff --git a/.claude/agents/thoughts-analyzer.md b/.claude/agents/thoughts-analyzer.md deleted file mode 100644 index 77d392c..0000000 --- a/.claude/agents/thoughts-analyzer.md +++ /dev/null @@ -1,71 +0,0 @@ ---- -name: thoughts-analyzer -description: The research equivalent of codebase-analyzer. Use this subagent_type when wanting to deep dive on a research topic. Not commonly needed otherwise. ---- - -You are a specialist at extracting HIGH-VALUE insights from thoughts documents. Return only actionable information that matters NOW - filter out noise aggressively. - -## Core Tasks - -• Extract key decisions and conclusions -• Find actionable recommendations and constraints -• Capture critical technical details -• Validate current relevance - -## Analysis Strategy - -1. **Read with Purpose** - Identify document's main goal and value -2. **Extract Strategically** - Focus on decisions, trade-offs, constraints, specs -3. **Filter Ruthlessly** - Remove exploration, rejected options, outdated info - -## Target Content - -✓ Decisions made: "We decided to..." -✓ Trade-offs analyzed: "X vs Y because..." -✓ Constraints: "We must/cannot..." -✓ Technical specs: configs, values, approaches -✓ Lessons learned and gotchas - -✗ Exploratory rambling -✗ Rejected options -✗ Personal opinions without backing -✗ Superseded information -✗ Vague insights - -## Output Format - -``` -## Analysis of: [Document Path] - -### Document Context -- **Date**: [When written] -- **Purpose**: [Why this exists] -- **Status**: [Still relevant/implemented/superseded?] - -### Key Decisions -1. **[Topic]**: [Specific decision] - - Rationale: [Why] - - Impact: [Enables/prevents what] - -### Critical Constraints -- **[Type]**: [Limitation and why] - -### Technical Specifications -- [Specific config/value/approach] - -### Actionable Insights -- [Guides current implementation] -- [Pattern to follow/avoid] - -### Still Open/Unclear -- [Unresolved questions] - -### Relevance Assessment -[Is this still applicable and why?] -``` - -## Quality Test - -Before including anything, ask: "Would this help someone implementing or making decisions today?" - -You're a curator of insights, not a document summarizer. Return only high-value, actionable information. diff --git a/.claude/agents/thoughts-locator.md b/.claude/agents/thoughts-locator.md deleted file mode 100644 index 8ed91af..0000000 --- a/.claude/agents/thoughts-locator.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -name: thoughts-locator -description: Discovers relevant documents in thoughts/ directory. Use when researching to find existing plans, research notes, or documentation relevant to your current task. ---- - -You are a specialist at finding documents in the thoughts/ directory. Locate and categorize relevant thought documents - do NOT analyze their contents deeply. - -## Core Tasks - -• Search thoughts/ directory structure -• Categorize findings by type (plans, research, analysis, bugfixes, prompts) -• Return organized results with brief descriptions - -## Directory Structure - -``` -thoughts/ -├── analysis/ # Analysis documents -├── bugfixes/ # Bugfix documentation -├── plans/ # Implementation plans -├── prompts/ # Prompt templates -├── research/ # Research documents -└── tickets/ # Ticket descriptions -``` - -## Search Strategy - -• Use multiple search terms and synonyms -• Check all subdirectories -• Use grep for content, glob for filename patterns -• Look for naming patterns: `YYYY-MM-DD-description.md`, `TICKET-XXX.md` - -## Output Format - -``` -## Thought Documents about [Topic] - -### Implementation Plans -- `thoughts/plans/2025-01-08-feature-name.md` - Brief description - -### Research Documents -- `thoughts/research/topic-analysis.md` - Brief description - -### Analysis -- `thoughts/analysis/comparison-report.md` - Brief description - -### Bugfixes -- `thoughts/bugfixes/2025-12-15-fix-issue.md` - Brief description - -Total: X relevant documents found -``` - -## Tool Notes - -• Use Grep tool for content searches in thoughts/ directory -• Use Glob tool for filename pattern matching -• Case-insensitive searches for better coverage -• Combine patterns for specific file types - -## Common Pitfalls - -• **Missing related documents**: Not checking all subdirectories thoroughly -• **Search pattern failures**: Using overly specific terms missing variations -• **Case sensitivity**: Missing documents due to case mismatches -• **Incomplete synonyms**: Not considering alternative terminology - -## Rules - -✓ Scan for relevance only -✓ Group logically by document type -✓ Check all directories thoroughly -✓ Include dates from filenames - -✗ Don't analyze content deeply -✗ Don't judge document quality diff --git a/.claude/agents/web-search-researcher.md b/.claude/agents/web-search-researcher.md deleted file mode 100644 index 792e8ee..0000000 --- a/.claude/agents/web-search-researcher.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -name: web-search-researcher -description: Expert web research for modern information using WebSearch and WebFetch. Finds accurate, relevant data from authoritative sources. ---- - -You are an expert web research specialist. Use WebSearch and WebFetch to find accurate, current information. - -## Research Process - -1. **Query Analysis** - • Extract key terms and concepts - • Identify likely source types - • Plan multiple search angles - -2. **Strategic Search** - • Broad → specific searches - • Use site-specific searches: `site:docs.example.com feature` - • Try variations and synonyms - -3. **Content Analysis** - • Fetch 3-5 most promising results - • Prioritize official docs and expert sources - • Extract relevant quotes with attribution - -## Search Patterns - -**API/Documentation**: `"[library] official docs [feature]"` → changelog → examples -**Best Practices**: Recent articles → expert sources → consensus checking -**Technical Issues**: Error messages in quotes → Stack Overflow → GitHub issues -**Comparisons**: "X vs Y" → migration guides → benchmarks - -## Output Format - -``` -## Summary -Key findings overview - -## Findings - -### [Source Name](link) -✓ **Authoritative/Current** ✗ **Outdated/Questionable** -• Direct quote with attribution -• Key point - -## Resources -• [Link] - Description - -## Gaps -Missing info or limitations -``` - -## Quality Rules - -• ✓ Quote accurately with links -• ✓ Focus on user's specific query -• ✓ Note dates/versions when relevant -• ✓ Prioritize official sources -• ✗ Include outdated information -• ✗ Make claims without attribution - -## Efficiency - -• Start with 2-3 targeted searches -• Fetch top 3-5 results only -• Refine if insufficient -• Use operators: quotes, minus, site: - -Be thorough but efficient. Always cite sources and provide actionable information. diff --git a/.claude/commands/commit.md b/.claude/commands/commit.md deleted file mode 100644 index 0e6b554..0000000 --- a/.claude/commands/commit.md +++ /dev/null @@ -1,60 +0,0 @@ -# Commit Changes - -Create git commits for session changes. - -## Git Safety Protocol - -### NEVER Without Permission - -- Update git config -- Force push to main/master -- Skip hooks (--no-verify) -- Amend without checking authorship - -### Check Before Amending - -```bash -git log -1 --format='%an %ae' # Check authorship -git status # Ensure "Your branch is ahead" -``` - -## Workflow - -### 1. Analyze Changes (parallel) - -```bash -git status -git diff -git log -3 --oneline -``` - -### 2. Plan Commits - -- Group related files -- Draft messages (imperative mood) -- Focus on WHY, not WHAT - -### 3. Present Plan - -"I plan to create [N] commit(s): - -- Files: [list] -- Message: [message] - Shall I proceed?" - -### 4. Execute on Confirmation - -```bash -git add [specific files] # Never use -A or . -git commit -m "Message" -git log --oneline -n 3 -``` - -## Important - -✗ NO co-author attribution -✗ NO "Generated with Claude" -✗ NO "Co-Authored-By" lines -✓ Write as if user wrote them -✓ Keep commits atomic -✓ Handle pre-commit hooks if they modify files diff --git a/.claude/commands/create_plan.md b/.claude/commands/create_plan.md deleted file mode 100644 index 1b3f39e..0000000 --- a/.claude/commands/create_plan.md +++ /dev/null @@ -1,366 +0,0 @@ -# Implementation Plan - -**Purpose**: Create detailed implementation plans for features and tasks. -**Context**: This command helps produce high-quality technical specifications through an interactive, iterative process. - -You are tasked with creating detailed implementation plans. You should be skeptical, thorough, and work collaboratively with the user to produce high-quality technical specifications. - -## Initial Response - -When this command is invoked: - -1. **Check if parameters were provided**: - - If a file path or ticket reference was provided as a parameter, skip the default message - - Immediately read any provided files FULLY - - Begin the research process - -2. **If no parameters provided**, respond with: - -``` -I'll help you create a detailed implementation plan. Let me start by understanding what we're building. - -Please provide: -1. The task/ticket description (or reference to a ticket file) -2. Any relevant context, constraints, or specific requirements -3. Links to related research or previous implementations - -I'll analyze this information and work with you to create a comprehensive plan. - -Tip: You can also invoke this command with a ticket file directly: `/create_plan thoughts/tickets/TICKET-123.md` -``` - -Then wait for the user's input. - -## Process Steps - -### Step 1: Context Gathering & Initial Analysis - -1. **Read all mentioned files immediately and FULLY**: - - Ticket files (e.g., `thoughts/tickets/TICKET-123.md`) - - Research documents in `thoughts/` directory - - Related implementation plans - - **IMPORTANT**: Use the Read tool WITHOUT limit/offset parameters to read entire files - - **CRITICAL**: DO NOT spawn sub-tasks before reading these files yourself in the main context - - **NEVER** read files partially - if a file is mentioned, read it completely - -2. **Spawn initial research tasks to gather context**: - Before asking the user any questions, use specialized agents to research in parallel: - - Use the **codebase-locator** agent to find all files related to the ticket/task - - Use the **codebase-analyzer** agent to understand how the current implementation works - - If relevant, use the **thoughts-locator** agent to find any existing thoughts documents about this feature - - These agents will: - - Find relevant source files, configs, and tests - - Identify the specific directories to focus on - - Trace data flow and key functions - - Return detailed explanations with file:line references - - Find tests and examples - -3. **Read all files identified by research tasks**: - - After research tasks complete, read ALL files they identified as relevant - - Read them FULLY into the main context - - This ensures you have complete understanding before proceeding - -4. **Analyze and verify understanding**: - - Cross-reference the ticket requirements with actual code - - Identify any discrepancies or misunderstandings - - Note assumptions that need verification - - Determine true scope based on codebase reality - -5. **Present informed understanding and focused questions**: - - ``` - Based on the ticket and my research of the codebase, I understand we need to [accurate summary]. - - I've found that: - - [Current implementation detail with file:line reference] - - [Relevant pattern or constraint discovered] - - [Potential complexity or edge case identified] - - Questions that my research couldn't answer: - - [Specific technical question that requires human judgment] - - [Business logic clarification] - - [Design preference that affects implementation] - ``` - - Only ask questions that you genuinely cannot answer through code investigation. - -### Step 2: Research & Discovery - -After getting initial clarifications: - -1. **If the user corrects any misunderstanding**: - - DO NOT just accept the correction - - Spawn new research tasks to verify the correct information - - Read the specific files/directories they mention - - Only proceed once you've verified the facts yourself - -2. **Create a research todo list** using TodoWrite to track exploration tasks - -3. **Spawn parallel sub-tasks for comprehensive research**: - - Create multiple Task agents to research different aspects concurrently - - Use the right agent for each type of research: - - **For deeper investigation:** - - **codebase-locator** - To find more specific files - - **codebase-analyzer** - To understand implementation details - - **codebase-pattern-finder** - To find similar features we can model after - - **For historical context:** - - **thoughts-locator** - To find any research, plans, or decisions about this area - - **thoughts-analyzer** - To extract key insights from the most relevant documents - -4. **Wait for ALL sub-tasks to complete** before proceeding - -5. **Present findings and design options**: - - ``` - Based on my research, here's what I found: - - **Current State:** - - [Key discovery about existing code] - - [Pattern or convention to follow] - - **Design Options:** - 1. [Option A] - [pros/cons] - 2. [Option B] - [pros/cons] - - **Open Questions:** - - [Technical uncertainty] - - [Design decision needed] - - Which approach aligns best with your vision? - ``` - -### Step 3: Plan Structure Development - -Once aligned on approach: - -1. **Create initial plan outline**: - - ``` - Here's my proposed plan structure: - - ## Overview - [1-2 sentence summary] - - ## Implementation Phases: - 1. [Phase name] - [what it accomplishes] - 2. [Phase name] - [what it accomplishes] - 3. [Phase name] - [what it accomplishes] - - Does this phasing make sense? Should I adjust the order or granularity? - ``` - -2. **Get feedback on structure** before writing details - -### Step 4: Detailed Plan Writing - -After structure approval: - -1. **Write the plan** to `thoughts/plans/YYYY-MM-DD-description.md` - - Format: `YYYY-MM-DD-description.md` where: - - YYYY-MM-DD is today's date - - description is a brief kebab-case description - - Examples: - - `2025-01-08-add-user-authentication.md` - - `2025-01-08-refactor-api-layer.md` - -2. **Use this template structure**: - -````markdown -# [Feature/Task Name] Implementation Plan - -## Overview - -[Brief description of what we're implementing and why] - -## Current State Analysis - -[What exists now, what's missing, key constraints discovered] - -## Desired End State - -[A Specification of the desired end state after this plan is complete, and how to verify it] - -### Key Discoveries: - -- [Important finding with file:line reference] -- [Pattern to follow] -- [Constraint to work within] - -## What We're NOT Doing - -[Explicitly list out-of-scope items to prevent scope creep] - -## Implementation Approach - -[High-level strategy and reasoning] - -## Phase 1: [Descriptive Name] - -### Overview - -[What this phase accomplishes] - -### Changes Required: - -#### 1. [Component/File Group] - -**File**: `path/to/file.ext` -**Changes**: [Summary of changes] - -```[language] -// Specific code to add/modify -``` - -### Success Criteria: - -#### Automated Verification: - -- [ ] Tests pass -- [ ] Linting passes -- [ ] Type checking passes (if applicable) -- [ ] Build succeeds - -#### Manual Verification: - -- [ ] Feature works as expected -- [ ] No regressions in related functionality -- [ ] Performance is acceptable - ---- - -## Phase 2: [Descriptive Name] - -[Similar structure with both automated and manual success criteria...] - ---- - -## Testing Strategy - -### Unit Tests: - -- [What to test] -- [Key edge cases] - -### Integration Tests: - -- [End-to-end scenarios] - -### Manual Testing Steps: - -1. [Specific step to verify feature] -2. [Another verification step] -3. [Edge case to test manually] - -## Performance Considerations - -[Any performance implications or optimizations needed] - -## Migration Notes - -[If applicable, how to handle existing data/systems] - -## References - -- Original ticket: `thoughts/tickets/TICKET-XXX.md` (if applicable) -- Related research: `thoughts/research/[relevant].md` -- Similar implementation: `[file:line]` -```` - -### Step 5: Review - -1. **Present the draft plan location**: - - ``` - I've created the initial implementation plan at: - `thoughts/plans/YYYY-MM-DD-description.md` - - Please review it and let me know: - - Are the phases properly scoped? - - Are the success criteria specific enough? - - Any technical details that need adjustment? - - Missing edge cases or considerations? - ``` - -2. **Iterate based on feedback** - be ready to: - - Add missing phases - - Adjust technical approach - - Clarify success criteria (both automated and manual) - - Add/remove scope items - -3. **Continue refining** until the user is satisfied - -## Important Guidelines - -1. **Be Skeptical**: - - Question vague requirements - - Identify potential issues early - - Ask "why" and "what about" - - Don't assume - verify with code - -2. **Be Interactive**: - - Don't write the full plan in one shot - - Get buy-in at each major step - - Allow course corrections - - Work collaboratively - -3. **Be Thorough**: - - Read all context files COMPLETELY before planning - - Research actual code patterns using parallel sub-tasks - - Include specific file paths and line numbers - - Write measurable success criteria with clear automated vs manual distinction - -4. **Be Practical**: - - Focus on incremental, testable changes - - Consider migration and rollback - - Think about edge cases - - Include "what we're NOT doing" - -5. **Track Progress**: - - Use TodoWrite to track planning tasks - - Update todos as you complete research - - Mark planning tasks complete when done - -6. **No Open Questions in Final Plan**: - - If you encounter open questions during planning, STOP - - Research or ask for clarification immediately - - Do NOT write the plan with unresolved questions - - The implementation plan must be complete and actionable - - Every decision must be made before finalizing the plan - -## Success Criteria Guidelines - -**Always separate success criteria into two categories:** - -1. **Automated Verification** (can be run by execution agents): - - Commands that can be run: `make test`, `npm test`, etc. - - Specific files that should exist - - Code compilation/type checking - - Automated test suites - -2. **Manual Verification** (requires human testing): - - UI/UX functionality - - Performance under real conditions - - Edge cases that are hard to automate - - User acceptance criteria - -## Sub-task Spawning Best Practices - -When spawning research sub-tasks: - -1. **Spawn multiple tasks in parallel** for efficiency -2. **Each task should be focused** on a specific area -3. **Provide detailed instructions** including: - - Exactly what to search for - - Which directories to focus on - - What information to extract - - Expected output format -4. **Specify read-only tools** to use -5. **Request specific file:line references** in responses -6. **Wait for all tasks to complete** before synthesizing -7. **Verify sub-task results**: - - If a sub-task returns unexpected results, spawn follow-up tasks - - Cross-check findings against the actual codebase - - Don't accept results that seem incorrect diff --git a/.claude/commands/create_worktree.md b/.claude/commands/create_worktree.md deleted file mode 100644 index 2277a46..0000000 --- a/.claude/commands/create_worktree.md +++ /dev/null @@ -1,156 +0,0 @@ -# Create Worktree - -Create a new git worktree for isolated development work with proper safety protocols. - -## Safety Protocols - -**CRITICAL SAFETY CHECKS - NEVER SKIP:** - -1. Verify base branch (main/develop) is clean and up-to-date -2. Confirm tests/typecheck passes on base branch before creating worktree -3. Validate worktree setup completes successfully - -## Workflow - -### 1. Pre-flight Safety Checks - -First, verify the repository state: - -```bash -# Check current status -git status - -# Ensure we're on the base branch and it's clean -git checkout main # or develop -git pull origin main - -# Verify tests pass on base branch (adjust command to your project) -# npm test || echo "❌ Tests failing on base branch - fix before creating worktree" -``` - -**IMPORTANT:** If any of these checks fail, DO NOT proceed. Fix issues first. - -### 2. Gather Required Information - -Before creating the worktree, collect: - -- **Ticket ID** (e.g., TICKET-123) - if applicable -- **Descriptive branch name** (e.g., feat/add-user-authentication) -- **Plan file path** (relative path from project root) - if applicable - -### 3. Create Worktree - -```bash -# Create worktree directory -BRANCH_NAME="feat/your-feature-name" -PROJECT_NAME=$(basename $(pwd)) -WORKTREE_PATH="../${PROJECT_NAME}-${BRANCH_NAME}" - -# Create new branch and worktree -git worktree add -b "$BRANCH_NAME" "$WORKTREE_PATH" main -``` - -**Examples:** - -```bash -# Create feature branch worktree -git worktree add -b feat/user-auth ../myproject-user-auth main - -# Create fix branch worktree -git worktree add -b fix/login-bug ../myproject-login-fix main -``` - -### 4. Setup Worktree - -After creating the worktree: - -```bash -cd "$WORKTREE_PATH" - -# Copy environment files (adjust paths to your project) -cp ../original-project/.env .env - -# Install dependencies (adjust to your package manager) -npm install # or pnpm install, yarn, etc. - -# Verify setup -npm test # or your project's verification command -``` - -### 5. Navigate to Worktree - -```bash -# Navigate to the worktree -cd "$WORKTREE_PATH" - -# Verify you're in the worktree -git branch --show-current # Should show your new branch -pwd # Should show worktree path -``` - -### 6. Begin Development - -The worktree is now ready for isolated development: - -- Separate working directory -- Own dependencies after install -- Can run services independently -- Ready for implementation - -## Important Path Notes - -**Thoughts Directory:** - -- The `thoughts/` directory exists in each worktree -- Use relative paths starting with `thoughts/...` -- Example: `thoughts/plans/implement-feature.md` - -## Error Recovery - -**If worktree creation fails:** - -1. Check the error message -2. Verify base branch passes tests -3. Ensure you have write permissions to the parent directory -4. Check available disk space - -**If you need to clean up manually:** - -```bash -# Remove worktree -git worktree remove --force "$WORKTREE_PATH" - -# Delete the branch (if needed) -git branch -D "$BRANCH_NAME" - -# Prune stale worktree references -git worktree prune -``` - -## Best Practices - -**DO:** - -- Always create worktrees from a clean, tested base branch -- Use descriptive branch names (feat/, fix/, refactor/) -- Copy necessary .env files before running -- Verify worktree setup completes successfully - -**DON'T:** - -- Skip the pre-flight safety checks -- Create worktrees from broken branches -- Share database connections between worktrees running simultaneously -- Force worktree creation if setup fails - -## Integration with Implementation - -After worktree creation, you can: - -1. Navigate to the worktree -2. Run `/create_plan` to create an implementation plan -3. Follow normal development workflow in isolation -4. Create commits and PRs from the worktree -5. Clean up when work is complete - -The worktree provides complete isolation for parallel development. diff --git a/.claude/commands/debug-ponder.md b/.claude/commands/debug-ponder.md index bac77f3..d9f2d16 100644 --- a/.claude/commands/debug-ponder.md +++ b/.claude/commands/debug-ponder.md @@ -6,6 +6,30 @@ Analyze `ponder.log` to diagnose indexer issues. Run after `pnpm dev --disable-u **NEVER use the `Read` tool on `ponder.log`** — the file is too large and will crash context. Use only `Bash` with `grep`, `tail`, or `sed`. +## Log Format + +Handler code uses a structured JSON logger (`src/application/helpers/logger.ts`). Each `log(level, msg, fields)` call emits exactly one JSON line: + +```json +{"time":1700000000000,"level":"info","msg":"OrderDiscoveryPoller:DONE","block":"12345678","chainId":1,"due":12,"success":2,"never":0,"backedOff":0} +``` + +Practical consequences for grep: +- The `msg` token is the stable search key. Grep it directly: `grep OrderDiscoveryPoller:DONE ponder.log` (or `grep '"OrderDiscoveryPoller:DONE"'` to avoid substring collisions). +- Fields like `block`, `chainId`, `owner`, `due` are JSON keys, not `key=value` text. Filter on them with `grep '"chainId":100'`, not `grep 'chain=100'`. +- Severity is the JSON `"level"` key (`info` / `warn` / `error`), not a bare `INFO` / `WARN` / `ERROR` word — though Ponder's own framework lines still use the bare-word format, so both appear in the file. +- Pretty-print a matched line with `jq`: `grep OrderDiscoveryPoller:DONE ponder.log | tail -1 | jq`. + +The block handlers split work across five Ponder block entries. The canonical handler names are: + +| Handler | Role | +|---------|------| +| `OrderDiscoveryPoller` | RPC multicall for non-deterministic generators, every block | +| `CandidateConfirmer` | API batch check for unconfirmed candidates, every block | +| `OrderStatusTracker` | API batch check for open discrete orders + expiry, every block | +| `OwnerBackfill` | One-shot owner fetch for non-deterministic backfill orders | +| `CancellationWatcher` | `singleOrders()` mapping read for deterministic generators OrderDiscoveryPoller skips | + --- ## Investigation Steps @@ -15,39 +39,42 @@ Run all steps before reporting. If a step returns nothing, note it explicitly ### Step 1 — Fatal errors ```bash -grep -n "ERROR" ponder.log | head -40 +# Framework errors (bare-word) plus structured error lines +grep -n "ERROR\|\"level\":\"error\"" ponder.log | head -40 ``` If any errors found, grab context around the first one: ```bash # Replace N with the line number from above -grep -n "ERROR" ponder.log | head -1 +grep -n "ERROR\|\"level\":\"error\"" ponder.log | head -1 # Then run: sed -n 'N-2,N+20p' ponder.log ``` ### Step 2 — Warnings ```bash -grep -n "WARN\|console.warn\|\[ComposableCow\].*failed\|\[ComposableCow\].*Unknown" ponder.log | head -40 +grep -n "WARN\|\"level\":\"warn\"" ponder.log | head -40 ``` +The structured warn lines worth scanning include `composableCow:decodeFailed`, `composableCow:unknownHandler`, the `ob:*` fetch failures/timeouts, and the `*:multicall_timeout` handler lines. + ### Step 3 — Handler events (success path) ```bash -grep -n "\[ComposableCow\]" ponder.log | tail -30 +grep -n "composableCow:" ponder.log | tail -30 ``` Healthy output looks like: -``` -[ComposableCow] ConditionalOrderCreated event=... orderType=TWAP block=... -[ComposableCow] Decoded event=... orderType=TWAP decodedParams=ok +```json +{"level":"info","msg":"composableCow:created","event":"...","chainId":1,"orderType":"TWAP","block":"..."} +{"level":"info","msg":"composableCow:decoded","event":"...","orderType":"TWAP","decodedParams":"ok"} ``` Red flags: -- `decodedParams=null` on a known orderType → decoder returned nothing -- `Decode failed` line → malformed staticInput, check `decodeError` column in DB -- `Unknown handler` line → address not in `HANDLER_MAP` in `src/utils/order-types.ts` +- `composableCow:decoded` with `"decodedParams":"null"` on a known orderType -> decoder returned nothing +- `composableCow:decodeFailed` line -> malformed staticInput; the `err` field has the message +- `composableCow:unknownHandler` line -> address not in `HANDLER_MAP` in `src/utils/order-types.ts` ### Step 4 — Startup / DB / RPC health @@ -55,7 +82,7 @@ Red flags: grep -n "INFO\|WARN\|ERROR" ponder.log | head -20 ``` -Healthy startup sequence: +These are Ponder's own framework lines (bare-word format). Healthy startup sequence: ``` INFO Connected to database INFO Connected to JSON-RPC @@ -107,158 +134,130 @@ After running all steps, output: ## Precompute Diagnostics -Deterministic types (TWAP, StopLoss) should have all UIDs precomputed at creation — they should NOT appear in C1 polling. If precompute fails, the generator falls into C1 and wastes RPC calls every block. +Deterministic types (TWAP, StopLoss) should have all UIDs precomputed at creation — they should NOT appear in `OrderDiscoveryPoller` polling. If precompute fails, the generator falls into OrderDiscoveryPoller and wastes RPC calls every block. -### Precompute failures — why generators fall into C1 +### Precompute failures — why generators fall into OrderDiscoveryPoller ```bash -grep -n "\[COW:PRECOMPUTE\] SKIP" ponder.log | head -20 +grep -n "precompute:skip" ponder.log | head -20 ``` -Each line is a deterministic generator that FAILED precompute and will fall into C1 polling. The `reason=` field tells you why: +Each line is a deterministic generator that FAILED precompute and will fall into OrderDiscoveryPoller polling. The JSON `reason` field tells you why: | reason | meaning | fix | |--------|---------|-----| | `decodedParams_null` | Decode of staticInput returned null | Check decoder for that order type; likely malformed on-chain data | -| `missing_params` | Required fields missing after decode (see `missing=` for which) | Decoder returned incomplete data | +| `missing_params` | Required fields missing after decode (see the `missing` field for which) | Decoder returned incomplete data | | `invalid_math` | nParts <= 0 or tSeconds <= 0 | Invalid TWAP params on-chain | | `too_many_parts` | nParts > 100,000 | Extremely large TWAP; raise limit if legitimate | -**If you see SKIP lines**: count them and cross-reference with C1's `due=` count. If they match, precompute failures are the sole cause of C1 polling for deterministic types. +**If you see skip lines**: count them and cross-reference with OrderDiscoveryPoller's `due` count. If they match, precompute failures are the sole cause of OrderDiscoveryPoller polling for deterministic types. + +```bash +grep -c "precompute:skip" ponder.log +``` + +The counterpart success log is `precompute:allTerminal` (all UIDs for a generator precomputed up front): ```bash -grep -c "\[COW:PRECOMPUTE\] SKIP" ponder.log +grep -c "precompute:allTerminal" ponder.log ``` -### Verify deterministic types are NOT in C1 +### Verify deterministic types are NOT in OrderDiscoveryPoller -After precompute fixes, C1 should only poll non-deterministic types. Check if C1 success lines show TWAP/StopLoss (they shouldn't): +After precompute fixes, OrderDiscoveryPoller should only poll non-deterministic types. Inspect recent OrderDiscoveryPoller DONE lines on gnosis: ```bash -grep "\[COW:C1\] DONE" ponder.log | grep 'chain=100' | tail -5 +grep '"OrderDiscoveryPoller:DONE"' ponder.log | grep '"chainId":100' | tail -5 ``` -A healthy `due=` count should be much smaller than total generators — only non-deterministic types should remain. +A healthy `due` count should be much smaller than total generators — only non-deterministic types should remain. --- -## Orderbook Cache (M3) +## Orderbook Cache The `orderbook_cache` table persists across Ponder resyncs (it is NOT an `onchainTable`). These steps verify the cache is alive and working. ### Cache startup — verify persistence across restarts -Look for the setup log emitted once at startup: +Look for the setup log emitted once at startup (`setup:cacheReady`): ```bash -grep -n "\[COW:SETUP\]" ponder.log | head -5 +grep -n "setup:cacheReady" ponder.log | head -5 ``` -Healthy output: -``` -[COW:SETUP] orderbook_cache ready — 42 entries from previous run -``` - -If you see `0 entries from previous run` on a restart (not a first run), the cache table was dropped — this indicates a schema migration or Docker volume wipe, not a bug. - -### Cache hits — verify terminal owners are served from cache - -```bash -grep -n "\[COW:OB:CACHE\] HIT" ponder.log | tail -20 +Healthy output (the `count` field is the row count loaded from the previous run): +```json +{"level":"info","msg":"setup:cacheReady","count":42,"entries":"42 entries from previous run"} ``` -Each line confirms a terminal owner was served from cache instead of hitting the API: -``` -[COW:OB:CACHE] HIT owner=0x1234... chain=1 orders=5 -``` +If you see `"count":0` on a restart (not a first run), the cache table was dropped — this indicates a schema migration or Docker volume wipe, not a bug. -If you see zero hits after a warm restart, the cache was not populated in the previous run (all owners were non-terminal) or the table was reset. +### Orderbook fetches — what is served from cache vs. the API -### Cache saves — verify terminal owners are being cached +Each orderbook fetch emits an `ob:fetch` entry on start and an `ob:fetchResult` on completion. The result line carries the cache breakdown: ```bash -grep -n "\[COW:OB:CACHE\] SAVED" ponder.log | tail -20 +grep -n "ob:fetchResult" ponder.log | tail -20 ``` Healthy output: +```json +{"level":"info","msg":"ob:fetchResult","owner":"0x1234...","chainId":1,"apiTotal":12,"composable":5,"cached":3,"refreshed":2} ``` -[COW:OB:CACHE] SAVED owner=0x1234... chain=1 orders=3 (all terminal, cached permanently) -``` - -Active owners (with any `open` order) are intentionally NOT saved — they must be re-fetched on every poll cycle. - -### Orderbook poll cycle metrics - -```bash -grep -n "\[COW:OB:POLL\] DONE" ponder.log | tail -10 -``` - -Healthy output includes cache hit ratio and active owner count: -``` -[COW:OB:POLL] DONE block=12345678 chain=1 owners=20 discovered=3 cacheHits=15 apiFetches=5 activeOwners=2 totalOrders=47 -``` - -High `cacheHits` relative to `owners` means the cache is working. High `apiFetches` with low `activeOwners` may indicate many owners are not yet cached. -### C4 HistoricalBootstrap — one-shot (`endBlock: "latest"`) — PR #29 entrada 9 +- `cached` = composable orders served from the cache (no per-UID status refresh needed). +- `refreshed` = composable orders whose status was re-fetched this cycle. -`HistoricalBootstrap` in `ponder.config.ts` uses `startBlock: "latest"` and `endBlock: "latest"` so it should run **once per chain** when the indexer reaches live (not every block). Use logs to confirm. +High `cached` relative to `composable` means the cache is working. If `cached` stays near zero after a warm restart, the cache was not populated in the previous run (all owners were non-terminal) or the table was reset. -**Invocation counter (expect `#1` only per chain per process):** +Fetch-side failures and timeouts are warn lines worth scanning when fetches look wrong: ```bash -grep -n "\[COW:C4\] HistoricalBootstrap invocation" ponder.log +grep -nE "ob:(noApiUrl|accountError|accountFetchFailed|accountTimeout|batchFetchError|batchFetchFailed|batchFetchTimeout|statusByUidsTimeout)" ponder.log | tail -20 ``` -Healthy output (one line per chain after live starts): +### OwnerBackfill — one-shot (`endBlock: "latest"`) -``` -... [COW:C4] HistoricalBootstrap invocation=#1 chain=1 block=... (one-shot bootstrap; see .claude/commands/debug-ponder.md — C4 section) -``` - -If you see **`invocation=#2`** or a **`WARN`** line saying *invocation #2* / *repeats every block*, `endBlock: "latest"` is not behaving as a one-shot in your Ponder version — escalate or check Ponder release notes. A **full resync** resets the process: you will see `#1` again on the next run (expected). - -**Full C4 trace (bootstrap work or empty):** +`OwnerBackfill` in `ponder.config.ts` uses `startBlock: "latest"` and `endBlock: "latest"` so it should run **once per chain** when the indexer reaches live (not every block). Use logs to confirm. ```bash -grep -n "\[COW:C4\]" ponder.log +grep -nE "OwnerBackfill:(START|bootstrap_start|no_bootstrap_needed|DONE)" ponder.log ``` -You should see `invocation=#1`, then either `no generators need bootstrap` or `generators=...` + `DONE`, then **no further `[COW:C4]` lines** for that chain until restart. - -### Backfill skip — verify poller is not running during historical sync - -During backfill, the orderbook poller is silently skipped (no log line). To confirm live-only behavior, check that poll DONE lines only appear near the tip: - -```bash -grep -n "\[COW:OB:POLL\] DONE" ponder.log | head -5 +Healthy output (per chain, after live sync starts): +```json +{"level":"info","msg":"OwnerBackfill:START","block":"...","chainId":1,"pendingRetry":0} +{"level":"info","msg":"OwnerBackfill:bootstrap_start","block":"...","chainId":1,"generators":7,"freshOwners":7} +{"level":"info","msg":"OwnerBackfill:DONE","block":"...","chainId":1,"discovered":3} ``` -The `block=` values should be close to the current chain head. If you see poll DONE lines during historical blocks, the `PollResultPoller` start block may not be set to `"latest"`. +When nothing needs bootstrapping you get `OwnerBackfill:no_bootstrap_needed` instead of `bootstrap_start`/`DONE`. Either way you should see this sequence run roughly once per chain after live, not every block. Owner-fetch timeouts during bootstrap surface as `OwnerBackfill:owner_timeout` (and `OwnerBackfill:owner_retry_timeout` on the retry queue) — both carry the offending `owner` and `timeoutMs`. A **full resync** resets the process and you will see the START/DONE pair fire again on the next run (expected). --- -## C1 tryNextBlock backoff +## OrderDiscoveryPoller tryNextBlock backoff Generators that keep returning `PollResult.tryNextBlock` are progressively rate-limited. After 50 consecutive tryNextBlock responses the recheck interval jumps from +1 to +10 blocks; after 200, to +50. ### DONE log — backoff count per cycle ```bash -grep -n "\[COW:C1\] DONE" ponder.log | tail -20 +grep -n '"OrderDiscoveryPoller:DONE"' ponder.log | tail -20 ``` Healthy output (mainnet, few stuck generators): -``` -[COW:C1] DONE block=12345678 chain=1 due=12 success=2 never=0 backedOff=0 +```json +{"level":"info","msg":"OrderDiscoveryPoller:DONE","block":"12345678","chainId":1,"due":12,"success":2,"never":0,"backedOff":0,"capped":false} ``` -Gnosis after warm-up — expect non-zero `backedOff=` as chronic offenders climb past the 50-threshold: -``` -[COW:C1] DONE block=45678901 chain=100 due=180 success=3 never=0 backedOff=150 +Gnosis after warm-up — expect non-zero `backedOff` as chronic offenders climb past the 50-threshold: +```json +{"level":"info","msg":"OrderDiscoveryPoller:DONE","block":"45678901","chainId":100,"due":180,"success":3,"never":0,"backedOff":150,"capped":false} ``` -`backedOff=` counts generators whose counter exceeded the warmup threshold on *this* block — i.e., they received a backoff longer than +1. +`backedOff` counts generators whose counter exceeded the warmup threshold on *this* block — i.e., they received a backoff longer than +1. A `"NEVER"` entry (`OrderDiscoveryPoller:NEVER`) records a generator that returned `PollResult.dontTryNextBlock` with its `reason`. ### Counter distribution — verify the mechanism is climbing @@ -279,49 +278,49 @@ GROUP BY 1, 2 ORDER BY 1, 2; ``` -On a healthy gnosis run post-sync you should see a non-trivial bucket in `51-200` and/or `201+`. If everything sits at `0-50` after >300 gnosis blocks, either COW-904 eliminated all such generators (success) *or* the counter is not incrementing (bug). +On a healthy gnosis run post-sync you should see a non-trivial bucket in `51-200` and/or `201+`. If everything sits at `0-50` after >300 gnosis blocks, either there genuinely are no chronic tryNextBlock generators (precompute eliminated them — success) *or* the counter is not incrementing (bug). -### Red flag — counter stuck high but `due=` still huge +### Red flag — counter stuck high but `due` still huge -If `consecutive_try_next_block` is large for many generators *and* the C1 `due=` count is still massive every block, the backoff is not actually deferring those generators — check that the C1 SELECT filters by `nextCheckBlock <= currentBlock` and that the handler updated `nextCheckBlock = currentBlock + ` correctly on tryNextBlock. +If `consecutive_try_next_block` is large for many generators *and* the OrderDiscoveryPoller `due` count is still massive every block, the backoff is not actually deferring those generators — check that the OrderDiscoveryPoller SELECT filters by `nextCheckBlock <= currentBlock` and that the handler updated `nextCheckBlock = currentBlock + ` correctly on tryNextBlock. --- -## C5 DeterministicCancellationSweeper — singleOrders() mapping sweep +## CancellationWatcher — singleOrders() mapping sweep -`DeterministicCancellationSweeper` in `ponder.config.ts` runs every block but only does work when at least one deterministic generator (`allCandidatesKnown = true AND status = "Active"`) has `nextCheckBlock <= currentBlock`. Per-generator cadence is `DETERMINISTIC_CANCEL_SWEEP_INTERVAL` blocks (see `src/constants.ts`, default 100). The handler reads `ComposableCoW.singleOrders(owner, hash)` — `false` means the owner called `remove()` on-chain. +`CancellationWatcher` in `ponder.config.ts` runs every block but only does work when at least one deterministic generator (`allCandidatesKnown = true AND status = "Active"`) has `nextCheckBlock <= currentBlock`. Per-generator cadence is `DETERMINISTIC_CANCEL_SWEEP_INTERVAL` blocks (see `src/constants.ts`, default 100). The handler reads `ComposableCoW.singleOrders(owner, hash)` — `false` means the owner called `remove()` on-chain. ### ENTER / DONE — per-sweep summary ```bash -grep -n "\[COW:C5\]" ponder.log | tail -40 +grep -nE "CancellationWatcher:(ENTER|DONE)" ponder.log | tail -40 ``` Healthy output (one ENTER + one DONE per block where work happens): -``` -... [COW:C5] ENTER block=... chain=1 due=12 -... [COW:C5] DONE block=... chain=1 due=12 cancelled=0 stillActive=12 errors=0 +```json +{"level":"info","msg":"CancellationWatcher:ENTER","block":"...","chainId":1,"due":12} +{"level":"info","msg":"CancellationWatcher:DONE","block":"...","chainId":1,"due":12,"cancelled":0,"stillActive":12,"errors":0} ``` -If `due=0` on every block for a long time, either there are no Active deterministic generators on that chain yet, or the kill-switch is on (see below). +If `due` is 0 on every block for a long time, either there are no Active deterministic generators on that chain yet, or the kill-switch is on (see below). When the multicall itself times out you get `CancellationWatcher:multicall_timeout` instead of a DONE line. ### Cancellations detected ```bash -grep -n "\[COW:C5\] CANCELLED" ponder.log +grep -n "CancellationWatcher:CANCELLED" ponder.log ``` Each line is a deterministic generator whose on-chain `singleOrders(owner, hash)` returned `false`: -``` -[COW:C5] CANCELLED generatorId=... orderType=StopLoss block=... chain=1 +```json +{"level":"info","msg":"CancellationWatcher:CANCELLED","block":"...","chainId":1,"generatorId":"...","orderType":"StopLoss"} ``` -After any `CANCELLED` line you should see COW-918's cascade fire on the next C2 block tick: -``` -[COW:C2] block=... chain=1 parent-cancelled=N ← candidates drained to discrete_order +After any `CANCELLED` line the candidate-cancellation cascade fires on the next CandidateConfirmer block tick — candidates are drained to `discrete_order`: +```json +{"level":"info","msg":"CandidateConfirmer:parent_cancelled","block":"...","chainId":1,"parentCancelled":3,"preflightKnown":0} ``` -C3's parent-cancelled sweep has no dedicated log line — verify via SQL: +The OrderStatusTracker parent-cancelled sweep has no dedicated log line — verify via SQL: ```sql SELECT count(*) FROM discrete_order WHERE status='cancelled' AND conditional_order_generator_id = ''; @@ -329,20 +328,11 @@ WHERE status='cancelled' AND conditional_order_generator_id = ''; ### Multicall errors -`errors > 0` on a DONE line is not fatal: C5 leaves `nextCheckBlock` untouched for errored entries so they retry on the next sweep. Sustained nonzero `errors` across many blocks means the RPC provider is flaky — consider swapping provider (see COW-887 on DRPC flakiness). - -### Sweep disabled (kill-switch) - -If operators see no `[COW:C5]` lines at all and expect them: -```bash -grep -n "DISABLE_DETERMINISTIC_CANCEL_SWEEP" .env.local env.prod 2>/dev/null -``` - -Non-empty means the sweeper is intentionally disabled via env var — same pattern as `DISABLE_POLL_RESULT_CHECK` for C1. +`errors > 0` on a DONE line is not fatal: CancellationWatcher leaves `nextCheckBlock` untouched for errored entries so they retry on the next sweep. Sustained nonzero `errors` across many blocks means the RPC provider is flaky — consider swapping provider. ### lastPollResult audit -SQL spot-check for what C5 has touched: +SQL spot-check for what CancellationWatcher has touched: ```sql SELECT chain_id, order_type, status, last_poll_result, count(*) FROM conditional_order_generator @@ -364,3 +354,4 @@ ORDER BY 1,2,3,4; | `Unknown handler ... saving as Unknown` | Handler address not in `HANDLER_MAP` in `src/utils/order-types.ts` | Add address to map; expected for new/unsupported contracts | | `Decode failed ... orderType=...` | `staticInput` does not match expected ABI for that order type | Check ABI tuple in `src/decoders/.ts`; compare with `agent_docs/decoder-reference.md` | | `Fetching backfill JSON-RPC data is taking longer than expected` | RPC rate limit or slow provider | Transient — monitor; switch RPC if persistent | +| `[COW:timeout]