Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions .agents/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,15 @@ Subagent write restrictions: on `main`/`master`, subagents may ONLY write to `RE

## Development Lifecycle

1. Create TODO entry before starting work
2. Ask user: implement now or queue for runner?
3. Full-loop: branch/worktree → implement → test → verify → commit/PR
4. Queue: add to TODO.md for supervisor dispatch
5. Never skip testing. Never declare "done" without verification.
1. Create TODO entry **with brief** before starting work
2. Brief file at `todo/tasks/{task_id}-brief.md` is MANDATORY (see `templates/brief-template.md`)
3. Brief must include: session origin, what, why, how, acceptance criteria, context
4. Ask user: implement now or queue for runner?
5. Full-loop: branch/worktree → implement → test → verify → commit/PR
6. Queue: add to TODO.md for supervisor dispatch
7. Never skip testing. Never declare "done" without verification.

**Task brief rule**: A task without a brief is undevelopable. The brief captures conversation context that would otherwise be lost between sessions. See `workflows/plans.md` and `scripts/commands/new-task.md`.

---

Expand All @@ -56,7 +60,9 @@ Format: `- [ ] t001 Description @owner #tag ~4h started:ISO blocked-by:t002`

Task IDs: `/new-task` or `claim-task-id.sh`. NEVER grep TODO.md for next ID.

Auto-dispatch: `#auto-dispatch` tag. Add `assignee:` before pushing if working interactively.
**Task briefs are MANDATORY.** Every task must have `todo/tasks/{task_id}-brief.md` capturing: session origin, what, why, how, acceptance criteria, and conversation context. Use `templates/brief-template.md`. A task without a brief loses the knowledge that created it.

Auto-dispatch: `#auto-dispatch` tag — only if brief has 2+ acceptance criteria, file references in How section, and clear deliverable in What section. Add `assignee:` before pushing if working interactively.

Completion: NEVER mark `[x]` without merged PR (`pr:#NNN`) or `verified:YYYY-MM-DD`. Use `task-complete-helper.sh`.

Expand Down
122 changes: 104 additions & 18 deletions .agents/scripts/commands/new-task.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,25 +57,82 @@ ID: {task_id}
Ref: ref:{task_ref}

