Skip to content

Comments

t318.2: Verify supervisor worker PRs include task ID#1283

Merged
marcusquinn merged 1 commit intomainfrom
feature/t318.2
Feb 12, 2026
Merged

t318.2: Verify supervisor worker PRs include task ID#1283
marcusquinn merged 1 commit intomainfrom
feature/t318.2

Conversation

@marcusquinn
Copy link
Owner

@marcusquinn marcusquinn commented Feb 12, 2026

Summary

Audit and fix PR title generation to ensure all worker PRs include task IDs for audit traceability.

Changes

  • Fix run_pr_create_phase() PR title format: Changed from feat: description (tNNN) to tNNN: description — matches the MANDATORY PR title format documented in AGENTS.md and git-workflow.md
  • Add validate_pr_task_id() function: Pre-creation validation that warns when a PR title lacks a task ID pattern (tNNN)
  • Add missing-task-ID warning: When branch name has no task ID, the function now warns explicitly instead of silently creating a PR without traceability
  • Reinforce in worker prompt: Added "3b. PR title MUST contain task ID" to the Worker Efficiency Protocol in supervisor dispatch prompt

Audit Results

PR Creation Path Task ID in Title? Status
run_pr_create_phase() (full-loop) Was feat: desc (tNNN)Fixed to tNNN: desc Fixed
auto_create_pr_for_task() (supervisor) Already ${task_id}: ${task_desc} OK
Worker prompt gh pr create instruction Already <task-id>: <description> OK
validate_pr_belongs_to_task() Already validates task ID in title/branch OK

Ref #1236

Summary by CodeRabbit

  • New Features

    • Enhanced PR title validation to ensure consistency and traceability.
    • Improved state tracking with extended metadata including timestamps and iteration counts.
    • Better PR metadata assembly with richer information for auditing.
  • Documentation

    • Added guidance on mandatory task-ID prefixes in PR titles.
  • Chores

    • Refined automated workflow handling for improved reliability and robustness.

- Fix run_pr_create_phase() PR title format: use "tNNN: description" instead
  of "feat: description (tNNN)" — matches MANDATORY PR title format
- Add validate_pr_task_id() function to warn when PR title lacks task ID
- Add warning when branch name has no task ID pattern (no-task-ID fallback)
- Add "3b. PR title MUST contain task ID" to worker efficiency prompt in
  supervisor dispatch — reinforces existing instruction at step 2
- auto_create_pr_for_task() already uses correct format (no change needed)
- validate_pr_belongs_to_task() already validates task ID (no change needed)
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 12, 2026

Walkthrough

The PR enhances PR management automation by introducing task-ID validation in PR titles through a new validate_pr_task_id helper, improving state tracking with extended YAML frontmatter including timestamps and metadata, refining headless mode guards, and restructuring PR creation flows to ensure consistent task ID enforcement across deployment pipelines.

Changes

Cohort / File(s) Summary
Core PR Validation & State Management
.agents/scripts/full-loop-helper.sh
Added validate_pr_task_id(pr_title, branch) function for PR title enforcement; expanded save_state and load_state to handle extended frontmatter (started_at, updated_at, pr_number, max_iterations, skip flags, headless flag); reworked headless guard logic in pre-commit hook creation; refactored run_task_phase with explicit v2/v1 capability detection; updated PR creation flow to incorporate task-ID validation and derive titles from task data; enhanced phase/status display for richer state visualization.
Documentation & Enforcement Guidance
.agents/scripts/supervisor-helper.sh
Added declarative documentation blocks reinforcing mandatory task-ID prefix requirement in PR titles (format: <task-id>: <description>); clarified that CI pipeline and supervisor validate task-ID presence.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

Possibly related PRs

Poem

🎯 Task IDs guard the PR gate with pride,
State frontmatter tracks each step and tide,
Headless modes check twice before they slip,
Zero debt maintained on every trip! 🚀

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.93% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: adding task ID validation to PR creation in the supervisor worker script.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/t318.2

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

🔍 Code Quality Report

