Skip to content

feat(pr): standardise PR title, body, and task slug for Jira tickets#235

Open
EllaLiu0401 wants to merge 4 commits into
mainfrom
claude/confident-thompson-6889a7
Open

feat(pr): standardise PR title, body, and task slug for Jira tickets#235
EllaLiu0401 wants to merge 4 commits into
mainfrom
claude/confident-thompson-6889a7

Conversation

@EllaLiu0401
Copy link
Copy Markdown
Contributor

@EllaLiu0401 EllaLiu0401 commented May 25, 2026

Summary

  • Wire Jira ticket metadata through cube auto --jira workflow into PR creation
  • Task files now named with human-readable slugs (AP-878-standardise-pr-title.md instead of AP-878.md)
  • PR titles use Conventional Commits format mapped from Jira issue type (Bug→fix, Story/Feature→feat, Task→chore)
  • PR bodies use type-specific templates: Bug Fix (root cause / fix / how to test), Feature (what it adds / key changes / how to test), Chore (summary / key changes)
  • Non-Jira tasks fall back to original format — zero regression

Context

AP-878 — after cube auto --jira AP-123, PRs had generic titles (feat: AP-123) and minimal bodies. Jacob also suggested giving cube tasks sensible human-readable names instead of bare Jira keys.

Changes

File What changed
jira.py Added _slugify_title() — smart truncation: ≤7 words kept whole, >7 words takes first 5, 50 char max
pr.py Added _build_pr_title(), _build_pr_body() with 3 type-based templates + fallback
phases_registry.py Added jira_metadata field to WorkflowContext
cli.py Builds metadata dict from JiraTicket and passes it through
main.py, workflow.py, handlers.py Thread jira_metadata from CLI → orchestrator → Phase 10 → create_pr()
tests/ Added focused coverage for Jira title/body formatting, Feature templates, slug edge cases, and CLI metadata threading

Test plan

  • Focused pytest: python -m pytest tests/core/test_orchestrate_pr.py tests/core/test_jira_integration.py tests/cli/test_single_writer.py
  • Jira PR title/body helpers cover null field fallback, Bug title/body, and Feature body template routing
  • Jira task slug tests cover empty summaries, truncation without trailing hyphens, and slugified task filenames
  • CLI --jira test verifies fetched ticket metadata is forwarded into orchestration
  • All files compile cleanly (py_compile)
  • Run cube auto --jira <ticket> end-to-end and verify PR title/body format
  • Run a non-Jira task file and verify fallback behavior unchanged

🤖 Generated with Claude Code

Overview

Integrates Jira ticket metadata into the auto-orchestration flow so PR titles, PR bodies and task filenames can be generated from Jira fields while preserving the original behaviour when no Jira metadata is present.

Key changes

  • python/cube/integrations/jira.py

    • Added _slugify_title(key, summary, max_len=50) to generate human-readable, hyphenated slugs (e.g. AP-878-standardise-pr-title.md). Rules: keep ≤7 words; if >7 words use first 5; prefix with ticket key; cap final slug at max_len with hyphen-aware trimming; fallback to key when no words remain.
    • write_task_file now writes prompts to <prompts_dir>/.md instead of <prompts_dir>/<ticket.key>.md.
  • python/cube/commands/orchestrate/pr.py

    • Added _build_pr_title() mapping Jira issue types → Conventional Commit prefixes (bug → fix, story/epic/feature → feat, task/sub-task/subtask → chore) and enforcing a 72-char limit (ellipsis truncation).
    • Added _build_pr_body() to render issue-type-specific Markdown templates:
      • Bug: Bug Fix (what was the bug / root cause / fix / how to test)
      • Story/Epic/Feature: Feature (what does this add / key changes / how to test)
      • Other (chore/task): Changes (summary / key changes)
    • create_pr(...) accepts jira_metadata: Optional[dict] and uses computed title/body (also used in the manual-gh fallback).
  • Metadata threading (CLI → Orchestrator → Workflow → PR creation)

    • python/cube/cli.py: when --jira is provided, captures Jira ticket fields (key, summary, issue_type, priority, url, description) into jira_metadata and forwards it into orchestrate_auto_command.
    • python/cube/commands/orchestrate/main.py & workflow.py: accept jira_metadata and thread it into WorkflowContext.
    • python/cube/commands/orchestrate/phases_registry.py: WorkflowContext gains optional jira_metadata field.
    • python/cube/commands/orchestrate/handlers.py: forwards ctx.jira_metadata into create_pr() on PR creation paths.

