diff --git a/.claude/agents/issue-plan-agent.md b/.claude/agents/issue-plan-agent.md index 62e61eee..80b2e6ff 100644 --- a/.claude/agents/issue-plan-agent.md +++ b/.claude/agents/issue-plan-agent.md @@ -212,14 +212,14 @@ Write solution JSON to JSONL file (one line per solution): **File Format** (JSONL - each line is a complete solution): ``` -{"id":"SOL-GH-123-1","description":"...","approach":"...","analysis":{...},"score":0.85,"tasks":[...]} -{"id":"SOL-GH-123-2","description":"...","approach":"...","analysis":{...},"score":0.75,"tasks":[...]} +{"id":"SOL-GH-123-a7x9","description":"...","approach":"...","analysis":{...},"score":0.85,"tasks":[...]} +{"id":"SOL-GH-123-b2k4","description":"...","approach":"...","analysis":{...},"score":0.75,"tasks":[...]} ``` **Solution Schema** (must match CLI `Solution` interface): ```typescript { - id: string; // Format: SOL-{issue-id}-{N} + id: string; // Format: SOL-{issue-id}-{uid} description?: string; approach?: string; tasks: SolutionTask[]; @@ -232,9 +232,14 @@ Write solution JSON to JSONL file (one line per solution): **Write Operation**: ```javascript // Append solution to JSONL file (one line per solution) -const solutionId = `SOL-${issueId}-${seq}`; +// Use 4-char random uid to avoid collisions across multiple plan runs +const uid = Math.random().toString(36).slice(2, 6); // e.g., "a7x9" +const solutionId = `SOL-${issueId}-${uid}`; const solutionLine = JSON.stringify({ id: solutionId, ...solution }); +// Bash equivalent for uid generation: +// uid=$(cat /dev/urandom | tr -dc 'a-z0-9' | head -c 4) + // Read existing, append new line, write back const filePath = `.workflow/issues/solutions/${issueId}.jsonl`; const existing = existsSync(filePath) ? readFileSync(filePath) : ''; @@ -311,7 +316,7 @@ Each line is a solution JSON containing tasks. Schema: `cat .claude/workflows/cl 6. Evaluate each solution with `analysis` and `score` 7. Write solutions to `.workflow/issues/solutions/{issue-id}.jsonl` (append mode) 8. For HIGH complexity: generate 2-3 candidate solutions -9. **Solution ID format**: `SOL-{issue-id}-{N}` (e.g., `SOL-GH-123-1`, `SOL-GH-123-2`) +9. **Solution ID format**: `SOL-{issue-id}-{uid}` where uid is 4 random alphanumeric chars (e.g., `SOL-GH-123-a7x9`) 10. **GitHub Reply Task**: If issue has `github_url` or `github_number`, add final task to comment on GitHub issue with completion summary **CONFLICT AVOIDANCE** (for batch processing of similar issues): diff --git a/.claude/commands/issue/plan.md b/.claude/commands/issue/plan.md index 9dc32294..16a15369 100644 --- a/.claude/commands/issue/plan.md +++ b/.claude/commands/issue/plan.md @@ -203,7 +203,7 @@ ${issueList} 7. Single solution → auto-bind; Multiple → return for selection ### Rules -- Solution ID format: SOL-{issue-id}-{seq} +- Solution ID format: SOL-{issue-id}-{uid} (uid: 4 random alphanumeric chars, e.g., a7x9) - Single solution per issue → auto-bind via ccw issue bind - Multiple solutions → register only, return pending_selection - Tasks must have quantified acceptance.criteria diff --git a/.claude/workflows/cli-templates/schemas/solution-schema.json b/.claude/workflows/cli-templates/schemas/solution-schema.json index c304138e..c136d9f2 100644 --- a/.claude/workflows/cli-templates/schemas/solution-schema.json +++ b/.claude/workflows/cli-templates/schemas/solution-schema.json @@ -7,9 +7,9 @@ "properties": { "id": { "type": "string", - "description": "Unique solution identifier: SOL-{issue-id}-{seq}", - "pattern": "^SOL-.+-[0-9]+$", - "examples": ["SOL-GH-123-1", "SOL-ISS-20251229-1"] + "description": "Unique solution identifier: SOL-{issue-id}-{4-char-uid} where uid is 4 alphanumeric chars", + "pattern": "^SOL-.+-[a-z0-9]{4}$", + "examples": ["SOL-GH-123-a7x9", "SOL-ISS-20251229-001-b2k4"] }, "description": { "type": "string", diff --git a/ccw/src/templates/dashboard-js/views/issue-manager.js b/ccw/src/templates/dashboard-js/views/issue-manager.js index b4ed558a..4669c0eb 100644 --- a/ccw/src/templates/dashboard-js/views/issue-manager.js +++ b/ccw/src/templates/dashboard-js/views/issue-manager.js @@ -338,6 +338,14 @@ function renderIssueCard(issue) { ${t('issues.boundSolution') || 'Bound'} ` : ''} + ${issue.github_url ? ` + + + ${issue.github_number ? `#${issue.github_number}` : 'GitHub'} + + ` : ''} `;