�[0;35m[MONITOR]�[0m Code Review Monitoring Report

�[0;34m[INFO]�[0m Latest Quality Status:
SonarCloud: 0 bugs, 0 vulnerabilities, 16 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Thu Feb 12 17:30:30 UTC 2026: Code review monitoring started
Thu Feb 12 17:30:30 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 16

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 16
  • VULNERABILITIES: 0

Generated on: Thu Feb 12 17:30:33 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

@sonarqubecloud
Copy link

@marcusquinn marcusquinn merged commit 145f20e into main Feb 12, 2026
10 of 11 checks passed
@marcusquinn marcusquinn deleted the feature/t318.2 branch February 12, 2026 17:32
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @.agents/scripts/full-loop-helper.sh:
- Around line 554-569: The pr_url variable is being assigned with stderr merged
into stdout via "gh pr create ... 2>&1", which can pollute pr_url with warnings
and break the PR number extraction that uses grep on pr_url; change the gh pr
create invocation so pr_url captures only stdout (no 2>&1), and redirect stderr
separately (e.g., to a log file or a separate variable) or discard it, then keep
the fallback logic that calls gh pr view into pr_url and the later grep -oE
'[0-9]+$' on pr_url unchanged; update any error logging to use the separate
stderr capture if you need to preserve warnings for debugging.
🧹 Nitpick comments (6)
.agents/scripts/full-loop-helper.sh (6)

174-191: Clean validation function — minor robustness nit with echo.

If pr_title ever starts with a dash (e.g., -fix: something), echo may interpret it as a flag. printf '%s\n' is the standard portable-safe alternative.

♻️ Suggested hardening
-	if echo "$pr_title" | grep -qE '\bt[0-9]+(\.[0-9]+)*\b'; then
+	if printf '%s\n' "$pr_title" | grep -qE '\bt[0-9]+(\.[0-9]+)*\b'; then

435-435: Redundant stderr redirection.

&>/dev/null already redirects both stdout and stderr to /dev/null. The trailing 2>&1 is a no-op.

♻️ Minor cleanup
-		if gh auth status &>/dev/null 2>&1; then
+		if gh auth status &>/dev/null; then

158-169: Guard removal awk is coupled to the exact indentation of the heredoc.

The ^fi$ anchor only works because the inner fi is indented with spaces. If the guard format ever changes (e.g., tabs, or a refactor flattens the nesting), this removal logic silently leaves orphaned guard fragments in the hook file.

Consider using a paired end-marker comment (e.g., # t173-headless-todo-guard-end) for unambiguous block removal with sed:

♻️ Proposed marker-based approach

Add # t173-headless-todo-guard-end after the closing fi in both heredocs (install), then simplify removal:

-	awk '/# t173-headless-todo-guard/{skip=1} /^fi$/ && skip{skip=0; next} !skip' "$hook_file" >"$tmp_file"
+	sed '/# t173-headless-todo-guard/,/# t173-headless-todo-guard-end/d' "$hook_file" >"$tmp_file"

This decouples removal logic from internal indentation details.


246-262: load_state silently leaves globals empty when fields are missing from the state file.

If a state file is written by an older version (or gets corrupted), grep returns empty and variables like CURRENT_PHASE become empty strings. The cmd_resume case statement would then fall into *) and error — which is acceptable. But STARTED_AT, SAVED_PROMPT, etc. being silently empty could cause subtle bugs in save_state calls that propagate empty values forward (e.g., line 574: save_state "$PHASE_PR_REVIEW" "$SAVED_PROMPT" "$pr_number" "$STARTED_AT").

Consider adding a guard after parsing the required field:

🛡️ Proposed guard for required fields
 	CURRENT_PHASE=$(grep '^phase:' "$STATE_FILE" | cut -d: -f2 | tr -d ' "')
+	if [[ -z "$CURRENT_PHASE" ]]; then
+		print_error "Corrupt state file: missing 'phase' field"
+		return 1
+	fi

516-519: SQL value derived from regex-constrained input — safe, but prefer parameterized queries as a habit.

$task_id_match is safe here because grep -oE 't[0-9]+(\.[0-9]+)*' restricts it to t, digits, and dots. However, embedding shell variables directly into SQL strings is a code smell that can become a real vulnerability if the input source changes.

If the supervisor DB helper supports parameterized queries or a safe quoting function, prefer that. Otherwise, this is acceptable as-is given the input constraint.


88-90: Predicate functions lack explicit return statements.

is_headless, is_loop_active, and is_on_feature_branch rely on the implicit exit code of their last command. Per the project's coding guidelines, shell functions should include explicit returns. A simple return $? suffix or an if/then/return pattern would satisfy this.

As per coding guidelines, "Include explicit returns in shell scripts".

♻️ Example for is_headless
 is_headless() {
-	[[ "$HEADLESS" == "true" ]]
+	if [[ "$HEADLESS" == "true" ]]; then
+		return 0
+	fi
+	return 1
 }

Also applies to: 272-274, 306-310

Comment on lines +554 to +569
# Create PR with proper title and body
print_info "Creating pull request..."
local pr_url
pr_url=$(gh pr create --title "$pr_title" --body "$pr_body" 2>&1) || {
# PR might already exist
pr_url=$(gh pr view --json url --jq '.url' 2>/dev/null || echo "")
if [[ -z "$pr_url" ]]; then
print_error "Failed to create PR"
return 1
fi
print_info "PR already exists: $pr_url"
}

# Extract PR number
local pr_number
pr_number=$(echo "$pr_url" | grep -oE '[0-9]+$' || gh pr view --json number --jq '.number')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

2>&1 in gh pr create captures stderr warnings into pr_url, which may corrupt the URL.

If gh pr create emits any stderr warnings (e.g., deprecation notices), they get mixed into pr_url. The subsequent grep -oE '[0-9]+$' extraction on line 569 would then potentially match digits from warning text rather than the PR number.

Redirect stderr to the log or discard it separately so pr_url contains only the URL.

🐛 Proposed fix
-	pr_url=$(gh pr create --title "$pr_title" --body "$pr_body" 2>&1) || {
+	pr_url=$(gh pr create --title "$pr_title" --body "$pr_body" 2>/dev/null) || {

Or, if you want to preserve stderr for debugging:

-	pr_url=$(gh pr create --title "$pr_title" --body "$pr_body" 2>&1) || {
+	pr_url=$(gh pr create --title "$pr_title" --body "$pr_body") || {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Create PR with proper title and body
print_info "Creating pull request..."
local pr_url
pr_url=$(gh pr create --title "$pr_title" --body "$pr_body" 2>&1) || {
# PR might already exist
pr_url=$(gh pr view --json url --jq '.url' 2>/dev/null || echo "")
if [[ -z "$pr_url" ]]; then
print_error "Failed to create PR"
return 1
fi
print_info "PR already exists: $pr_url"
}
# Extract PR number
local pr_number
pr_number=$(echo "$pr_url" | grep -oE '[0-9]+$' || gh pr view --json number --jq '.number')
# Create PR with proper title and body
print_info "Creating pull request..."
local pr_url
pr_url=$(gh pr create --title "$pr_title" --body "$pr_body" 2>/dev/null) || {
# PR might already exist
pr_url=$(gh pr view --json url --jq '.url' 2>/dev/null || echo "")
if [[ -z "$pr_url" ]]; then
print_error "Failed to create PR"
return 1
fi
print_info "PR already exists: $pr_url"
}
# Extract PR number
local pr_number
pr_number=$(echo "$pr_url" | grep -oE '[0-9]+$' || gh pr view --json number --jq '.number')
🤖 Prompt for AI Agents
In @.agents/scripts/full-loop-helper.sh around lines 554 - 569, The pr_url
variable is being assigned with stderr merged into stdout via "gh pr create ...
2>&1", which can pollute pr_url with warnings and break the PR number extraction
that uses grep on pr_url; change the gh pr create invocation so pr_url captures
only stdout (no 2>&1), and redirect stderr separately (e.g., to a log file or a
separate variable) or discard it, then keep the fallback logic that calls gh pr
view into pr_url and the later grep -oE '[0-9]+$' on pr_url unchanged; update
any error logging to use the separate stderr capture if you need to preserve
warnings for debugging.

@gemini-code-assist
Copy link

Summary of Changes

Hello @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 enhances the traceability and adherence to naming conventions for worker-generated Pull Requests. It standardizes the PR title format to ensure task IDs are always present, introduces a validation step to warn about missing task IDs before PR creation, and updates worker instructions to reinforce this mandatory requirement. The changes aim to improve auditability and consistency across the development workflow.

Highlights

  • PR Title Format Enforcement: The format for Pull Request titles generated by run_pr_create_phase() has been updated from feat: description (tNNN) to the mandatory tNNN: description to align with documented standards for audit traceability.
  • Task ID Validation: A new function, validate_pr_task_id(), was introduced to perform pre-creation validation, issuing a warning if a PR title lacks the required task ID pattern (tNNN).
  • Missing Task ID Warning: Explicit warnings are now provided when a branch name does not contain a task ID, preventing silent creation of untraceable PRs.
  • Worker Prompt Update: The supervisor dispatch prompt for workers now includes a reinforced instruction (3b) emphasizing the mandatory inclusion of task IDs in PR titles.
  • State Management Enhancement: Extended metadata, including iteration counts for task, preflight, and PR phases, has been added to the state tracking mechanism.
Changelog
  • .agents/scripts/full-loop-helper.sh
    • Added validate_pr_task_id function to check for task ID presence in PR titles.
    • Modified run_pr_create_phase to generate PR titles with the tNNN: description format.
    • Implemented a warning in run_pr_create_phase when a branch lacks a task ID for PR title generation.
    • Integrated validate_pr_task_id into the PR creation flow to perform pre-creation checks.
    • Updated state saving logic to include task_iterations, preflight_iterations, and pr_iterations.
  • .agents/scripts/supervisor-helper.sh
    • Updated the worker efficiency protocol to explicitly state that PR titles MUST contain a task ID.
Activity
  • The pull request was created by marcusquinn to address the need for consistent task ID inclusion in worker PR titles.
Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request successfully refactors the PR title generation to prepend the task ID, which is a great improvement for auditability and traceability. The addition of the validate_pr_task_id function provides a helpful, non-blocking warning for PRs that might be missing this crucial information. The changes are well-implemented and align with the repository's conventions. I have one suggestion to improve the robustness of a script used for git hook cleanup.

_save_cleanup_scope
trap '_run_cleanups' RETURN
push_cleanup "rm -f '${tmp_file}'"
awk '/# t173-headless-todo-guard/{skip=1} /^fi$/ && skip{skip=0; next} !skip' "$hook_file" >"$tmp_file"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The awk command used to remove the pre-commit hook guard is a bit brittle. It relies on matching a line containing only fi to determine the end of the block. If the guard's logic were ever extended to include a nested if...fi block where the inner fi is on its own line, this awk script would fail and only partially remove the guard.

A more robust approach would be to use explicit start and end markers. For example, in install_headless_todo_guard:

# START t173-headless-todo-guard
...
# END t173-headless-todo-guard

Then you could safely remove the block with sed '/# START t173-headless-todo-guard/,/# END t173-headless-todo-guard/d', which would be more resilient to future changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant