# Task Writing Guide for AI Agents This guide helps create clear, actionable tasks that AI agents (and human developers) can implement efficiently. Well-written tasks reduce back-and-forth, minimize exploration time, and lead to better implementations. ## Important: Task Identifiers Are Auto-Generated **DO NOT specify identifiers when creating tasks.** The system automatically generates human-readable identifiers for all tasks: - **G1, G2, G3...** - Goals (large initiatives, 25+ hours, contain multiple tasks) - **W1, W2, W3...** - Work tasks (individual work items, 1-3 hours) - **D1, D2, D3...** - Defects (bug fixes and defect corrections) **What this means for you:** - When creating tasks via `POST /api/tasks`, **never** include an `identifier` field - The system will automatically assign the next available identifier (e.g., W42, G5, D12) - Identifiers are globally unique and sequential - You can reference tasks by identifier after they're created (e.g., "W42 depends on W15") **Example - Creating a Goal with Tasks:** ```json { "goal": { "title": "Implement search feature", "tasks": [ { "title": "Add search schema", "type": "work" }, { "title": "Build search UI", "type": "work" } ] } } ``` **System generates:** - Goal: `G1 - Implement search feature` - Task 1: `W1 - Add search schema` - Task 2: `W2 - Build search UI` ## Understanding the 2-Level Task Hierarchy Stride uses a **2-level hierarchy** to organize work effectively: ### The Two Levels 1. **Goals (G prefix)** - Large initiatives requiring 25+ hours - Container for multiple related tasks - Identifier: G1, G2, G3, etc. - Has `parent_id` of `nil` (top-level) - Progress tracked automatically (e.g., "7/13 tasks complete") - Moves through workflow automatically based on child task states 2. **Tasks (W/D prefix)** - Individual work items (1-3 hours each) - **Work tasks (W prefix)** - New functionality, enhancements - **Defects (D prefix)** - Bug fixes, corrections - Can belong to a goal (via `parent_id`) or be standalone - Moved manually through workflow columns ### When to Create a Goal **Create a Goal when:** - Planning large initiatives (25+ hours total) - Breaking down complex features into multiple work items - Grouping related tasks for a release or milestone - You need to track progress across multiple related tasks **Example - Single Goal:** ```json POST /api/tasks { "goal": { "title": "Implement user authentication system", "description": "Add comprehensive authentication with JWT tokens, password reset, and session management", "estimated_files": "10+", "tasks": [ { "title": "Add JWT library and configuration", "type": "work", "complexity": "small", "estimated_files": "2" }, { "title": "Create auth controller and endpoints", "type": "work", "complexity": "medium", "estimated_files": "3-4", "dependencies": [0] }, { "title": "Add password reset flow", "type": "work", "complexity": "medium", "estimated_files": "2-3", "dependencies": [1] }, { "title": "Fix password validation bug", "type": "defect", "complexity": "small", "estimated_files": "1" } ] } } ``` **Example - Multiple Goals at Once:** When you need to create several related goals (e.g., planning a sprint or project phase), use the batch endpoint to create them all in one API call: ```json POST /api/tasks/batch { "goals": [ { "title": "Implement user authentication system", "description": "Add comprehensive authentication with JWT tokens", "type": "goal", "priority": "high", "complexity": "large", "tasks": [ { "title": "Add JWT library and configuration", "type": "work", "complexity": "small" }, { "title": "Create auth controller and endpoints", "type": "work", "complexity": "medium", "dependencies": [0] } ] }, { "title": "User profile management", "description": "Allow users to view and edit profiles", "type": "goal", "priority": "medium", "complexity": "medium", "tasks": [ { "title": "Create profile schema", "type": "work", "complexity": "small" }, { "title": "Build profile view page", "type": "work", "complexity": "medium", "dependencies": [0] } ] } ] } ``` **⚠️ CRITICAL: Cross-Goal Dependencies** **DO NOT** specify dependencies between goals in a batch request like `"dependencies": ["G1"]`. This will NOT work because: - Identifiers (G1, G2, W1, W2) are auto-generated and cannot be predicted - The system determines identifiers based on existing tasks in the database - You cannot know if the first goal will be G1, G5, or G20 **Solutions for dependent goals:** 1. Create goals in **separate API calls** - Create the first goal, get its identifier from response, then create the second goal with the correct dependency 2. Add dependencies **after creation** using `PATCH /api/tasks/:id` 3. Keep goals **independent** if possible **Benefits of batch creation:** - Reduced API calls (1 request instead of N) - Faster project setup when planning multiple goals - Clear visibility of related work structure - Dependencies work within a goal's tasks (but NOT across goals) See [POST /api/tasks/batch](api/post_tasks_batch.md) for complete documentation. ### When to Use Flat Tasks **Create flat tasks when:** - Quick fixes or bugs (use `type: "defect"`) - Independent features (use `type: "work"`) - Simple requests that don't belong to a larger initiative - The work takes less than 8 hours total **Example:** ```json POST /api/tasks { "title": "Fix typo in welcome email", "type": "defect", "complexity": "small", "estimated_files": "1", "description": "The welcome email has 'recieve' instead of 'receive'" } ``` ### Why This Structure Works for Agents 1. **Natural planning structure** - Matches how you break down work mentally 2. **Progress visibility** - Goals show "7/13 tasks complete" automatically 3. **Context preservation** - If interrupted, goal shows full context and related tasks 4. **Scope management** - Easy to see what's part of a larger initiative 5. **Simpler than 3+ levels** - Only 2 levels means less overhead and complexity ### How Goals Move Through Workflow **Automatic movement:** - Goals are **not draggable** - they move automatically - When ALL child tasks are in the same column, the goal moves to that column - Goal positions itself BEFORE the first child task in the target column - Special case: When all tasks complete, goal moves to "Done" at the end **Example workflow:** ``` Initial state: - G1 (Ready) - "Implement auth" - W1 (Ready) - "Add JWT library" - W2 (Ready) - "Create controller" After W1 moves to Doing: - G1 (Ready) - "Implement auth" # Stays in Ready (not all tasks in same column) - W1 (Doing) - "Add JWT library" - W2 (Ready) - "Create controller" After W2 moves to Doing: - G1 (Doing) - "Implement auth" # Moves to Doing automatically - W1 (Doing) - "Add JWT library" - W2 (Doing) - "Create controller" After both complete: - G1 (Done) - "Implement auth" # Moves to Done automatically - W1 (Done) - "Add JWT library" - W2 (Done) - "Create controller" ``` ### Adding Tasks to Existing Goals You can attach tasks to existing goals by providing the goal's identifier: ```json POST /api/tasks { "title": "Add session timeout feature", "type": "work", "parent_goal": "G1", "complexity": "small", "estimated_files": "2-3" } ``` This task will become part of goal G1 and update its progress count. ## Why Structured JSON Format Matters for Agents When creating tasks, use **structured JSON** instead of free-form markdown for technical details. Here's why: ### Structured JSON is Significantly Better **✅ Advantages for agents:** 1. **Parseable & Actionable** - Agents can extract specific fields directly - See `key_files` → Read those files first - See `database_changes` → Generate migrations if needed - See `verification_steps` → Know exactly what to test 2. **Reduces Ambiguity** - Clear structure means clear expectations - "Modify these 3 files" vs "You'll probably need to change some files" - "Add these specific tests" vs "Make sure to test it" 3. **Saves Time** - No need to parse natural language or guess intent - Agent can jump directly to the right files - Clear verification steps mean no exploration needed - Explicit pitfalls and out_of_scope prevent wrong approaches 4. **Consistent** - Same structure across all tasks - Agents learn the pattern once - Easier to validate and query - Reduces miscommunication ### Example Comparison **❌ Markdown (Harder for agents):** ```markdown You'll need to modify the board LiveView and probably the Boards context. Look at how the status filter works and do something similar. Make sure to add tests. Oh and don't change the card layout. ``` **Problems:** - "probably" → uncertainty - "something similar" → vague - Which files exactly? → agent must guess - What tests specifically? → undefined **✅ Structured JSON (Better for agents):** ```json { "title": "Add priority filter to board view", "type": "work", "complexity": "medium", "key_files": [ { "file_path": "lib/kanban_web/live/board_live.ex", "note": "Add filter UI and handle_event", "position": 0 }, { "file_path": "lib/kanban/boards.ex", "note": "Add filter query logic", "position": 1 } ], "patterns_to_follow": "Use handle_event for filter changes (see status filter in lib/kanban_web/live/board_live/status_filter_component.ex)\nPut query logic in context module, not LiveView", "pitfalls": [ "Don't modify task card layout or styling" ], "verification_steps": [ { "step_type": "command", "step_text": "mix test test/kanban_web/live/board_live_test.exs", "expected_result": "All tests pass including new filter tests", "position": 0 }, { "step_type": "manual", "step_text": "Test filter by each priority level (0-4), clear filter shows all tasks, filter state persists in URL", "expected_result": "Filtering works correctly and state persists", "position": 1 } ] } ``` **Benefits:** - Agent knows exactly which files to modify - Clear patterns to follow with file references - Explicit pitfalls to avoid - Defined verification steps (both automated and manual) ### Hybrid Approach (Recommended) Use structured fields for machine-readable data, plus optional markdown for nuance: ```json { "title": "Implement password reset flow", "type": "work", "key_files": [ {"file_path": "lib/kanban_web/controllers/auth_controller.ex", "position": 0} ], "patterns_to_follow": "Use PHX.Token for reset tokens", "notes": "## Additional Context\n\nThe reset token should expire after 1 hour. Priority scale is 0-4 where 0 is highest (might be counterintuitive)." } ``` This gives you: - Precision where it matters (files, tests, patterns) - Flexibility for additional context - Agent efficiency - Human readability ### What to Make Structured **CRITICAL - Always specify these fields (they control task availability):** #### `key_files` - Files that will be modified **Why critical:** Prevents merge conflicts by ensuring only one task modifies a file at a time. - Tasks with overlapping `key_files` CANNOT be claimed simultaneously - If Task A is modifying `lib/auth.ex` and is in Doing or Review, Task B that also lists `lib/auth.ex` will NOT be claimable until Task A completes - **Specify key_files whenever possible**, even if it's an educated guess based on the task description - Better to specify approximately than to omit entirely **Format:** ```json "key_files": [ {"file_path": "lib/kanban_web/controllers/auth_controller.ex", "note": "Add authentication endpoints", "position": 0}, {"file_path": "lib/kanban/accounts.ex", "note": "User account logic", "position": 1}, {"file_path": "test/kanban/accounts_test.exs", "note": "Test coverage", "position": 2} ] ``` **Note:** Each key_file is an object with: - `file_path` (required) - Relative path from project root - `note` (optional) - Why this file is being modified - `position` (required) - Order in which files should be reviewed/modified (starts at 0) #### `dependencies` - Tasks that must complete first **Why critical:** Controls the order of work execution. - Tasks with unmet dependencies are NOT claimable, even if in the Ready column - Ensures work happens in correct order (e.g., schema before endpoints) - **Always specify dependencies** when one task builds on another's work - Don't rely on agents to infer order - be explicit **Format depends on context:** **When creating a goal with child tasks (initial upload):** Use **0-based array indices** to reference tasks within the same goal: ```json { "title": "Implement authentication", "type": "goal", "tasks": [ {"title": "Create schema", "type": "work"}, // index 0 {"title": "Add endpoints", "type": "work", "dependencies": [0]}, // depends on first task {"title": "Write tests", "type": "work", "dependencies": [0, 1]} // depends on first and second ] } ``` The system automatically converts indices to actual identifiers (W47, W48, etc.) during creation. **When creating standalone tasks or adding tasks to existing goals:** Use actual task identifiers: ```json { "title": "Add new feature", "type": "work", "dependencies": ["W47", "W48"] // This task requires W47 and W48 to complete first } ``` **When updating existing tasks:** Use actual task identifiers: ```json PATCH /api/tasks/123 { "dependencies": ["W47", "W48", "W52"] } ``` **You can also mix indices with existing identifiers (when creating goals):** ```json { "title": "Extend feature", "type": "goal", "tasks": [ {"title": "New component", "type": "work"}, {"title": "Integration", "type": "work", "dependencies": [0, "W23"]} // index 0 + existing task ] } ``` **Best Practice for Goals:** 1. Identify which tasks must happen sequentially 2. Use index-based dependencies (0, 1, 2) when creating the goal initially 3. Use identifier-based dependencies (W47, W48) when updating or referencing existing tasks 4. Only add dependencies when truly required (don't over-constrain parallelization) #### `testing_strategy` - Overall Testing Approach **Why critical:** Provides comprehensive testing guidance beyond simple verification commands. The `testing_strategy` field is a flexible JSON object that describes how to think about testing this task. Unlike `verification_steps` which focuses on *what commands to run*, `testing_strategy` explains *how to approach testing*. **Format:** ```json "testing_strategy": { "unit_tests": ["Test user changeset validations", "Test password hashing functions", "Test authentication token generation"], "integration_tests": ["Test complete login flow end-to-end", "Test password reset flow with email"], "manual_tests": ["Test password reset email in staging environment", "Verify session timeout behavior"], "property_tests": "Use StreamData to verify password encoding with random special characters", "coverage_target": "100% for auth module, 80% overall", "test_data": "Create fixtures for valid/invalid passwords, use Factory pattern", "mocking": "Mock external email service for password reset tests using Mox", "edge_cases": [ "Empty password", "Password with unicode characters", "Password exceeding max length", "Concurrent login attempts" ], "performance_tests": "Login should complete in <100ms for 95th percentile", "regression_tests": "Verify existing user sessions remain valid", "security_tests": "Test SQL injection, XSS, CSRF protections" } ``` **⚠️ CRITICAL: Field Types** The following fields **MUST be arrays of strings** (not single strings): - `unit_tests` - **array** of unit test descriptions - `integration_tests` - **array** of integration test descriptions - `manual_tests` - **array** of manual testing steps All other fields can be strings or arrays as appropriate. **Common fields (all optional):** - `unit_tests` (**array of strings**) - List of specific unit tests to write - `integration_tests` (**array of strings**) - List of integration/end-to-end tests - `manual_tests` (**array of strings**) - List of manual testing procedures - `property_tests` (string) - Property-based testing approach (e.g., StreamData, PropCheck) - `coverage_target` (string) - Target code coverage percentage or scope - `test_data` (string) - How to set up test fixtures, factories, or seed data - `mocking` (string) - What external dependencies to mock/stub and how - `edge_cases` (array of strings) - Specific edge cases that must be tested - `performance_tests` (string) - Performance criteria, benchmarks, or load tests - `regression_tests` (string) - What existing functionality to verify still works - `security_tests` (string) - Security-specific test scenarios **When to use testing_strategy vs verification_steps:** - `testing_strategy` - **How to think about testing**: coverage goals, edge cases, testing philosophy - `verification_steps` - **What commands to run**: specific test commands and manual verification steps **Best Practice:** Use both fields together: - `testing_strategy` provides the comprehensive testing approach and edge cases to consider - `verification_steps` provides the concrete commands to run to verify completion **Example showing the difference:** ```json { "testing_strategy": { "unit_tests": ["Test priority filter logic with priority=0", "Test with priority=4", "Test with null priority"], "integration_tests": ["Test filter UI in LiveView with live rendering", "Test combined with status filter"], "manual_tests": ["Verify filter state persists after page refresh"], "edge_cases": [ "Tasks with null priority", "Filter combined with status filter", "Filter state persists after page refresh" ], "coverage_target": "100% for new filter functions" }, "verification_steps": [ { "step_type": "command", "step_text": "mix test test/kanban/boards_test.exs", "expected_result": "All tests pass", "position": 0 }, { "step_type": "manual", "step_text": "Test filter by each priority level, verify URL updates", "expected_result": "Filtering works and state persists", "position": 1 } ] } ``` In this example: - `testing_strategy` tells the agent to consider null priorities, combined filters, and persistence - `verification_steps` tells the agent exactly which test commands to run #### `technical_details` - Free-Form Technical Notes **Why useful:** Gives an agent a place to record any additional technical information that does not fit the other structured fields. The `technical_details` field is an **optional free-form JSON object**. Unlike `testing_strategy`, it has **no fixed keys** — record whatever technical information is useful (design decisions, migration notes, rollback plans, configuration, etc.). Any keys and values are accepted; nested objects and arrays are fine. Omitting it stores an empty object (`{}`). **Format:** ```json "technical_details": { "db_migration": "Adds a technical_details :map column with default {}", "rollback": { "steps": ["Drop the technical_details column"] }, "notes": "Mirror the integration_points wiring throughout the schema" } ``` **Always structure these other fields:** - `verification_steps` - What to test (array of objects with step_type, step_text, expected_result) - `testing_strategy` - Overall testing approach (JSON object - see detailed format above) - `technical_details` - Free-form technical notes (JSON object, no fixed keys) - `pitfalls` - What NOT to do (array of strings) - `patterns_to_follow` - Code patterns to replicate (newline-separated string) - `acceptance_criteria` - Definition of done (newline-separated string) **Optional markdown for:** - Additional context or nuance - Examples that don't fit the structure - Background information - Historical context ## Essential Information for Easy Implementation 1. Clear Acceptance Criteria - What does "done" look like? - Specific behaviors or outcomes expected - Examples of what should/shouldn't happen 2. Context & Why - What problem does this solve? - Who is the user/stakeholder? - What value does this provide? 3. Technical Constraints - Which files/modules are affected? - Any existing patterns to follow? - Performance requirements? - Security considerations? 4. Dependencies & Prerequisites - What must be done first? - What other issues does this relate to? - Are there blockers? 5. Examples & Test Cases - Input/output examples - Edge cases to handle - Error scenarios 6. UI/UX Details (if applicable) - Where does it appear in the UI? - What should the user see/experience? - Any specific styling or component requirements? 7. Scope Boundaries - What is explicitly OUT of scope? - What NOT to change/refactor? - Minimal vs. full implementation? 8. Related Code Locations (Discovery Shortcuts) - Specific file paths to start reading - Module/function names that are central to the task - Database tables/schemas involved - Routes or URLs affected - This saves exploration time - jump straight to the right files 9. Verification Commands - Exact commands to run to verify the task works - Expected output from those commands - How to know if tests pass vs. fail - Manual testing steps 10. Data Shape Examples - Actual data structures (maps, structs, JSON) - Before/after examples for mutations - Sample database records - API request/response examples 11. Common Pitfalls / What NOT to Do - Known issues in this area of code - Previous bugs or mistakes to avoid - "Don't forget to..." reminders - Anti-patterns specific to this codebase 12. Task Size/Complexity Indicator - Small (< 1 hour), Medium (1-2 hours), Large (> 2 hours) - Number of files expected to change (use estimated_files field) - Whether this needs careful planning vs. can start coding immediately 13. Success Indicators Beyond Tests - What should visibly work in the UI - What should appear in logs - Database state changes - Performance benchmarks (if applicable) 14. Integration Points - What other systems/features does this touch? - WebSocket/Phoenix Channel events involved - Background jobs triggered - External API calls - PubSub broadcasts needed 15. Observability Requirements - Should telemetry events be added? - What metrics should be tracked? - Any specific logging needed for debugging/monitoring? - Performance metrics to capture 16. Environment & Configuration - Environment variables or config needed - Feature flags that affect this code path - Database state assumptions (migrations, seed data) - External service dependencies 17. Error Handling Expectations - How to communicate errors to users - What happens on failure (rollback, retry, silent fail) - Logging requirements (level, info to include) - Specific error messages or validation messages 18. Migration Path (for changes) - Is this a breaking change? - Do existing records need data migration? - Backwards compatibility requirements? - Deployment order (migration before/after deploy) ### Task Template (Copy-Paste Ready) When creating tasks via the API, use this JSON structure: ```json { "task": { "title": "[Verb] [What] [Where/Context]", "type": "work", "complexity": "small", "estimated_files": "2-3", "why": "[Problem being solved / Value provided]", "what": "[Specific feature/change]", "where_context": "[UI location / code area]", "description": "[Optional detailed description]" } } ``` **⚠️ CRITICAL: Valid Field Values** - **`type`**: MUST be one of: `"work"`, `"defect"`, or `"goal"` (strings, not atoms) - `"work"` - New features, enhancements, improvements - `"defect"` - Bug fixes, error corrections - `"goal"` - Container for multiple related tasks (25+ hours) - ❌ Invalid: `"task"`, `"bug"`, `"feature"`, `null`, or any other value - **`complexity`**: `"small"`, `"medium"`, or `"large"` - **`priority`**: `"low"`, `"medium"`, `"high"`, or `"critical"` **⚠️ CRITICAL: verification_steps Format** The `verification_steps` field MUST be an **array of objects** (not an empty array, not an array of strings): ```json "verification_steps": [ { "step_type": "command", "step_text": "mix test test/kanban/accounts_test.exs", "expected_result": "All tests pass", "position": 0 }, { "step_type": "manual", "step_text": "Navigate to /login and verify password validation", "expected_result": "Invalid passwords show error message", "position": 1 } ] ``` **Each object MUST have:** - `step_type` (required): Either `"command"` or `"manual"` - `step_text` (required): The command to run or manual instruction - `position` (required): Integer >= 0 for ordering - `expected_result` (optional): What should happen when successful **❌ Invalid formats:** ```json "verification_steps": [] // Empty array - system will accept but provides no value "verification_steps": ["mix test"] // Array of strings - will cause crash "verification_steps": "mix test" // String - will cause crash ``` **✅ Valid formats:** ```json "verification_steps": [{"step_type": "command", "step_text": "mix test", "position": 0}] // Array of objects "verification_steps": [] // Empty array is technically valid but not useful ``` For documentation/planning purposes, you can also use this markdown template: ```markdown ## [Verb] [What] [Where/Context] **Complexity:** [small/medium/large] | **Est. Files:** [1-2 / 3-5 / 5+] ### Why, What, Where **WHY:** [Problem being solved / Value provided] **WHAT:** [Specific feature/change] **WHERE:** [UI location / code area] ### Acceptance Criteria - [ ] [Specific behavior 1] - [ ] [Specific behavior 2] - [ ] [Specific behavior 3] ### Key Files to Read First - `path/to/main/file.ex` - [Brief description of relevance] - `path/to/context.ex` - [Brief description] ### Technical Notes **Patterns to Follow:** - [Existing pattern/convention to use] **Database/Schema:** - Tables: [table_names] - Migrations needed: [yes/no - description if yes] **Integration Points:** - [ ] PubSub broadcasts: [channel/event names] - [ ] Phoenix Channels: [socket/topic names] - [ ] External APIs: [which services] ### Verification **Commands to Run:** ```bash mix test path/to/test.exs mix precommit ``` **Manual Testing:** 1. [Step-by-step testing instructions] 2. [Expected outcome] **Success Looks Like:** - [UI shows X] - [Database has Y] - [Logs contain Z] ### Data Examples **Input:** ```elixir %{field: value} ``` **Output:** ```elixir %Model{field: value, ...} ``` ### Observability - [ ] Telemetry event: `[:app, :domain, :action]` - [ ] Metrics: [counter/sum/summary of what] - [ ] Logging: [info/warn/error for what scenarios] ### Error Handling - User sees: [error message/UI state] - On failure: [rollback/retry/silent fail] - Validation: [what to validate and messages] ### Common Pitfalls - [ ] Don't forget to [common mistake] - [ ] Remember to [important step] - [ ] Avoid [anti-pattern] ### Dependencies **Requires:** [task-id or "none"] **Blocks:** [task-id or "none"] ### Out of Scope - [What NOT to do/change] - [Future enhancements to skip] ``` ### Example Task (Filled Out) ```json { "task": { "title": "Add priority filter to board list view", "type": "work", "complexity": "medium", "estimated_files": "2-3", "why": "Users need to focus on high-priority tasks without manually scanning", "what": "Add a dropdown filter for task priority in board header", "where_context": "Board list view header, next to existing status filter", "description": "Add dropdown filter for task priority (0-4) in board header next to status filter" } } ``` Or in markdown format: ```markdown ## Add priority filter to board list view **Complexity:** medium | **Est. Files:** 2-3 ### Why, What, Where **WHY:** Users need to focus on high-priority tasks without manually scanning **WHAT:** Add a dropdown filter for task priority (0-4) in board header **WHERE:** Board list view header, next to existing status filter ### Acceptance Criteria - [ ] Dropdown shows priorities 0-4 with labels (Critical, High, Medium, Low, None) - [ ] Filtering updates task list in real-time via LiveView - [ ] Filter state persists in URL params (?priority=3) - [ ] Shows "All Priorities" option to clear filter - [ ] Works with existing status filter (combines filters) ### Key Files to Read First - `lib/kanban_web/live/board_live.ex` - Main LiveView handling board display - `lib/kanban/boards.ex` - Context with get_tasks/2 function to update - `lib/kanban/schemas/task.ex` - Check if priority field exists ### Technical Notes **Patterns to Follow:** - Use same filter pattern as existing status filter in board_live.ex - Follow LiveView handle_event pattern for filter changes **Database/Schema:** - Tables: tasks - Migrations needed: Yes - add priority:integer field if not exists **Integration Points:** - [ ] PubSub broadcasts: Not needed (read-only filter) - [ ] Phoenix Channels: None - [ ] External APIs: None ### Verification **Commands to Run:** ```bash mix test test/kanban/boards_test.exs mix test test/kanban_web/live/board_live_test.exs mix precommit ``` **Manual Testing:** 1. Navigate to /boards 2. Click priority filter dropdown 3. Select "High (3)" priority 4. Verify only priority 3 tasks show 5. Check URL contains ?priority=3 6. Refresh page - filter should persist 7. Select "All Priorities" - should show all tasks **Success Looks Like:** - Dropdown appears in board header - Task list updates without page reload - URL updates with query param - Page refresh maintains filter state ### Data Examples **Query Params:** ```elixir %{"priority" => "3", "status" => "in_progress"} ``` **Filtered Query:** ```elixir # In Boards.get_tasks/2 from t in Task, where: t.priority == ^priority, where: t.status == ^status ``` ### Observability - [ ] Telemetry event: Not needed for this feature - [ ] Metrics: Could add `[:kanban, :filter, :used]` counter (optional) - [ ] Logging: No logging needed (simple read operation) ### Error Handling - User sees: No special errors (graceful degradation if invalid priority) - On failure: Show all tasks (don't break the page) - Validation: Ensure priority is 0-4 or nil ### Common Pitfalls - [ ] Don't forget to broadcast filter changes via PubSub (actually not needed - read-only) - [ ] Remember to handle nil priority (tasks without priority set) - [ ] Avoid N+1 queries - filters happen at DB level ### Dependencies **Requires:** None (can add migration in this task) **Blocks:** None ### Out of Scope - Don't add sorting by priority (separate task) - Don't modify the task card layout or styling - Don't add bulk priority assignment ``` ## Completion Validation Requirements (G65) Every Stride task completes with a structured payload the server validates. Three of those fields — `explorer_result`, `reviewer_result`, and `workflow_steps` — are populated from the agent's actual exploration, review, and workflow behavior during the task. **As a task author, the quality of your task metadata directly determines whether the agent can produce valid payloads.** Thin tasks produce thin skip-form summaries that fail the 40-character minimum. Rich tasks produce substantive dispatched payloads that clear validation cleanly. ### What this means for task authors 1. **`key_files` is what the explorer reads.** An agent's `explorer_result.summary` describes what it found in those files. If you list zero or vague `key_files`, the explorer has nothing concrete to summarize, and the agent falls back to a short skip-form summary that may fail validation. Aim for 2-5 specific file paths with a `note` explaining why each one matters. 2. **`acceptance_criteria` drives the reviewer.** When the reviewer subagent runs (Claude Code) or the agent self-reviews (Cursor, Windsurf, Continue, Kimi), it walks each line of `acceptance_criteria` and reports `acceptance_criteria_checked`. Vague criteria like "works correctly" aren't checkable — produce one clear, verifiable statement per line. 3. **`pitfalls` and `patterns_to_follow` give the reviewer substance.** `reviewer_result.summary` references these when reporting what was checked. Leaving them empty turns reviews into "walked the diff, no issues found" which reads thin. 4. **Small tasks with 0-1 `key_files` can legitimately skip exploration and review** per the workflow's decision matrix. In that case the agent submits a skip-form with `reason: "small_task_0_1_key_files"`. Tag your small tasks honestly with `complexity: "small"` to make this path available — don't inflate complexity to force dispatch. 5. **Subagent dispatch isn't available everywhere.** Cursor, Windsurf, Continue.dev, and Kimi Code agents always submit the skip-form with `reason: "no_subagent_support"` or `"self_reported_exploration"`/`"self_reported_review"`. Their summaries come from reading your task's metadata inline. So your task metadata IS the raw material for their validation payload — even more so than on Claude Code where a subagent's parallel exploration covers some gaps. ### Practical checklist for task authors - [ ] **Does `key_files` have at least one concrete, specific file path?** (Or is this genuinely small with 0-1 files, in which case say so?) - [ ] **Does `acceptance_criteria` contain at least 3 checkable lines?** Each should be verifiable by someone reading the diff. - [ ] **Are `pitfalls` named and specific?** (Not "don't break things" — name the specific anti-pattern.) - [ ] **Do `patterns_to_follow` point at a real file the agent can open?** If you answer "no" to any of these on a medium or large task, the resulting `explorer_result` / `reviewer_result` payloads will be thin even before the agent writes a line of code. Rich task = rich payload. ### Full payload specification This guide covers the author's perspective. For the exact payload shapes, skip-reason enum values, 40-character minimum rule, and rollout status: - [PATCH /api/tasks/:id/complete — Completion Validation Format (G65)](api/patch_tasks_id_complete.md#completion-validation-format-g65) — full API contract - [AI Workflow — Completion Validation](AI-WORKFLOW.md#completion-validation) — workflow context - `GET /api/agent/onboarding` → `api_schema.explorer_result_format` / `reviewer_result_format` / `workflow_steps_format` — machine-readable schema ## Internal Mental Model During Task Execution 1. Task Context - Original user request (exact words matter!) - The "why" behind the request - Success criteria / definition of "done" 2. Discovery & Understanding - Files I've read and their purpose - Existing patterns I've found - How the current system works - Dependencies between components 3. Implementation Plan - Step-by-step approach - Which files need changes - Order of operations (what must happen first) - Testing strategy 4. Progress Tracking - What I've completed - What's in progress - What's still pending - Blockers or questions that arise 5. Code Changes Map - Files modified and why - Functions/components added/changed - Migration/database changes - Configuration updates 6. Quality Checklist - Tests written/updated - Error handling added - Edge cases covered - Styling matches existing patterns - Security considerations addressed 7. Verification Plan - How to test the changes - Commands to run (mix test, mix precommit, etc.) - Manual testing steps - What success looks like 8. Open Questions & Assumptions - Things I'm uncertain about - Assumptions I'm making - Questions for the user ### Task Tracking in Stride In this project, tasks are tracked in the Stride kanban system with the following benefits: - Persists across sessions - API accessible for AI agents - Handles dependencies between tasks and goals - Visible to all team members and agents - Hook-based workflow for automation When creating tasks in Stride, include enough detail from this guide so that any agent (or developer) can: - Understand the context immediately - Start implementing without extensive exploration - Know exactly what success looks like - Verify their work is complete Well-written tasks with clear acceptance criteria, code locations, and verification steps make the difference between a 30-minute implementation and a 3-hour exploration session.