Options:
1. Add to TODO.md with defaults (~1h #auto-dispatch)
1. Add to TODO.md with brief (recommended)
2. Customize estimate, tags, and dependencies
3. Just show the ID (don't add to TODO.md)
```

### Step 5: Add to TODO.md (if requested)
### Step 5: Create Task Brief (MANDATORY)

**Every task MUST have a brief file** at `todo/tasks/{task_id}-brief.md`. This is non-negotiable. A task without a brief is undevelopable.

Use `templates/brief-template.md` as the base. Populate from conversation context:

```markdown
# {task_id}: {Title}

## Origin
- **Created:** {ISO date}
- **Session:** {app}:{session-id} (detect from runtime — e.g., opencode:session-xyz, claude-code:abc123)
- **Created by:** {author} (human | ai-supervisor | ai-interactive)
- **Parent task:** {parent_id} (if subtask — include link to parent brief)
- **Conversation context:** {1-2 sentence summary of what was discussed}

## What
{Clear deliverable description — not "implement X" but what it must produce}

## Why
{Problem, user need, business value, or dependency requiring this}

## How (Approach)
{Technical approach, key files, patterns to follow}
{Reference existing code: `path/to/file.ts:45`}

## Acceptance Criteria
- [ ] {Specific, testable criterion}
- [ ] Tests pass
- [ ] Lint clean

## Context & Decisions
{Key decisions, constraints, things ruled out}

## Relevant Files
- `path/to/file.ts:45` — {why relevant}
```

**For subtasks**: The brief MUST reference the parent task's brief and inherit its context. Don't repeat everything — link to the parent and add what's specific to this subtask.

**Session ID capture**: Detect the runtime environment:

- OpenCode: `$OPENCODE_SESSION_ID` or parse from `~/.local/share/opencode/sessions/`
- Claude Code: `$CLAUDE_SESSION_ID` or the conversation ID from the CLI
- If unavailable: use `{app}:unknown-{ISO-date}` and note "session ID not captured"

### Step 6: Add to TODO.md

Format the TODO.md entry using the allocated ID:

```markdown
- [ ] {task_id} {title} #{tag} #auto-dispatch ~{estimate} ref:{task_ref} logged:{YYYY-MM-DD}
- [ ] {task_id} {title} #{tag} ~{estimate} ref:{task_ref} logged:{YYYY-MM-DD}
```

Then commit and push via `planning-commit-helper.sh`:
**Auto-dispatch eligibility**: Only add `#auto-dispatch` if the brief has:
- At least 2 acceptance criteria beyond "tests pass" and "lint clean"
- A non-empty "How (Approach)" section with file references
- A non-empty "What" section with clear deliverable

If the brief is too thin for auto-dispatch, omit the tag and note why.

### Step 7: Commit and Push

Commit both the brief and TODO.md change:

```bash
~/.aidevops/agents/scripts/planning-commit-helper.sh "plan: add {task_id} {short_title}"
```

The brief file (`todo/tasks/{task_id}-brief.md`) is a planning file and goes directly to main alongside TODO.md.

## Offline Handling

If `TASK_OFFLINE=true`, warn the user:
Expand All @@ -92,24 +149,53 @@ If `TASK_OFFLINE=true`, warn the user:
User: /new-task Add CSV export button
AI: Allocated: t325 (ref:GH#1260)
Task: "Add CSV export button"
1. Add to TODO.md with defaults 2. Customize 3. Just show ID

Creating brief from conversation context...

Brief: todo/tasks/t325-brief.md
- What: Add a CSV export button to the data table component that exports
the current filtered view as a downloadable CSV file
- Why: Users need to export filtered data for offline analysis and reporting
- How: Add ExportButton to DataTable toolbar, use papaparse for CSV generation
- Acceptance: Button visible in toolbar, exports current filter, handles 10k+ rows

1. Confirm and add to TODO.md
2. Edit brief first
3. Cancel
User: 1
AI: Added to TODO.md:
- [ ] t325 Add CSV export button #auto-dispatch ~1h ref:GH#1260 logged:2026-02-12
AI: Added:
- todo/tasks/t325-brief.md (brief)
- TODO.md: - [ ] t325 Add CSV export button #feature #auto-dispatch ~1h ref:GH#1260 logged:2026-02-12
```

```text
User: /new-task
AI: What's the task title?
User: Fix login timeout on mobile
User: /new-task Fix login timeout on mobile
AI: Allocated: t326 (ref:GH#1261)
Task: "Fix login timeout on mobile"
1. Add to TODO.md with defaults 2. Customize 3. Just show ID
User: 2
AI: Customize:
- Estimate: ~2h
- Tags: #bugfix
- Dependencies: blocked-by:t300
- Auto-dispatch: yes
Confirm? [y/n]

I need more context for the brief:
1. What's the current timeout behaviour? (error message, redirect, etc.)
2. Which auth provider? (Better Auth, NextAuth, custom)
3. Mobile-specific or all platforms?

User: Better Auth, only on iOS Safari, users get logged out after 5 minutes
AI: Brief: todo/tasks/t326-brief.md
- What: Fix premature session expiry on iOS Safari — sessions should last 24h
- Why: iOS Safari users lose work after 5 min due to aggressive cookie handling
- How: Check Better Auth session config, likely needs SameSite=None + Secure
for iOS Safari cookie persistence. File: packages/auth/src/config.ts
- Acceptance: iOS Safari session persists 24h, no regression on other browsers

1. Confirm 2. Edit 3. Cancel
```

## CRITICAL: Supervisor Subtask Creation

When the AI supervisor creates subtasks (e.g., decomposing t005 into t005.1-t005.5), it MUST:

1. Create a brief for EACH subtask at `todo/tasks/{subtask_id}-brief.md`
2. Reference the parent task's brief: `**Parent task:** {parent_id} — see [todo/tasks/{parent_id}-brief.md]`
3. Inherit context from the parent but add subtask-specific details
4. Include the session ID of the supervisor session that created the subtask

A subtask without a brief is a knowledge loss. The parent task's rich context (from the original conversation) must flow down to every subtask.
28 changes: 26 additions & 2 deletions .agents/scripts/issue-sync-lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -549,9 +549,9 @@ find_related_files() {
fi
fi

# Deduplicate
# Deduplicate and exclude brief files (handled separately by compose_issue_body)
if [[ -n "$all_files" ]]; then
echo "$all_files" | sort -u
echo "$all_files" | sort -u | grep -v -- '-brief\.md$'
fi
return 0
}
Expand Down Expand Up @@ -872,6 +872,30 @@ compose_issue_body() {
done <<<"$related_files"
fi

# Task brief file (todo/tasks/{task_id}-brief.md)
local brief_file="$project_root/todo/tasks/${task_id}-brief.md"
if [[ -f "$brief_file" ]]; then
local brief_content
# Strip YAML frontmatter (--- ... ---) if present
brief_content=$(awk '
BEGIN { in_front=0; front_done=0 }
/^---$/ && !front_done { in_front=!in_front; if(!in_front) front_done=1; next }
!in_front { print }
' "$brief_file")
if [[ -n "$brief_content" && ${#brief_content} -gt 10 ]]; then
body="$body"$'\n\n'"## Task Brief"$'\n\n'"$brief_content"
fi
fi

# Extract HTML comments (e.g., REBASE notes) from the task line
local html_comments
# Match HTML comments — use sed to extract content between <!-- and -->
# Handles comments containing > characters (e.g., "use a -> b pattern")
html_comments=$(echo "$first_line" | sed -n 's/.*\(<!--.*-->\).*/\1/p' | sed 's/<!--//;s/-->//' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
if [[ -n "$html_comments" ]]; then
body="$body"$'\n\n'"## Implementation Notes"$'\n\n'"$html_comments"
fi

# Footer
body="$body"$'\n\n'"---"$'\n'"*Synced from TODO.md by issue-sync-helper.sh*"

Expand Down
Loading