Tests & safety

  • Unit/integration tests added for slugify, write_task_file, PR title/body helpers and create_pr wiring (tests/core/test_jira_integration.py, tests/core/test_orchestrate_pr.py, tests/cli/test_single_writer.py).
  • py_compile checks pass.
  • Pending: full end-to-end verification of cube auto --jira and confirming non-Jira fallback in live runs.

Notes

  • Backward compatible: when jira_metadata is absent, previous PR title/body/filenaming behaviour remains unchanged.

Review Change Stack

Wire Jira ticket metadata (summary, issue_type, priority, url) from
`cube auto --jira` through the workflow context into `create_pr()`.

- Task files now named with human-readable slugs (AP-878-my-title.md)
  instead of bare Jira keys (AP-878.md)
- PR titles use Conventional Commits mapped from Jira issue type
  (Bug→fix, Story→feat, Task→chore)
- PR bodies use type-specific templates: Bug Fix (root cause/fix/test),
  Feature (what/changes/test), Chore (summary/changes)
- Non-Jira tasks fall back to the original format unchanged

Closes AP-878

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 25, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 488edbaf-d8f6-42d3-b690-d6137781a8cb

📥 Commits

Reviewing files that changed from the base of the PR and between dfbaf82 and 7a57e99.

📒 Files selected for processing (3)
  • tests/cli/test_single_writer.py
  • tests/core/test_jira_integration.py
  • tests/core/test_orchestrate_pr.py
📜 Recent review details
🔇 Additional comments (3)
tests/cli/test_single_writer.py (1)

4-4: LGTM!

Also applies to: 9-9, 82-122

tests/core/test_jira_integration.py (1)

1-44: LGTM!

tests/core/test_orchestrate_pr.py (1)

6-6: LGTM!

Also applies to: 54-125


Walkthrough

CLI captures Jira fields, threads them into the auto orchestration WorkflowContext; handlers forward the metadata into create_pr which builds Jira-aware PR titles/bodies; Jira task filenames are slugified. Separately, a SteeringRuntime is added and a git submodule pointer is updated.

Changes

Jira Metadata Threading and PR Formatting

Layer / File(s) Summary
CLI capture and orchestration threading
python/cube/cli.py, python/cube/commands/orchestrate/main.py, python/cube/commands/orchestrate/workflow.py, python/cube/commands/orchestrate/phases_registry.py
CLI initialises jira_metadata, fills it from the prepared Jira ticket (key, summary, issue type, priority, url, description), and passes it into orchestrate_auto_command_orchestrate_auto_implWorkflowContext.
PR title/body generation from Jira metadata
python/cube/commands/orchestrate/pr.py, python/cube/commands/orchestrate/handlers.py
create_pr accepts optional jira_metadata and builds truncated, issue-type-aware PR titles and Markdown bodies; Phase 8 and Phase 10 handlers pass ctx.jira_metadata to all PR creation call sites; gh pr create and manual fallback use the computed title/body.
Slugified Jira task file naming
python/cube/integrations/jira.py
Adds _slugify_title(key, summary, max_len) and writes task prompts to <prompts_dir>/<slug>.md instead of <ticket.key>.md.
Tests and CLI validation
tests/cli/test_single_writer.py, tests/core/test_jira_integration.py, tests/core/test_orchestrate_pr.py
Adds tests covering CLI forwarding of jira_metadata, slug generation and task-file naming, and PR title/body construction and usage in create_pr.

Steering runtime and repo pointer

