# Task Granularity Standards A task must be specific enough for execution without interpretation. Vague tasks cause agents to guess, leading to inconsistent results and rework. ## The Granularity Test Ask: **Can an agent execute this task without making assumptions?** If the answer requires "it depends" or "probably means", the task is too vague. --- ## Comparison Table | Too Vague | Just Right | |-----------|------------| | "Add authentication" | "Add JWT auth with refresh rotation using jose library, store in httpOnly cookie, 15min access / 7day refresh" | | "Create the API" | "Create POST /api/projects accepting {name, description}, validates name length 3-50 chars, returns 201 with project object" | | "Style the dashboard" | "Add Tailwind classes to Dashboard.tsx: grid layout (3 cols on lg, 1 on mobile), card shadows, hover states on action buttons" | | "Handle errors" | "Wrap API calls in try/catch, return {error: string} on 4xx/5xx, show toast via sonner on client" | | "Add form validation" | "Add Zod schema to CreateProjectForm: name (3-50 chars, alphanumeric), description (optional, max 500 chars), show inline errors" | | "Improve performance" | "Add React.memo to ProjectCard, useMemo for filtered list in Dashboard, lazy load ProjectDetails route" | | "Fix the login bug" | "Fix login redirect loop: after successful login in auth.ts:45, redirect to stored returnUrl instead of always '/' " | | "Set up the database" | "Create SQLite database at data/cw.db with migrations in db/migrations/, run via 'cw db migrate'" | --- ## Required Task Components Every task MUST include: ### 1. Files Exact paths that will be created or modified. ```yaml files: - src/components/Chat.tsx # create - src/hooks/useChat.ts # create - src/api/messages.ts # modify ``` ### 2. Action What to do, what to avoid, and WHY. ```yaml action: | Create Chat component with: - Message list (virtualized for performance) - Input field with send button - Auto-scroll to bottom on new message DO NOT: - Implement WebSocket (separate task) - Add typing indicators (Phase 2) WHY: Core chat UI needed before real-time features ``` ### 3. Verify Command or check to prove completion. ```yaml verify: - command: "npm run typecheck" expect: "No type errors" - command: "npm run test -- Chat.test.tsx" expect: "Tests pass" - manual: "Navigate to /chat, see empty message list and input" ``` ### 4. Done Measurable acceptance criteria. ```yaml done: - "Chat component renders without errors" - "Input accepts text and clears on submit" - "Messages display in chronological order" - "Tests cover send and display functionality" ``` --- ## Task Types ### Type: auto Agent executes autonomously. ```yaml type: auto files: [src/components/Button.tsx] action: "Create Button component with primary/secondary variants using Tailwind" verify: "npm run typecheck && npm run test" done: "Button renders with correct styles for each variant" ``` ### Type: checkpoint:human-verify Agent completes, human confirms. ```yaml type: checkpoint:human-verify files: [src/pages/Dashboard.tsx] action: "Implement dashboard layout with project cards" verify: "Navigate to /dashboard after login" prompt: "Does the dashboard match the design mockup?" done: "User confirms layout is correct" ``` ### Type: checkpoint:decision Human makes choice that affects implementation. ```yaml type: checkpoint:decision prompt: "Which chart library should we use?" options: - recharts: "React-native, good for simple charts" - d3: "More powerful, steeper learning curve" - chart.js: "Lightweight, canvas-based" affects: "All subsequent charting tasks" ``` ### Type: checkpoint:human-action Unavoidable manual step. ```yaml type: checkpoint:human-action prompt: "Please click the verification link sent to your email" reason: "Cannot automate email client interaction" continue_after: "User confirms email verified" ``` --- ## Time Estimation Tasks should fit within context budgets: | Complexity | Context % | Wall Time | Example | |------------|-----------|-----------|---------| | Trivial | 5-10% | 2-5 min | Add a CSS class | | Simple | 10-20% | 5-15 min | Add form field | | Medium | 20-35% | 15-30 min | Create API endpoint | | Complex | 35-50% | 30-60 min | Implement auth flow | | Too Large | >50% | - | **SPLIT REQUIRED** | --- ## Splitting Large Tasks When a task exceeds 50% context estimate, decompose: ### Before (Too Large) ```yaml title: "Implement user authentication" # This is 3+ hours of work, dozens of decisions ``` ### After (Properly Decomposed) ```yaml tasks: - title: "Create users table with password hash" files: [db/migrations/001_users.sql] - title: "Add signup endpoint with Zod validation" files: [src/api/auth/signup.ts] depends_on: [users-table] - title: "Add login endpoint with JWT generation" files: [src/api/auth/login.ts] depends_on: [users-table] - title: "Create auth middleware for protected routes" files: [src/middleware/auth.ts] depends_on: [login-endpoint] - title: "Add refresh token rotation" files: [src/api/auth/refresh.ts, db/migrations/002_refresh_tokens.sql] depends_on: [auth-middleware] ``` --- ## Anti-Patterns ### Vague Verbs **Bad:** "Improve", "Enhance", "Update", "Fix" (without specifics) **Good:** "Add X", "Change Y to Z", "Remove W" ### Missing Constraints **Bad:** "Add validation" **Good:** "Add Zod validation: email format, password 8+ chars with number" ### Implied Knowledge **Bad:** "Handle the edge cases" **Good:** "Handle: empty input (show error), network failure (retry 3x), duplicate email (show message)" ### Compound Tasks **Bad:** "Set up auth and create the user management pages" **Good:** Two separate tasks with dependency ### No Success Criteria **Bad:** "Make it work" **Good:** "Tests pass, no TypeScript errors, manual verification of happy path" --- ## Examples by Domain ### API Endpoint ```yaml title: "Create POST /api/projects endpoint" files: - src/api/projects/create.ts - src/api/projects/schema.ts action: | Create endpoint accepting: - name: string (3-50 chars, required) - description: string (max 500 chars, optional) Returns: - 201: { id, name, description, createdAt } - 400: { error: "validation message" } - 401: { error: "Unauthorized" } Use Zod for validation, drizzle for DB insert. verify: - "npm run test -- projects.test.ts" - "curl -X POST /api/projects -d '{\"name\": \"Test\"}' returns 201" done: - "Endpoint creates project in database" - "Validation rejects invalid input with clear messages" - "Auth middleware blocks unauthenticated requests" ``` ### React Component ```yaml title: "Create ProjectCard component" files: - src/components/ProjectCard.tsx - src/components/ProjectCard.test.tsx action: | Create card displaying: - Project name (truncate at 30 chars) - Description preview (2 lines max) - Created date (relative: "2 days ago") - Status badge (active/archived) Props: { project: Project, onClick: () => void } Use Tailwind: rounded-lg, shadow-sm, hover:shadow-md verify: - "npm run typecheck" - "npm run test -- ProjectCard" - "Storybook renders all variants" done: - "Card renders with all project fields" - "Truncation works for long names" - "Hover state visible" - "Click handler fires" ``` ### Database Migration ```yaml title: "Create projects table" files: - db/migrations/003_projects.sql - src/db/schema/projects.ts action: | Create table: - id: TEXT PRIMARY KEY (uuid) - user_id: TEXT NOT NULL REFERENCES users(id) - name: TEXT NOT NULL - description: TEXT - status: TEXT DEFAULT 'active' CHECK (IN 'active', 'archived') - created_at: INTEGER DEFAULT unixepoch() - updated_at: INTEGER DEFAULT unixepoch() Indexes: user_id, status, created_at DESC verify: - "cw db migrate runs without error" - "sqlite3 data/cw.db '.schema projects' shows correct schema" done: - "Migration applies cleanly" - "Drizzle schema matches SQL" - "Indexes created" ``` --- ## Checklist Before Creating Task - [ ] Can an agent execute this without asking questions? - [ ] Are all files listed explicitly? - [ ] Is the action specific (not "improve" or "handle")? - [ ] Is there a concrete verify step? - [ ] Are done criteria measurable? - [ ] Does estimated context fit under 50%? - [ ] Are there no compound actions (split if needed)?