automagik-genie
Version:
Self-evolving AI agent orchestration framework with Model Context Protocol support
411 lines (305 loc) • 10.4 kB
Markdown
# Rule #6: Wish-Issue Linkage (Behavioral Spell)
**Created:** 2025-10-20
**Priority:** CRITICAL
**Learn Session:** c873572f-fd95-4ea0-a0c9-cdaed1dda898
**CRITICAL RULE:** Every wish MUST link to a GitHub issue. No issue → no wish creation.
## The Core Principle
**Before ANY wish document is created:**
1. GitHub issue MUST exist
2. Issue number MUST be validated
3. Issue link MUST be in wish front-matter
**No exceptions.** This is mandatory for all wish workflows.
## Why This Rule Exists
### Problem it Solves
**Without issue linkage:**
- ❌ No team visibility (non-Genie users don't know what's planned)
- ❌ No approval checkpoint (work may be rejected after implementation)
- ❌ No audit trail (work history scattered across systems)
- ❌ No search/discovery (GitHub search can't find wishes)
- ❌ No permalink stability (wishes live in .genie/, may move)
**With issue linkage:**
- ✅ Team visibility (everyone sees what's being worked on)
- ✅ Approval gates (issue discussion before implementation starts)
- ✅ Complete audit trail (issue → wish → forge task → PR → merge)
- ✅ Searchable history (GitHub search finds all work)
- ✅ Stable permalinks (issue #XXX never changes)
### Architectural Hierarchy
```
GitHub Issue (Public, Permanent)
↓
Wish Document (Internal Planning)
↓
Forge Task (Execution Tracking)
↓
Git Branch + Worktree (Implementation)
↓
Pull Request (Review + Merge)
```
**Each level links to parent:**
- Wish → Issue #XXX
- Forge task → Issue #XXX + Wish path
- Branch → forge/XXXX-kebab-case (derived from task)
- PR → Closes #XXX
## How To Apply This Rule
### Step 1: Issue Validation (BEFORE Discovery)
**When user requests wish creation:**
```typescript
// Genie MUST check:
const issueProvided = userInput.includes('#') || userInput.includes('issue');
if (!issueProvided) {
// Ask user for issue number
await ask("Is there a GitHub issue for this? If yes, provide #XXX. If no, I'll create one.");
}
// Validate issue exists
const issue = await gh.issue.get(issueNumber);
if (!issue) {
// Route to issue creation workflow
await createIssueFirst();
}
```
**BLOCK wish creation until issue confirmed.**
### Step 2: Issue Creation (If Missing)
If no issue exists, route to issue creation:
```markdown
**Issue Creation Checklist:**
1. Ask user: "Should I create GitHub issue first?"
2. Gather context:
- Title (clear, actionable)
- Description (context ledger summary)
- Labels (wish, enhancement, bug, etc.)
- Acceptance criteria
3. Create issue via GitHub API:
\`gh issue create --title "..." --body "..." --label wish\`
4. Extract issue number from response
5. THEN proceed to wish creation
```
### Step 3: Wish Document Linkage
Every wish document MUST include issue reference:
```markdown
# Wish: <Title>
**GitHub Issue:** #152 <-- MANDATORY FIELD
**Status:** Discovery
**Created:** !`date -u +"%Y-%m-%d"`
**Forge Task:** (filled after task creation)
## Context Ledger
**Origin:** GitHub Issue #152
**Problem:** [from issue description]
...
```
### Step 4: Forge Task Linkage
When creating wish with task:
```typescript
await mcp__genie__create_wish({
feature: "MCP Server Authentication",
github_issue: 152 // Issue number required!
});
// Or run forge task directly:
await mcp__genie__run_forge({
agent: "implementor",
prompt: `
**GitHub Issue:** #152
**Wish Document:** @.genie/wishes/mcp-auth/mcp-auth-wish.md
[Full wish context from issue]
`
});
```
## Integration With Existing Workflows
### Wish Workflow Enhancement
**Add Step 0 (NEW) before Discovery:**
```markdown
### Step 0: Issue Validation
**Goal:** Ensure GitHub issue exists before starting wish dance
**Process:**
1. Check if user provided issue number
2. If YES:
- Validate issue exists: \`gh issue view #XXX\`
- Extract context from issue
- Proceed to Step 1 (Discovery)
3. If NO:
- Ask: "Should I create a GitHub issue first?"
- If user says yes → delegate to issue-creation workflow
- If user says no → BLOCK wish creation, explain rule
**Delegation:**
\`\`\`
mcp__genie__run with agent="issue-check" prompt="Validate issue #XXX exists"
\`\`\`
**Output:** Issue number + issue context + "Ready for discovery?"
```
### Blueprint Workflow Enhancement
**Update wish document template:**
```markdown
**Required front-matter fields:**
- GitHub Issue: #XXX <-- MUST be filled
- Forge Task: <task_id> <-- Auto-filled after creation
- Status: Discovery/In-Progress/Review/Done
- Created: !`date`
```
## Enforcement Mechanism
### Pre-Creation Check
**In wish.md orchestrator:**
```typescript
// BEFORE starting wish dance
async function validateIssueExists(userRequest: string): Promise<IssueValidation> {
const issueMatch = userRequest.match(/#(\d+)/);
if (!issueMatch) {
return {
valid: false,
reason: "No issue number provided",
action: "prompt_user_for_issue"
};
}
const issueNumber = issueMatch[1];
const issue = await gh.issue.get(issueNumber);
if (!issue) {
return {
valid: false,
reason: `Issue #${issueNumber} does not exist`,
action: "create_issue_first"
};
}
return {
valid: true,
issue: issue,
issueNumber: issueNumber
};
}
```
### Post-Creation Validation
**In review.md agent:**
```typescript
// Validate wish document has issue link
async function validateWishDocument(wishPath: string): Promise<boolean> {
const content = await fs.readFile(wishPath, 'utf-8');
const hasIssueLink = /\*\*GitHub Issue:\*\* #\d+/.test(content);
if (!hasIssueLink) {
throw new Error(`Wish ${wishPath} missing GitHub issue link! Rule #6 violation.`);
}
return true;
}
```
## Examples
### ✅ CORRECT: Issue First, Then Wish
```
User: "I want to add MCP authentication"
Genie: "Great idea! Is there a GitHub issue for this?"
User: "Yes, #152"
Genie: [Validates #152 exists]
Genie: "Perfect! Issue #152 confirmed. Let's start the wish dance..."
[Creates wish with GitHub Issue: #152]
[Links Forge task to #152]
```
### ✅ CORRECT: Create Issue First
```
User: "I want to unify the naming taxonomy"
Genie: "Excellent! I don't see a GitHub issue for this. Should I create one first?"
User: "Yes please"
Genie: [Creates issue #155 via gh CLI]
Genie: "Issue #155 created! Now let's create the wish..."
[Creates wish with GitHub Issue: #155]
```
### ❌ WRONG: Wish Without Issue
```
User: "Create a wish for voice agent transformation"
Genie: [Creates wish document immediately] <-- VIOLATION!
Genie: [No issue link in wish] <-- VIOLATION!
← This breaks Rule #6. MUST validate/create issue FIRST.
```
## Spell Metadata
**Spell Type:** Behavioral (Tier 6 - Workflow & State Management)
**Auto-loaded:** YES (every session)
**Enforced by:** wish.md orchestrator, review.md validator
**Violation handling:** BLOCK wish creation, route to issue-creation
**Related spells:**
- Rule #2: Wish Initiation (`@.genie/spells/wish-initiation.md`)
- Wish Document Management (`@.genie/spells/wish-lifecycle.md`)
- Persistent Tracking Protocol (`@.genie/spells/track-long-running-tasks.md`)
## Anti-Patterns To Avoid
❌ **"The issue is implied"** → No. Explicit link required.
❌ **"I'll create issue after wish"** → No. Issue FIRST, always.
❌ **"This is internal work, no issue needed"** → No. All wishes need issues.
❌ **"Issue creation slows me down"** → Good. Approval gate is intentional.
❌ **"I forgot to link the issue"** → Fix immediately (retroactive linking).
## Retroactive Fixes
**If wish exists without issue:**
1. Create GitHub issue immediately
2. Update wish document with issue #
3. Update Forge task title/description with issue #
4. Add violation note to learn session
5. Document in meta-learn protocol
**Example:**
```bash
# Create missing issue
gh issue create --title "Wish: Voice Agent Transformation" \
--body "$(cat .genie/wishes/voice-agent/voice-agent-wish.md)" \
--label wish
# Extract issue number
ISSUE_NUM=$(gh issue list --limit 1 --json number --jq '.[0].number')
# Update wish document
sed -i "s/\*\*GitHub Issue:\*\* TBD/**GitHub Issue:** #$ISSUE_NUM/" \
.genie/wishes/voice-agent/voice-agent-wish.md
# Document violation
echo "Rule #6 violation: Retroactively linked issue #$ISSUE_NUM" >> \
.genie/reports/learn-wish-issue-amendment-20251020.md
```
## MCP Integration
### Genie Spell Execution Pattern
**Goal:** Genie MCP executes spells dynamically (lighter base prompts)
**How this works:**
1. Base Genie prompt = thin orchestrator
2. Spells loaded as @ references (not full content in base prompt)
3. When wish requested → Genie dynamically loads wish-issue-linkage-rule.md
4. Spell execution = read file, apply rules, validate
**Benefits:**
- Lighter base prompts (token efficiency)
- Spells updated independently (no base prompt changes)
- Clear separation of concerns (orchestration vs execution)
**Implementation:**
```typescript
// In wish.md orchestrator
async function ensureIssueExists(userRequest: string) {
// Load spell dynamically
const spell = await loadSkill('@.genie/spells/wish-issue-linkage.md');
// Execute spell logic
const validation = await spell.validateIssue(userRequest);
if (!validation.valid) {
// Route to issue creation
return await spell.createIssueFirst(userRequest);
}
return validation.issueNumber;
}
```
## Summary
**Rule #6 in one sentence:**
> No GitHub issue = no wish creation. Issue first, always.
**Why it matters:**
- Team visibility (public tracking)
- Approval gates (discussion before work)
- Audit trail (complete history)
- Search/discovery (GitHub search works)
- Permalink stability (issue # never changes)
**How to follow:**
1. Check if issue exists
2. If not → create issue first
3. Link issue # in wish front-matter
4. Link issue # in Forge task
5. Close issue when PR merges
**Enforcement:**
- wish.md blocks creation without issue
- review.md validates issue link exists
- Meta-learn tracks violations
**Status:** Active behavioral rule (all future wishes must follow)
**Violation handling:** BLOCK + route to issue creation
**Framework impact:** CRITICAL - enables public visibility + audit trail
**Remember:** GitHub is source of truth. Wishes are implementation plans. Forge tasks are execution. All three MUST link together.