Layer / File(s) Summary
Steering runtime integration
agent-cube (new steering runtime file, wiring, tests)
Adds SteeringRuntime, wires steering into Phase 2 writer/verify flows, SDK bridge event teeing, status reporting, and runtime tests.
Submodule pointer update
.claude/worktrees/kind-ishizaka-4e3c7e
Updates the git submodule reference to a new commit hash.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • aetheronhq/agent-cube#151: Introduced the cube auto --jira OAuth-based Jira task preparation that this PR builds on; this PR threads returned ticket fields into orchestration and PR formatting.
  • aetheronhq/agent-cube#149: Modified PR-creation plumbing and body wording; related to changes in create_pr inputs and formatting.

Poem

🐰 I hopped through fields and threaded them tight,

Jira keys tucked in for title and write,
Slugs trimmed and tidy, prompts find their name,
A steering runtime hums in the game,
Small hops, big flows — a cheerful commit night.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(pr): standardise PR title, body, and task slug for Jira tickets' directly and accurately reflects the main changes across the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (2)
  • AP-878: Request failed with status code 401
  • AP-123: Request failed with status code 401

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

Copy link
Copy Markdown

@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: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@python/cube/commands/orchestrate/pr.py`:
- Around line 20-27: The _build_pr_title function (and similar PR creation code
around lines referenced) assumes jira["issue_type"], jira["key"], and
jira["summary"] are non-null strings; normalize and guard these fields before
calling string methods by reading them with jira.get("issue_type"),
jira.get("key"), jira.get("summary") and coercing None to safe defaults (e.g.,
empty string or fallback values) and call .lower()/.strip() only after that
normalization; update _ISSUE_TYPE_TO_CC lookup to use the normalized issue_type
and ensure key/summary fallbacks avoid KeyError/TypeError so PR title building
never invokes .lower()/.strip() on None.
- Line 132: The printed fallback command uses raw interpolated variables (branch
and title) which breaks if title contains apostrophes or shell metacharacters;
update the console.print call(s) (the line printing "gh pr create --base main
--head {branch} --title '{title}'" and the similar one at the later occurrence)
to shell-quote both branch and title (e.g., use Python's shlex.quote or an
equivalent quoting helper) before interpolation so the suggested command is safe
to paste into a shell regardless of characters in the Jira-derived title.

In `@python/cube/integrations/jira.py`:
- Around line 550-559: The slug generation can produce an empty title (so full
becomes "<KEY>-"), causing malformed filenames; update the logic after computing
words/title_part to handle an empty title by falling back to the key-only form
(e.g., if not words or title_part == "" then set full = key) before applying the
max_len truncation, and preserve existing truncation behavior (rsplit on "-"
when trimming) so filenames become "<KEY>" (and thus "<KEY>.md") instead of
"<KEY>-".
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0e9e2775-d3a9-431e-926e-4f356a7280ec

📥 Commits

Reviewing files that changed from the base of the PR and between 62dbc6e and 399ecc6.

📒 Files selected for processing (7)
  • python/cube/cli.py
  • python/cube/commands/orchestrate/handlers.py
  • python/cube/commands/orchestrate/main.py
  • python/cube/commands/orchestrate/phases_registry.py
  • python/cube/commands/orchestrate/pr.py
  • python/cube/commands/orchestrate/workflow.py
  • python/cube/integrations/jira.py
📜 Review details
🔇 Additional comments (6)
python/cube/integrations/jira.py (1)

562-568: LGTM!

python/cube/cli.py (1)

699-700: LGTM!

Also applies to: 723-730, 855-855

python/cube/commands/orchestrate/main.py (1)

16-16: LGTM!

Also applies to: 30-30, 50-50

python/cube/commands/orchestrate/phases_registry.py (1)

40-41: LGTM!

python/cube/commands/orchestrate/workflow.py (1)

48-48: LGTM!

Also applies to: 97-97

python/cube/commands/orchestrate/handlers.py (1)

464-464: LGTM!

Also applies to: 542-542, 553-553, 562-562

Comment thread python/cube/commands/orchestrate/pr.py
Comment thread python/cube/commands/orchestrate/pr.py Outdated
Comment thread python/cube/integrations/jira.py
Copy link
Copy Markdown

@the-agent-cube the-agent-cube Bot left a comment

Choose a reason for hiding this comment

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

🤖 Agent Cube Review

⚠️ 3/5 judges approved. Some requested changes.

⚠️ Cube panel: 3/5 approved.

Per-judge:

  • judge_1: APPROVED
  • judge_2: APPROVED
  • judge_3: REQUEST_CHANGES
  • judge_4: REQUEST_CHANGES
  • judge_5: APPROVED

🤖 Agent Cube Peer Review

return (
f"## Bug Fix\n\n{jira_line}\n\n"
f"### What was the bug?\n{desc_preview}\n\n"
f"### Root cause\n_To be filled by reviewer_\n\n"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[NITPICK] The Jira PR templates include literal _To be filled by reviewer_ placeholders for sections like Root cause, Fix, and How to test. Since these PRs are created autonomously, consider either populating those sections from the writer's notes or omitting empty sections so merged PR descriptions do not retain reviewer placeholders.

Agent Cube / Judge PO/QA, Judge Principal 🤖

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Acknowledged — keeping the placeholders for now. They serve as a review checklist for the human reviewer to fill in; removing them would lose that prompt.

Comment thread python/cube/cli.py Outdated
fresh_writer=fresh_writer,
fresh_judges=fresh,
resume_prompt=prompt,
jira_metadata=_jira_metadata,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[WARNING] Jira metadata is only held in memory for the current cube auto --jira invocation. If a Jira-originated run is resumed later via cube auto <task-file> --resume or cube continue, PR creation receives jira_metadata=None and falls back to the generic title/body instead of the Jira-aware format.

Agent Cube / Judge Backend, Judge Frontend & UX 🤖

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Acknowledged — persisting jira_metadata to disk for resume would require changing the task-file format or adding a sidecar file. Keeping as a known limitation for now; the fallback to generic title/body is safe.

Comment thread python/cube/commands/orchestrate/pr.py Outdated
f"{footer}"
)

if issue_type in ("story", "epic"):
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[WARNING] Jira issue type Feature gets a feat(...) title but does not enter the feature body template, which only handles story and epic. It falls through to ## Changes and omits the feature PR testing section.

Agent Cube / Judge Frontend & UX 🤖

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in dfbaf82 — added "feature" to both the _ISSUE_TYPE_TO_CC mapping and the body template condition.

)


def _first_sentences(text: str, n: int) -> str:
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[NITPICK] _first_sentences is only used once. Inlining the small regex snippet at the call site would remove a single-use helper and local import.

Agent Cube / Judge Principal 🤖

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Acknowledged — keeping _first_sentences as a named helper for readability. It's small but the intent is clearer than an inline regex.

Comment thread python/cube/cli.py Outdated
from .core.output import print_error, print_info
from .core.user_config import get_default_writer, is_single_mode_default, resolve_writer_alias

_jira_metadata = None
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[NITPICK] _jira_metadata is a live local value that is passed into orchestration, so the leading underscore reads like an unused/private temporary. jira_metadata would better match how the variable is used.

Agent Cube / Judge Principal 🤖

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in dfbaf82 — renamed _jira_metadatajira_metadata.

Addressed feedback:
- python/cube/commands/orchestrate/pr.py: _⚠️ Potential issue_ | _🟠 Major_ | _⚡ Qu...
- python/cube/commands/orchestrate/pr.py: _⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Qu...
- python/cube/integrations/jira.py: _⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Qu...
- general: <!-- This is an auto-generated comment:...
- general: **Actionable comments posted: 3**  <deta...

Automated fixes via cube auto --fix-comments
@EllaLiu0401
Copy link
Copy Markdown
Contributor Author

Addressed the actionable review feedback: Jira PR metadata is normalized before string operations, suggested manual gh commands are shell-quoted, and empty Jira summary slugs now fall back to the key.

Addressed 2 top-level review comment(s):

  • @coderabbitai[bot]: ## Walkthrough This PR...
  • @coderabbitai[bot]: Actionable comments posted: 3
    🤖 Prompt for all review comments with AI agents ``` Verif...

