feat: mandatory task briefs with session provenance and conversation context#2116
feat: mandatory task briefs with session provenance and conversation context#2116marcusquinn merged 4 commits intomainfrom
Conversation
…context
Every task now requires a brief file (todo/tasks/{task_id}-brief.md) that
captures: session origin, what, why, how, acceptance criteria, and the
conversation context that created the task. This prevents knowledge loss
between sessions.
Changes:
- Add brief-template.md with session provenance fields
- Update /new-task to require brief creation before TODO.md entry
- Update plans.md workflow to enforce briefs and gate auto-dispatch
- Update compose_issue_body to include brief content in GitHub issues
- Extract HTML comments (REBASE notes) into issue Implementation Notes
- Exclude brief files from collapsed Related Files (shown prominently)
- Update AGENTS.md with brief requirement in lifecycle and planning docs
…racts conversation context Fixes: supervisor DB query too loose (LIKE → exact match), Python/awk block extraction captures full indented content, session context block now included in brief template, created_by detection respects exact supervisor match. ShellCheck clean.
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. WalkthroughThis PR introduces a mandatory task brief workflow by establishing required brief files at Changes
Sequence DiagramsequenceDiagram
actor Agent as Agent/User
participant TaskCmd as Task Creation<br/>Command
participant BriefGen as Brief Generator<br/>(task-brief-helper)
participant SessionDB as OpenCode Session<br/>DB
participant TaskFS as Task File<br/>System
participant AutoDispatch as Auto-Dispatch<br/>Gate
Agent->>TaskCmd: Create new task with context
TaskCmd->>TaskFS: Extract task ID & creation commit
TaskCmd->>BriefGen: Trigger brief generation
BriefGen->>SessionDB: Query session by commit timestamp
SessionDB-->>BriefGen: Return matched session context
BriefGen->>SessionDB: Extract conversation history
SessionDB-->>BriefGen: Return conversation blocks
BriefGen->>TaskFS: Read task description from TODO.md
BriefGen->>TaskFS: Generate structured brief<br/>(Origin, What, Why, How, AC, Files)
TaskFS-->>BriefGen: Brief written to<br/>todo/tasks/{task_id}-brief.md
TaskCmd->>TaskFS: Update TODO.md with brief reference
TaskCmd->>AutoDispatch: Evaluate brief against eligibility criteria
AutoDispatch->>TaskFS: Validate: 2+ acceptance criteria,<br/>non-empty How with file refs
alt Brief Meets Criteria
AutoDispatch-->>TaskCmd: Eligible for `#auto-dispatch`
else Brief Incomplete
AutoDispatch-->>TaskCmd: Manual review required
end
TaskCmd-->>Agent: Task created with brief
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary of ChangesHello @marcusquinn, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request addresses a critical issue of lost context for tasks by implementing a mandatory task brief system. It introduces a structured approach to documenting tasks, ensuring that every task is accompanied by a detailed brief outlining its origin, purpose, approach, and acceptance criteria. This change not only enforces better documentation practices but also provides a tool to retroactively generate these briefs from historical conversation data, significantly improving task clarity and maintainability across projects. Highlights
Changelog
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
🔍 Code Quality Report�[0;35m[MONITOR]�[0m Code Review Monitoring Report �[0;34m[INFO]�[0m Latest Quality Status: �[0;34m[INFO]�[0m Recent monitoring activity: 📈 Current Quality Metrics
Generated on: Sat Feb 21 18:02:39 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
There was a problem hiding this comment.
Code Review
The pull request introduces a mandatory task brief requirement, which significantly improves knowledge retention and session provenance within the framework. The updates to the documentation and templates are clear and well-integrated. However, the new generate-brief.sh script violates several repository-specific shell scripting standards (e.g., naming conventions, variable declaration, explicit returns, and error suppression) and contains security risks related to string interpolation in Python and SQL. Addressing these will ensure the script is robust, secure, and consistent with the rest of the codebase.
.agents/scripts/generate-brief.sh
Outdated
| sqlite3 "$OPENCODE_DB" " | ||
| SELECT id FROM project WHERE worktree = '$project_root' | ||
| " 2>/dev/null | head -1 |
There was a problem hiding this comment.
Violation of Repository Style Guide Rule 24. All SQLite usage must include WAL mode and busy_timeout=5000. Also, Rule 25 recommends parameterized queries where possible. Direct interpolation of $project_root into the SQL string is a security risk.
| sqlite3 "$OPENCODE_DB" " | |
| SELECT id FROM project WHERE worktree = '$project_root' | |
| " 2>/dev/null | head -1 | |
| sqlite3 "$OPENCODE_DB" " | |
| PRAGMA journal_mode=WAL; | |
| PRAGMA busy_timeout=5000; | |
| SELECT id FROM project WHERE worktree = ? | |
| " "$project_root" | head -1 |
References
- All SQLite databases use WAL mode + busy_timeout=5000. Use parameterized queries where possible. (link)
- To prevent SQL injection in shell scripts using
sqlite3, create a helper function that uses.param setfor safe parameterized bindings instead of direct string interpolation.
.agents/scripts/generate-brief.sh
Outdated
| python3 -c " | ||
| import sqlite3, json, sys, re | ||
|
|
||
| db = sqlite3.connect('$OPENCODE_DB') | ||
| cursor = db.cursor() | ||
|
|
||
| # Get all user messages from this session | ||
| cursor.execute(''' | ||
| SELECT m.data, m.time_created | ||
| FROM message m | ||
| WHERE m.session_id = ? | ||
| AND json_extract(m.data, '\$.role') = 'user' | ||
| ORDER BY m.time_created | ||
| ''', ('$session_id',)) | ||
|
|
||
| task_id = '$task_id' |
There was a problem hiding this comment.
Security risk: String interpolation of shell variables ($session_id, $task_id) directly into the Python script string can lead to command injection. A malicious task ID could execute arbitrary Python code. Use environment variables and os.environ inside the Python script to safely pass these values.
.agents/scripts/generate-brief.sh
Outdated
| task_block=$(python3 -c " | ||
| import re, sys | ||
| task_id = '$task_id' | ||
| lines = open('$project_root/TODO.md').readlines() |
| @@ -0,0 +1,491 @@ | |||
| #!/usr/bin/env bash | |||
There was a problem hiding this comment.
The script name generate-brief.sh does not follow the repository's naming convention. According to Rule 37, scripts should follow the {domain}-helper.sh pattern. Consider renaming this to task-brief-helper.sh or similar.
References
- Scripts: {domain}-helper.sh (e.g., supervisor-helper.sh, memory-helper.sh) (link)
- The {domain}-helper.sh naming convention applies to domain-specific helper scripts. Configuration scripts should be named to accurately describe their purpose (e.g., ai-cli-config.sh) if ...-helper.sh would be misleading.
| local task_id="$1" | ||
| local project_root="$2" |
There was a problem hiding this comment.
Violation of Repository Style Guide Rule 11. Local variables should be declared and assigned separately to ensure that the exit code of the assignment (especially for command substitutions) is not masked by the local keyword. This pattern should be applied to all functions in this script.
| local task_id="$1" | |
| local project_root="$2" | |
| local task_id | |
| task_id="$1" | |
| local project_root | |
| project_root="$2" |
References
- Use local var="$1" pattern in functions (declare and assign separately for exit code safety) (link)
- When declaring and assigning a local variable in shell scripts, separate the 'local' declaration from the assignment if command substitution is involved, to ensure exit code safety.
- When declaring and assigning local variables in shell scripts, separate the
localdeclaration from the assignment if command substitution is involved, to ensure exit code safety. For consistency, this pattern should be maintained even for simple assignments.
| fi | ||
|
|
||
| echo "$commit" | ||
| } |
There was a problem hiding this comment.
Violation of Repository Style Guide Rule 12. All functions must have explicit return statements. Please add return 0 (or appropriate exit code) to the end of every function.
| } | |
| echo "$commit" | |
| return 0 | |
| } |
References
- All functions must have explicit return statements (link)
- All functions in shell scripts must have explicit
returnstatements to ensure predictable behavior and exit code propagation.
.agents/scripts/generate-brief.sh
Outdated
|
|
||
| # Find the first commit that introduced this task ID in TODO.md | ||
| local commit | ||
| commit=$(git -C "$project_root" log --all --format="%H" -S "- [ ] ${task_id} " -- TODO.md 2>/dev/null | tail -1) |
There was a problem hiding this comment.
Violation of Repository Style Guide Rule 50. Blanket suppression of stderr with 2>/dev/null is discouraged as it masks potential errors and makes debugging difficult. Only use it when redirecting to log files.
| commit=$(git -C "$project_root" log --all --format="%H" -S "- [ ] ${task_id} " -- TODO.md 2>/dev/null | tail -1) | |
| commit=$(git -C "$project_root" log --all --format="%H" -S "- [ ] ${task_id} " -- TODO.md | tail -1) |
References
- 2>/dev/null is acceptable ONLY when redirecting to log files, not blanket suppression (link)
- Avoid using '2>/dev/null' for blanket suppression of command errors in shell scripts to ensure that authentication, syntax, or system issues remain visible for debugging.
…ction, add WAL mode - Rename generate-brief.sh → task-brief-helper.sh (naming convention) - Replace all shell variable interpolation in SQL/Python with env vars and parameterized queries (prevents injection) - Add PRAGMA journal_mode=WAL and busy_timeout=5000 to all SQLite calls - Add validate_task_id() — rejects non-tNNN format before any DB access - Separate local variable declarations from assignments - Add explicit return statements to all functions - Replace blanket 2>/dev/null with targeted error filtering - ShellCheck clean, injection test verified
🔍 Code Quality Report�[0;35m[MONITOR]�[0m Code Review Monitoring Report �[0;34m[INFO]�[0m Latest Quality Status: �[0;34m[INFO]�[0m Recent monitoring activity: 📈 Current Quality Metrics
Generated on: Sat Feb 21 20:52:13 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (1)
.agents/scripts/task-brief-helper.sh (1)
485-534: Heredoc with inline conditionals — functional but dense.The
$(if ...; then echo ...; fi)pattern within the heredoc (lines 496, 508-513, 514-517, 518-523) works correctly but makes the template hard to read and modify. This is a pragmatic trade-off for a backfill script that generates markdown — acceptable given the script's utility purpose. No functional issue.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.agents/scripts/task-brief-helper.sh around lines 485 - 534, The heredoc is cluttered by multiple inline command substitutions; refactor by computing each optional block into clearly named variables (e.g., parent_line, current_todo_section, rebase_section, supervisor_section) before writing the heredoc, then insert those variables directly in the cat >"$output_file" <<BRIEF template (keep existing symbols like task_id, task_title, best_block, context_block, task_block, rebase_note, supervisor_info, sup_id intact) so the conditional logic is separated from the template and the template becomes much easier to read and maintain.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.agents/scripts/issue-sync-lib.sh:
- Around line 890-895: The current extraction for HTML comments uses grep -oE
'<!--[^>]+-->' which fails when the comment contains '>' characters; update the
command that builds html_comments (the line assigning html_comments from
first_line) to use a non-greedy PCRE pattern, e.g. grep -oP '<!--.*?-->' piped
to the same sed trims, so change the grep invocation in the html_comments
assignment to use grep -oP with '<!--.*?-->' (note this requires GNU grep on
non-Linux systems); keep the rest of the logic that appends to body and the sed
trimming unchanged.
In @.agents/scripts/task-brief-helper.sh:
- Around line 1-12: Update the script header in task-brief-helper.sh so the
Dependencies line accurately reflects actual usage: remove "sqlite3" (the CLI is
not invoked) and change "python3 (for JSON parsing)" to something like "python3
(used for SQLite DB access and JSON parsing)" or equivalent; ensure the top
comment block and any usage notes that mention sqlite3 or limit python3 to just
JSON parsing are corrected to state that python3 handles all database queries
and task extraction.
- Around line 265-271: The current shell pipeline redirects Python stderr into
stdout (2>&1) and then strips tracebacks with grep -v, which is fragile; modify
the invocation so Python's stderr is not mixed with stdout (e.g., redirect
stderr to /dev/null or capture it separately) and remove the grep -v traceback
filter; specifically, locate the block that prints context_parts (the Python-run
output that ends with "print('\\n'.join(context_parts))" /
"print('NO_CONTEXT_FOUND')") and change the surrounding shell redirection to
send stderr to /dev/null (or into a separate variable) instead of using 2>&1 and
the grep-based stripping, ensuring only the intended stdout becomes the context
output.
- Around line 88-103: The Python subprocess in find_project_id (and likewise
find_session_by_timestamp, find_parent_session, find_supervisor_context)
currently redirects stderr into stdout via `2>&1 | head -1`, which lets Python
errors become the captured project/session id; change the redirection so stderr
is discarded or logged separately and only stdout is piped to head, e.g., run
the python3 command with stderr redirected to /dev/null and preserve a
successful pipeline by appending `|| true` to satisfy `set -e`; update each
invocation to use `2>/dev/null | head -1 || true` (or equivalent separation of
stdout/stderr) so only the actual query result is captured and errors don’t
become IDs.
---
Nitpick comments:
In @.agents/scripts/task-brief-helper.sh:
- Around line 485-534: The heredoc is cluttered by multiple inline command
substitutions; refactor by computing each optional block into clearly named
variables (e.g., parent_line, current_todo_section, rebase_section,
supervisor_section) before writing the heredoc, then insert those variables
directly in the cat >"$output_file" <<BRIEF template (keep existing symbols like
task_id, task_title, best_block, context_block, task_block, rebase_note,
supervisor_info, sup_id intact) so the conditional logic is separated from the
template and the template becomes much easier to read and maintain.
…L comment regex - Replace all 2>&1 with 2>/dev/null in Python/git subprocess captures to prevent error messages leaking into variable values - Remove fragile traceback grep-stripping in extract_session_context - Fix HTML comment regex in issue-sync-lib.sh to handle > inside comments - Update dependency header (sqlite3 CLI not used, python3 does all DB access) - ShellCheck clean
🔍 Code Quality Report�[0;35m[MONITOR]�[0m Code Review Monitoring Report �[0;34m[INFO]�[0m Latest Quality Status: �[0;34m[INFO]�[0m Recent monitoring activity: 📈 Current Quality Metrics
Generated on: Sat Feb 21 21:00:32 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
|



Summary
todo/tasks/{task_id}-brief.mdcapturing session origin, what, why, how, acceptance criteria, and conversation contextgenerate-brief.shscript that traces tasks back to their source OpenCode sessions and supervisor DB, extracting the original conversation context that created each tasknew-task.md,plans.md,AGENTS.md,issue-sync-lib.sh, andbrief-template.mdto enforce briefs going forwardProblem
Every open task across both repos (58 a managed private repo, 13 aidevops = 71 total) had NO brief file. Tasks were bare one-liners in TODO.md with no context about what, why, how, or acceptance criteria. The AI supervisor created subtasks as one-liners that lost all parent context. No session provenance linked tasks back to the conversations that created them.
What Changed
Framework enforcement (prevents future knowledge loss)
new-task.md— rewritten to require brief creation before TODO.md entryplans.md— added "MANDATORY: Task Brief Requirement" sectionAGENTS.md— development lifecycle now includes brief requirementbrief-template.md— new template with Origin, What, Why, How, Acceptance Criteria sectionsissue-sync-lib.sh—compose_issue_bodynow includes brief content in GitHub issuesBackfill tool
generate-brief.sh— traces task → git commit → OpenCode session → conversation context~/.local/share/opencode/opencode.db) for session messages with diffsBackfill results (committed separately)
Key examples
t004-brief.md: 392 lines — full 9-layer multi-org architecture spec recovered from original sessiont005-brief.md: 203 lines — complete AI chat sidebar UX spec with @mentions, /commands, tool calls, etc.t005.4-brief.md: Links to parent t005, includes REBASE notes and supervisor contextSummary by CodeRabbit
Release Notes
New Features
Chores