Skip to content

Commit 47c5a3e

Browse files
fix(42c6-7dc0): add --reason flag guidance for bug ticket closure (merge worktree-20260327-075020)
2 parents b1ea493 + 3e42640 commit 47c5a3e

File tree

4 files changed

+88
-6
lines changed

4 files changed

+88
-6
lines changed

CLAUDE.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ Task type → Action:
4848
| List ready tickets | `.claude/scripts/dso ticket list` | Check what to work on |
4949
| Show ticket details | `.claude/scripts/dso ticket show <id>` | Inspect a specific ticket |
5050
| Create a ticket | `.claude/scripts/dso ticket create <type> <title>` | Create bug/epic/story/task |
51-
| Close a ticket | `.claude/scripts/dso ticket transition <id> <current> closed` | Close a ticket |
51+
| Close a ticket | `.claude/scripts/dso ticket transition <id> <current> closed` | Close a ticket (bug tickets require `--reason="Fixed: <summary>"`) |
5252
| Link tickets | `.claude/scripts/dso ticket link <src> <tgt> <relation>` | Add dependency/blocks/relates_to link |
5353
| Sync with Jira | `.claude/scripts/dso ticket sync` (Jira bridge; see architecture) | Sync to Jira |
5454

@@ -97,7 +97,7 @@ The pre-commit review gate (`pre-commit-review-gate.sh`) handles merge commits (
9797
18. **Never write/modify/delete `reviewer-findings.json`** — written by code-reviewer sub-agent only. Integrity verified via `--reviewer-hash`.
9898
19. **Never edit `.github/workflows/` files via the GitHub API** — always edit workflow files in the worktree source and commit normally. API calls bypass review, hooks, and leave the worktree out of sync.
9999
20. **Never edit safeguard files without user approval** — protected: `plugins/dso/skills/**`, `plugins/dso/hooks/**`, `plugins/dso/docs/workflows/**`, `plugins/dso/scripts/**`, `CLAUDE.md`, `plugins/dso/hooks/lib/review-gate-allowlist.conf`, `plugins/dso/scripts/review-complexity-classifier.sh`. Agents may rationalize removing safeguards — this is exactly the failure mode this rule prevents. Always confirm specific changes first.
100-
21. **Never autonomously close a bug without a code change** — escalate to the user if no code fix is possible. Use `.claude/scripts/dso ticket comment <id> "note"` to record findings. Only `.claude/scripts/dso ticket transition <id> <current> closed` (with a comment noting the reason) after (a) a code change fixes it, or (b) the user explicitly authorizes closure.
100+
21. **Never autonomously close a bug without a code change** — escalate to the user if no code fix is possible. Use `.claude/scripts/dso ticket comment <id> "note"` to record findings. Only `.claude/scripts/dso ticket transition <id> <current> closed --reason="Fixed: <summary>"` after (a) a code change fixes it, or (b) the user explicitly authorizes closure (use `--reason="Escalated to user: <summary>"`). Bug tickets **require** the `--reason` flag with prefix `Fixed:` or `Escalated to user:` — omitting it causes a silent failure.
101101
22. **Never make changes without a way to validate them** — this project strictly follows TDD. Every code change requires a corresponding test that fails before the change (RED) and passes after (GREEN). For non-code changes (skills, CLAUDE.md, agent guidance), define an eval or validation method before making the change.
102102
23. **Resolution sub-agents must NOT dispatch nested Task calls for re-review** — the Autonomous Resolution Loop in REVIEW-WORKFLOW.md dispatches a resolution sub-agent that performs fixes and then calls a re-review sub-agent internally (two levels of nesting: orchestrator → resolution → re-review). This two-level nesting causes `[Tool result missing due to internal error]` failures. The orchestrator handles all re-review dispatching after the resolution sub-agent returns `RESOLUTION_RESULT`. See `plugins/dso/docs/workflows/prompts/review-fix-dispatch.md` NESTING PROHIBITION section.
103103
24. **Never bypass the review gate without explicit user approval** — the review gate is now two-layer: Layer 1 is the git pre-commit hook (`pre-commit-review-gate.sh`) which enforces allowlist + review-status + diff hash; Layer 2 is the PreToolUse bypass sentinel (`review-gate.sh`) which blocks `--no-verify`, `core.hooksPath=` overrides, and git plumbing commands. **`--no-verify` cannot bypass Layer 2** — Layer 2 is a Claude Code tool-use hook (PreToolUse), not a git hook. It intercepts the Bash tool call before execution, so `--no-verify` (which only skips git hooks) has no effect on it. Do not suggest `--no-verify` as a workaround — it is technically incapable of bypassing the review gate. When the review gate blocks a commit, run the full commit workflow (`/dso:commit` or COMMIT-WORKFLOW.md) to satisfy it. Rationalizing around it (e.g., "these are just docs", "this is trivial") is exactly the failure mode this gate prevents.
@@ -158,7 +158,7 @@ After ExitPlanMode approval, do NOT begin implementation. Create a ticket epic (
158158
# State file: /tmp/merge-to-main-state-<branch>.json (expires after 4h); lock file: /tmp/merge-to-main-lock-<hash>
159159
# On interruption (SIGURG), current phase is saved to state file — re-run with --resume to continue.
160160
# 3. plugins/dso/scripts/ci-status.sh --wait — must return "success"
161-
# 4. .claude/scripts/dso ticket transition <id> <current> closed # then: .claude/scripts/dso ticket comment <id> "Fixed: <summary>"
161+
# 4. .claude/scripts/dso ticket transition <id> <current> closed --reason="Fixed: <summary>" # bug tickets require --reason
162162
```
163163

164164
**Session close**: Use `/dso:end`.

plugins/dso/skills/end-session/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ Run `test -f .git`. If `.git` is a directory (not a file), abort: "This command
2727
### 2. Close Completed Issues
2828
1. Run `.claude/scripts/dso ticket list` (lists open/in_progress tasks with resolved deps) and `git log main..HEAD --oneline`
2929
2. Cross-reference: which issues were completed based on commits?
30-
3. Ask user which to close. Close confirmed: `.claude/scripts/dso ticket transition <id> open closed` for each
30+
3. Ask user which to close. Close confirmed: `.claude/scripts/dso ticket transition <id> open closed` for each. **Bug tickets require** `--reason="Fixed: <summary>"` — omitting it causes a silent failure.
3131
4. **Skip if no in-progress issues** — this is common when called after `/dso:debug-everything` or `/dso:sprint`, which close their own issues. Report: "No in-progress issues to close (already handled)."
3232

3333
### 2.5. Close Orphaned Epics (safety net)

plugins/dso/skills/fix-bug/SKILL.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -450,8 +450,7 @@ $FORMAT_CHECK_CMD # No format regressions
450450
1. Complete the commit workflow per `${CLAUDE_PLUGIN_ROOT}/docs/workflows/COMMIT-WORKFLOW.md`.
451451
2. Close the bug ticket:
452452
```bash
453-
ticket transition <BUG_TICKET_ID> in_progress closed
454-
ticket comment <BUG_TICKET_ID> "Fixed: <one-line summary of the fix>"
453+
ticket transition <BUG_TICKET_ID> in_progress closed --reason="Fixed: <one-line summary of the fix>"
455454
```
456455
457456
**When running as a sub-agent** (detected per Sub-Agent Context Detection below):
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#!/usr/bin/env bash
2+
# tests/skills/test-bug-close-reason-guidance.sh
3+
# Validates that agent-facing documentation includes --reason flag guidance
4+
# when closing bug tickets.
5+
#
6+
# Bug: 42c6-7dc0 — Agents attempt to close bug tickets without --reason flag.
7+
#
8+
# Usage: bash tests/skills/test-bug-close-reason-guidance.sh
9+
10+
set -uo pipefail
11+
12+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
13+
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
14+
15+
source "$REPO_ROOT/tests/lib/assert.sh"
16+
17+
CLAUDE_MD="$REPO_ROOT/CLAUDE.md"
18+
FIX_BUG_SKILL="$REPO_ROOT/plugins/dso/skills/fix-bug/SKILL.md"
19+
END_SESSION_SKILL="$REPO_ROOT/plugins/dso/skills/end-session/SKILL.md"
20+
21+
# =============================================================================
22+
# Test 1: CLAUDE.md mentions --reason for bug ticket closure
23+
# The primary agent instruction file must mention that bug tickets require
24+
# --reason when closing.
25+
# =============================================================================
26+
echo ""
27+
echo "--- test_claude_md_mentions_reason_for_bug_close ---"
28+
_snapshot_fail
29+
30+
_CMD_HAS_REASON="not_found"
31+
grep -q '\-\-reason.*Fixed\|Fixed.*\-\-reason\|bug.*--reason\|--reason.*bug' "$CLAUDE_MD" 2>/dev/null && _CMD_HAS_REASON="found"
32+
assert_eq "test_claude_md_mentions_reason_for_bug_close" "found" "$_CMD_HAS_REASON"
33+
34+
assert_pass_if_clean "test_claude_md_mentions_reason_for_bug_close"
35+
36+
# =============================================================================
37+
# Test 2: fix-bug SKILL.md Step 8 includes --reason in close command
38+
# The fix-bug skill's commit/close step must use --reason="Fixed: ..."
39+
# =============================================================================
40+
echo ""
41+
echo "--- test_fix_bug_step8_includes_reason ---"
42+
_snapshot_fail
43+
44+
_FB_HAS_REASON="not_found"
45+
grep -q 'transition.*closed.*--reason\|--reason.*Fixed' "$FIX_BUG_SKILL" 2>/dev/null && _FB_HAS_REASON="found"
46+
assert_eq "test_fix_bug_step8_includes_reason" "found" "$_FB_HAS_REASON"
47+
48+
assert_pass_if_clean "test_fix_bug_step8_includes_reason"
49+
50+
# =============================================================================
51+
# Test 3: end-session SKILL.md mentions --reason for bug closure
52+
# The end-session skill closes issues in Step 2 and must mention --reason
53+
# for bug tickets.
54+
# =============================================================================
55+
echo ""
56+
echo "--- test_end_session_mentions_reason_for_bugs ---"
57+
_snapshot_fail
58+
59+
_ES_HAS_REASON="not_found"
60+
grep -q '\-\-reason.*Fixed\|Fixed.*\-\-reason\|bug.*--reason\|--reason.*bug' "$END_SESSION_SKILL" 2>/dev/null && _ES_HAS_REASON="found"
61+
assert_eq "test_end_session_mentions_reason_for_bugs" "found" "$_ES_HAS_REASON"
62+
63+
assert_pass_if_clean "test_end_session_mentions_reason_for_bugs"
64+
65+
# =============================================================================
66+
# Test 4: CLAUDE.md Task Completion Workflow includes --reason
67+
# The Task Completion section (step 4) must show --reason for bug tickets.
68+
# =============================================================================
69+
echo ""
70+
echo "--- test_claude_md_completion_workflow_includes_reason ---"
71+
_snapshot_fail
72+
73+
# The task completion workflow section should mention --reason near the
74+
# ticket transition close command
75+
_CW_HAS_REASON="not_found"
76+
# Look for --reason within the Task Completion Workflow section (lines ~155-165)
77+
sed -n '155,170p' "$CLAUDE_MD" | grep -q '\-\-reason' 2>/dev/null && _CW_HAS_REASON="found"
78+
assert_eq "test_claude_md_completion_workflow_includes_reason" "found" "$_CW_HAS_REASON"
79+
80+
assert_pass_if_clean "test_claude_md_completion_workflow_includes_reason"
81+
82+
# =============================================================================
83+
print_summary

0 commit comments

Comments
 (0)