Agent Cube

Copy link
Copy Markdown

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
python/cube/integrations/jira.py (1)

546-561: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add defensive handling for truncation edge cases.

If max_len is very short or truncation lands mid-key, line 560's rsplit could lose the issue number or leave trailing hyphens. The past review comment suggested using .rstrip("-") before the conditional rsplit and adding an or key[:max_len] fallback to handle empty results.

🛡️ Proposed fix
 def _slugify_title(key: str, summary: str, max_len: int = 50) -> str:
     """Build a human-readable slug: AP-123-some-descriptive-words."""
     import re
 
     slug = re.sub(r"[^a-z0-9]+", "-", summary.lower()).strip("-")
     words = [word for word in slug.split("-") if word]
     if not words:
         return key[:max_len]
     if len(words) <= 7:
         title_part = "-".join(words)
     else:
         title_part = "-".join(words[:5])
     full = f"{key}-{title_part}" if title_part else key
     if len(full) > max_len:
-        full = full[:max_len].rsplit("-", 1)[0]
+        full = full[:max_len].rstrip("-")
+        if "-" in full:
+            full = full.rsplit("-", 1)[0] or key[:max_len]
     return full
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@python/cube/integrations/jira.py` around lines 546 - 561, The _slugify_title
function can drop the issue key or leave trailing hyphens when truncating;
update the truncation logic in _slugify_title to rstrip("-") before performing
rsplit so you don't leave trailing hyphens, and if the rsplit yields an empty
string (e.g., very small max_len), fall back to returning key[:max_len]; ensure
this change is applied to the branch that assigns to full when len(full) >
max_len so the function never returns an empty or mid-key slug.
♻️ Duplicate comments (1)
python/cube/commands/orchestrate/pr.py (1)

68-75: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Issue type "feature" doesn't enter the feature template.

The condition only checks for lowercase "story" and "epic". If Jira returns issue_type "Feature" (which normalises to "feature"), it falls through to the generic "## Changes" template and omits the feature-specific testing section.

🔧 Proposed fix
-    if issue_type in ("story", "epic"):
+    if issue_type in ("story", "epic", "feature"):
         return (
             f"## Feature\n\n{jira_line}\n\n"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@python/cube/commands/orchestrate/pr.py` around lines 68 - 75, The
feature-specific template never runs when Jira returns "feature" because the
condition currently only checks issue_type in ("story", "epic"); update the
condition (where issue_type is evaluated in pr.py) to include "feature" (or
ensure issue_type is normalized and check for "feature" alongside "story" and
"epic") so that the Feature template block (the f-string that builds "##
Feature...### How to test") is used for feature issues.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@python/cube/integrations/jira.py`:
- Around line 546-561: The _slugify_title function can drop the issue key or
leave trailing hyphens when truncating; update the truncation logic in
_slugify_title to rstrip("-") before performing rsplit so you don't leave
trailing hyphens, and if the rsplit yields an empty string (e.g., very small
max_len), fall back to returning key[:max_len]; ensure this change is applied to
the branch that assigns to full when len(full) > max_len so the function never
returns an empty or mid-key slug.

---

Duplicate comments:
In `@python/cube/commands/orchestrate/pr.py`:
- Around line 68-75: The feature-specific template never runs when Jira returns
"feature" because the condition currently only checks issue_type in ("story",
"epic"); update the condition (where issue_type is evaluated in pr.py) to
include "feature" (or ensure issue_type is normalized and check for "feature"
alongside "story" and "epic") so that the Feature template block (the f-string
that builds "## Feature...### How to test") is used for feature issues.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6b0c7c31-a7fe-481c-b2fc-09e74ab8db78

📥 Commits

Reviewing files that changed from the base of the PR and between 399ecc6 and e2a1efc.

📒 Files selected for processing (2)
  • python/cube/commands/orchestrate/pr.py
  • python/cube/integrations/jira.py
📜 Review details
🔇 Additional comments (5)
python/cube/commands/orchestrate/pr.py (4)

21-31: LGTM!


140-152: LGTM!


3-3: LGTM!


93-105: LGTM!

python/cube/integrations/jira.py (1)

564-570: LGTM!

- Add "feature" to issue type condition so Feature tickets use the
  feature PR body template instead of falling through to generic
- Add rstrip("-") and key fallback in slug truncation to prevent
  trailing hyphens or empty slugs on edge-case max_len
- Rename _jira_metadata → jira_metadata (not a private/unused temp)

Co-authored-by: Cursor <cursoragent@cursor.com>
@EllaLiu0401
Copy link
Copy Markdown
Contributor Author

Both remaining items from CodeRabbit's second review are fixed in dfbaf82:

  1. Truncation edge cases (jira.py) — added .rstrip("-") before rsplit, and or key[:max_len] fallback for empty results.
  2. Feature type fallthrough (pr.py) — added "feature" to the _ISSUE_TYPE_TO_CC mapping and the body template condition.

Also addressed Agent Cube review comments: renamed _jira_metadatajira_metadata in cli.py. Acknowledged nitpicks on placeholder text and _first_sentences helper — keeping as-is by design.

Co-authored-by: Cursor <cursoragent@cursor.com>
Copy link
Copy Markdown

@the-agent-cube the-agent-cube Bot left a comment

Choose a reason for hiding this comment

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

🤖 Agent Cube Review

❌ 2 judge(s) requested changes. ⚠️ 3 judge(s) failed to produce a decision: Judge PO/QA, Judge Principal, Judge Security.

⚠️ Cube panel: 0/5 approved — 3 expected judge(s) failed to produce a decision: Judge PO/QA, Judge Principal, Judge Security.

Per-judge:

  • judge_3: REQUEST_CHANGES
  • judge_4: REQUEST_CHANGES

🤖 Agent Cube Peer Review

@@ -0,0 +1 @@
Subproject commit 28fd38c74f98a4605538301ce288c6b83b5489aa
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[WARNING] Could these gitlink additions be removed from the PR? This path and the root agent-cube entry are committed as mode-160000 subproject pointers without a .gitmodules entry, and they appear unrelated to the Jira PR metadata change. Fresh checkouts will inherit unexplained, unusable gitlinks instead of normal project files.

Agent Cube / Judge Backend, Judge Frontend & UX 🤖

Comment thread python/cube/cli.py
fresh_writer=fresh_writer,
fresh_judges=fresh,
resume_prompt=prompt,
jira_metadata=jira_metadata,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[WARNING] Jira metadata appears to be lost on resume. jira_metadata starts as None and is only populated during the current cube auto --jira invocation, so a later cube auto --resume / cube continue can reach PR creation with jira_metadata=None and fall back to the generic feat: <task_id> title/body instead of the Jira-specific formatting.

Agent Cube / Judge Backend, Judge Frontend & UX 🤖

Copy link
Copy Markdown

@the-agent-cube the-agent-cube Bot left a comment

Choose a reason for hiding this comment

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

🤖 Agent Cube Review

❌ 2 judge(s) requested changes. ⚠️ 3 judge(s) failed to produce a decision: Judge PO/QA, Judge Principal, Judge Security.

⚠️ Cube panel: 0/5 approved — 3 expected judge(s) failed to produce a decision: Judge PO/QA, Judge Principal, Judge Security.

Per-judge:

  • judge_3: REQUEST_CHANGES
  • judge_4: REQUEST_CHANGES

🤖 Agent Cube Peer Review

Copy link
Copy Markdown

@the-agent-cube the-agent-cube Bot left a comment

Choose a reason for hiding this comment

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

🤖 Agent Cube Review

❌ 2 judge(s) requested changes. ⚠️ 3 judge(s) failed to produce a decision: Judge PO/QA, Judge Principal, Judge Security.

⚠️ Cube panel: 0/5 approved — 3 expected judge(s) failed to produce a decision: Judge PO/QA, Judge Principal, Judge Security.

Per-judge:

  • judge_3: REQUEST_CHANGES
  • judge_4: REQUEST_CHANGES

🤖 Agent Cube Peer Review

Copy link
Copy Markdown

@the-agent-cube the-agent-cube Bot left a comment

Choose a reason for hiding this comment

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

🤖 Agent Cube Review

⚠️ 1/5 judges approved. Some requested changes.

⚠️ Cube panel: 1/5 approved.

Per-judge:

  • judge_1: REQUEST_CHANGES
  • judge_2: REQUEST_CHANGES
  • judge_3: REQUEST_CHANGES
  • judge_4: REQUEST_CHANGES
  • judge_5: APPROVED

🤖 Agent Cube Peer Review

Copy link
Copy Markdown
Contributor

@roy-songzhe-li roy-songzhe-li left a comment

Choose a reason for hiding this comment

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

Prior concerns addressed well — Feature routing fixed, null normalization added, shell quoting done, slug fallback implemented. Two remaining issues: gitlink artifacts polluting the diff and a test gap around slug collisions.

@@ -0,0 +1 @@
Subproject commit 28fd38c74f98a4605538301ce288c6b83b5489aa
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Contract: This file and the root agent-cube entry are mode-160000 subproject commits with no .gitmodules file. They appear unrelated to Jira PR metadata and will create broken gitlinks on fresh clones. Should be removed from this PR before merge.

parts = re.split(r"(?<=[.!?])\s+", text.strip(), maxsplit=n)
return " ".join(parts[:n])


Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Bug: _first_sentences splits on re.split(r"(?<=[.!?])\s+", text, maxsplit=n) and returns parts[:n]. If text contains no sentence-ending punctuation (common for short Jira descriptions like "Fix broken PR title"), the split produces a single element and the function returns the entire text unchanged. For short descriptions this is fine, but for long single-sentence Jira descriptions (200+ chars), the full blob becomes the PR body preview without truncation. Consider adding a character-length fallback (e.g., truncate to 200 chars with ellipsis if result exceeds a threshold).

full = full[:max_len].rstrip("-")
if "-" in full:
full = full.rsplit("-", 1)[0] or key[:max_len]
return full
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Test Gap: No test covers the case where two Jira tickets produce the same slug. Since write_task_file uses path.write_text(), the second call silently overwrites the first task file. For a solo cube auto --jira invocation this is fine, but if used in batch/parallel contexts (multiple tickets queued), data loss is possible. Worth at least a comment documenting this limitation or a test asserting the overwrite behavior is intentional.

summary = str(jira.get("summary") or task_id).strip()
cc = _ISSUE_TYPE_TO_CC.get(issue_type, "feat")
title = f"{cc}({key}): {summary}"
if len(title) > 72:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Unclear: When jira.get("key") is None and jira.get("summary") is None, both fall back to task_id. The resulting title becomes feat(task_id): task_id — e.g., feat(AP-878): AP-878. The test asserts exactly this, but is the duplication intentional UX or would something like feat(AP-878): <no summary> be more informative to the reviewer?

Copy link
Copy Markdown
Contributor

@roy-songzhe-li roy-songzhe-li left a comment

Choose a reason for hiding this comment

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

⚠️ One merge blocker + solid feature work

Re-review via cursor-agent + code-review skill. Prior concerns are resolved and test coverage is strong. One blocking item before merge.

Prior Concerns ✅

  • Feature template routing fixed
  • _jira_metadatajira_metadata
  • Shell-quoting via shlex.quote()
  • Null field normalization
  • Empty summary slug fallback
  • Metadata resume limitation acknowledged (safe fallback)

Test Coverage ✅

15 tests covering:

  • Slug generation (empty, truncation, filename)
  • PR title (null normalization)
  • PR body (Feature template)
  • PR creation (Bug type + jira_metadata)
  • CLI threading (--jira flag)

Merge Blocker ❌

Gitlink artifacts (.claude/worktrees/kind-ishizaka-4e3c7e and agent-cube) must be removed. These are broken subproject pointers with no .gitmodules and will break fresh clones.

Minor Issues (not blockers)

  • Long single-sentence Jira descriptions not truncated (no .!? punctuation)
  • No test for slug collision (same ticket + similar summaries)
  • Duplicated fallback when key and summary both None

Once the gitlinks are removed, this is ready to merge. Great work on addressing the feedback!

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.

2 participants