docs: update PlantUML diagrams for multi-provider fallback and regex marker extraction
- Updated commit-workflow.puml to show claude→codex→gemini fallback chain - Updated patcher-pipeline.puml with provider fallback logic and model hints - Updated voting-system.puml for multi-stage promotions (READY_FOR_DESIGN) - Created ai-provider-fallback.puml documenting provider chain in detail - Created discussion-stages.puml showing complete feature lifecycle - Created workflow-marker-extraction.puml documenting regex patterns - Updated diagrams-README.md with all new diagrams and workflows - Increased diagram count from 7 to 10 total - All diagrams now reflect current system architecture 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
0601117371
commit
038dbe8a3e
|
|
@ -0,0 +1,163 @@
|
|||
@startuml ai-provider-fallback
|
||||
!theme plain
|
||||
title AI Provider Fallback Chain with Model Hints
|
||||
|
||||
start
|
||||
|
||||
:Automation needs AI generation\n(from patcher.py or runner.py);
|
||||
|
||||
:Read config/ai.yml;
|
||||
|
||||
if (Rule has model_hint?) then (yes)
|
||||
if (model_hint == "fast"?) then (yes)
|
||||
:Use **command_chain_fast**:
|
||||
- claude -p (→ Haiku subagent)
|
||||
- codex --model gpt-5-mini
|
||||
- gemini --model gemini-2.5-flash;
|
||||
else if (model_hint == "quality"?) then (yes)
|
||||
:Use **command_chain_quality**:
|
||||
- claude -p (→ Sonnet subagent)
|
||||
- codex --model o3
|
||||
- gemini --model gemini-2.5-pro;
|
||||
else (unknown hint)
|
||||
:Fall back to default chain;
|
||||
endif
|
||||
else (no hint)
|
||||
:Use **command_chain** (default):
|
||||
- claude -p (→ auto-select subagent)
|
||||
- codex --model gpt-5
|
||||
- gemini --model gemini-2.5-flash;
|
||||
endif
|
||||
|
||||
partition "Provider Loop" {
|
||||
:Get next provider from chain;
|
||||
|
||||
if (Provider == "claude"?) then (yes)
|
||||
:Execute: **claude -p**;
|
||||
note right
|
||||
Claude CLI uses TASK COMPLEXITY hint
|
||||
from prompt to select subagent:
|
||||
- FAST → cdev-patch (Haiku)
|
||||
- QUALITY → cdev-patch-quality (Sonnet)
|
||||
- Default → auto-select
|
||||
end note
|
||||
|
||||
if (Returned output?) then (yes)
|
||||
if (Contains diff markers?) then (yes)
|
||||
:✓ Success! Extract diff;
|
||||
stop
|
||||
else (no - non-diff response)
|
||||
:Log: "Claude non-diff output";
|
||||
:Try next provider;
|
||||
endif
|
||||
else (command failed)
|
||||
:Log: "Claude command failed";
|
||||
:Try next provider;
|
||||
endif
|
||||
|
||||
else if (Provider == "codex"?) then (yes)
|
||||
:Execute: **codex exec --model X --json -**;
|
||||
note right
|
||||
Codex requires special handling:
|
||||
- Add "exec" subcommand
|
||||
- Add "--json" flag
|
||||
- Add "--color=never"
|
||||
- Add "-" to read from stdin
|
||||
- Parse JSON output for agent_message
|
||||
end note
|
||||
|
||||
if (Exit code == 0?) then (yes)
|
||||
:Parse JSON lines;
|
||||
:Extract agent_message text;
|
||||
|
||||
if (Contains diff?) then (yes)
|
||||
:✓ Success! Extract diff;
|
||||
stop
|
||||
else (no diff)
|
||||
:Log: "Codex no diff output";
|
||||
:Try next provider;
|
||||
endif
|
||||
else (exit code 1)
|
||||
:Log: "Codex exited with 1";
|
||||
:Try next provider;
|
||||
endif
|
||||
|
||||
else if (Provider == "gemini"?) then (yes)
|
||||
:Execute: **gemini --model X**;
|
||||
note right
|
||||
Gemini is the most reliable fallback:
|
||||
- Accepts plain text input
|
||||
- Returns consistent output
|
||||
- Supports sentinel token
|
||||
end note
|
||||
|
||||
if (Returned output?) then (yes)
|
||||
if (Output == sentinel token?) then (yes)
|
||||
:Log: "No changes needed";
|
||||
:Return empty (intentional);
|
||||
stop
|
||||
else if (Contains diff?) then (yes)
|
||||
:✓ Success! Extract diff;
|
||||
stop
|
||||
else (no diff)
|
||||
:Log: "Gemini no diff output";
|
||||
:Try next provider;
|
||||
endif
|
||||
else (command failed)
|
||||
:Log: "Gemini command failed";
|
||||
:Try next provider;
|
||||
endif
|
||||
endif
|
||||
|
||||
if (More providers in chain?) then (yes)
|
||||
:Continue loop;
|
||||
else (no)
|
||||
:✗ All providers failed;
|
||||
:Raise PatchGenerationError;
|
||||
stop
|
||||
endif
|
||||
}
|
||||
|
||||
stop
|
||||
|
||||
legend bottom
|
||||
**Configuration Example (config/ai.yml):**
|
||||
|
||||
runner:
|
||||
command_chain:
|
||||
- "claude -p"
|
||||
- "codex --model gpt-5"
|
||||
- "gemini --model gemini-2.5-flash"
|
||||
|
||||
command_chain_fast:
|
||||
- "claude -p"
|
||||
- "codex --model gpt-5-mini"
|
||||
- "gemini --model gemini-2.5-flash"
|
||||
|
||||
command_chain_quality:
|
||||
- "claude -p"
|
||||
- "codex --model o3"
|
||||
- "gemini --model gemini-2.5-pro"
|
||||
|
||||
sentinel: "CASCADINGDEV_NO_CHANGES"
|
||||
|
||||
**Environment Override:**
|
||||
export CDEV_AI_COMMAND="claude -p || gemini --model gemini-2.5-pro"
|
||||
(Overrides config.yml for this commit only)
|
||||
endlegend
|
||||
|
||||
note right
|
||||
**Why Fallback Chain?**
|
||||
|
||||
1. **Redundancy**: Rate limits, API outages
|
||||
2. **Model specialization**: Different models excel at different tasks
|
||||
3. **Cost optimization**: Try cheaper models first
|
||||
4. **Quality assurance**: Fast models for simple tasks, quality for complex
|
||||
|
||||
**Observed Behavior:**
|
||||
- Claude occasionally returns non-diff output
|
||||
- Codex consistently exits with code 1 (auth issues?)
|
||||
- Gemini is the most reliable fallback
|
||||
end note
|
||||
|
||||
@enduml
|
||||
|
|
@ -8,7 +8,10 @@ participant "pre-commit hook" as hook
|
|||
participant "runner.py" as runner
|
||||
participant "config.py" as config
|
||||
participant "patcher.py" as patcher
|
||||
participant "Claude API" as claude
|
||||
participant "AI Providers" as ai
|
||||
participant "Claude CLI" as claude
|
||||
participant "Codex CLI" as codex
|
||||
participant "Gemini CLI" as gemini
|
||||
participant "workflow.py" as workflow
|
||||
database ".git index" as index
|
||||
|
||||
|
|
@ -35,22 +38,57 @@ loop For each staged file
|
|||
activate patcher
|
||||
|
||||
patcher -> patcher: Build prompt with\nsource diff + context
|
||||
patcher -> claude: Send prompt
|
||||
|
||||
patcher -> ai: Try provider 1/3
|
||||
activate ai
|
||||
ai -> claude: Send prompt
|
||||
activate claude
|
||||
|
||||
alt API Success
|
||||
claude -> patcher: Return unified diff\n(wrapped in markers)
|
||||
alt Claude produces diff
|
||||
claude -> ai: Return unified diff\n(wrapped in markers)
|
||||
ai -> patcher: Success with diff
|
||||
deactivate claude
|
||||
deactivate ai
|
||||
patcher -> patcher: Extract & sanitize patch
|
||||
patcher -> patcher: git apply --3way
|
||||
patcher -> index: Stage generated file
|
||||
patcher -> runner: Success
|
||||
else API Overload/Error
|
||||
claude -> patcher: Error response
|
||||
patcher -> patcher: Log error to stderr
|
||||
patcher -> runner: Skip this file
|
||||
else Claude non-diff output
|
||||
claude -> ai: Non-diff response
|
||||
deactivate claude
|
||||
ai -> codex: Try provider 2/3
|
||||
activate codex
|
||||
|
||||
alt Codex succeeds
|
||||
codex -> ai: Return diff (JSON parsed)
|
||||
deactivate codex
|
||||
deactivate ai
|
||||
patcher -> patcher: Extract & sanitize
|
||||
patcher -> index: Stage file
|
||||
patcher -> runner: Success
|
||||
else Codex fails (exit 1)
|
||||
codex -> ai: Exit code 1
|
||||
deactivate codex
|
||||
ai -> gemini: Try provider 3/3
|
||||
activate gemini
|
||||
|
||||
alt Gemini succeeds
|
||||
gemini -> ai: Return diff
|
||||
deactivate gemini
|
||||
deactivate ai
|
||||
patcher -> patcher: Extract & sanitize
|
||||
patcher -> index: Stage file
|
||||
patcher -> runner: Success
|
||||
else All providers failed
|
||||
gemini -> ai: Error/no diff
|
||||
deactivate gemini
|
||||
deactivate ai
|
||||
patcher -> patcher: Log error to stderr
|
||||
patcher -> runner: Skip this file
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
deactivate claude
|
||||
deactivate patcher
|
||||
end
|
||||
|
||||
|
|
@ -73,15 +111,38 @@ git -> index: Create commit
|
|||
git -> Developer: Commit successful
|
||||
deactivate git
|
||||
|
||||
note right of ai
|
||||
**Multi-Provider Fallback Chain**
|
||||
Configured in config/ai.yml:
|
||||
1. claude -p (Claude CLI with subagent)
|
||||
2. codex exec --model gpt-5 --json
|
||||
3. gemini --model gemini-2.5-flash
|
||||
|
||||
Each provider tried until one succeeds.
|
||||
Provides redundancy against:
|
||||
- Rate limits
|
||||
- API outages
|
||||
- Non-diff responses
|
||||
end note
|
||||
|
||||
note right of patcher
|
||||
Saves debug artifacts to
|
||||
.git/ai-rules-debug/
|
||||
for troubleshooting
|
||||
for troubleshooting:
|
||||
- *.raw.out
|
||||
- *.clean.diff
|
||||
- *.sanitized.diff
|
||||
- *.final.diff
|
||||
end note
|
||||
|
||||
note right of workflow
|
||||
Always exits 0
|
||||
(non-blocking)
|
||||
|
||||
Extracts structured markers:
|
||||
- **DECISION**: text
|
||||
- **QUESTION**: text
|
||||
- **ACTION**: @assignee text
|
||||
end note
|
||||
|
||||
@enduml
|
||||
|
|
|
|||
|
|
@ -39,18 +39,18 @@ plantuml -tsvg docs/*.puml
|
|||
|
||||
---
|
||||
|
||||
### 2. **commit-workflow.puml**
|
||||
**Sequence diagram** of what happens during `git commit`.
|
||||
### 2. **commit-workflow.puml** ⭐ UPDATED
|
||||
**Sequence diagram** of what happens during `git commit` with multi-provider fallback.
|
||||
|
||||
**Shows:**
|
||||
- Pre-commit hook execution
|
||||
- runner.py orchestration
|
||||
- AI API calls
|
||||
- Multi-provider AI fallback (claude → codex → gemini)
|
||||
- Patch generation and application
|
||||
- Vote processing
|
||||
- Vote processing with marker extraction
|
||||
- File staging
|
||||
|
||||
**Best for:** Understanding the complete commit-time automation flow.
|
||||
**Best for:** Understanding the complete commit-time automation flow with provider redundancy.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -67,33 +67,34 @@ plantuml -tsvg docs/*.puml
|
|||
|
||||
---
|
||||
|
||||
### 4. **patcher-pipeline.puml**
|
||||
**Detailed flowchart** of AI patch generation and application.
|
||||
### 4. **patcher-pipeline.puml** ⭐ UPDATED
|
||||
**Detailed flowchart** of AI patch generation and application with provider fallback.
|
||||
|
||||
**Shows:**
|
||||
- Prompt building
|
||||
- AI command execution
|
||||
- Prompt building with model hints
|
||||
- Multi-provider fallback logic (claude → codex → gemini)
|
||||
- Codex JSON parsing
|
||||
- Patch extraction (with markers)
|
||||
- Patch sanitization
|
||||
- git apply strategies (strict → 3-way → fallback)
|
||||
- Debug artifact saving
|
||||
- Error handling
|
||||
|
||||
**Best for:** Debugging patch application issues or understanding the AI integration.
|
||||
**Best for:** Debugging patch application issues or understanding the AI provider chain.
|
||||
|
||||
---
|
||||
|
||||
### 5. **voting-system.puml**
|
||||
**Voting and promotion logic** for feature discussions.
|
||||
### 5. **voting-system.puml** ⭐ UPDATED
|
||||
**Voting and promotion logic** for multi-stage feature discussions.
|
||||
|
||||
**Shows:**
|
||||
- Vote parsing from discussion files
|
||||
- Eligible voter calculation
|
||||
- Promotion thresholds (READY_FOR_IMPLEMENTATION)
|
||||
- Rejection logic
|
||||
- Stage-specific promotion thresholds (READY_FOR_DESIGN, READY_FOR_IMPLEMENTATION, etc.)
|
||||
- Rejection logic per stage
|
||||
- Summary file updates
|
||||
|
||||
**Best for:** Understanding how features move through approval stages.
|
||||
**Best for:** Understanding how features move through multi-stage approval (feature → design → implementation → review).
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -125,20 +126,72 @@ plantuml -tsvg docs/*.puml
|
|||
|
||||
---
|
||||
|
||||
### 8. **ai-provider-fallback.puml** 🆕
|
||||
**Detailed flowchart** of the multi-provider AI fallback chain with model hints.
|
||||
|
||||
**Shows:**
|
||||
- Command chain selection (default, fast, quality)
|
||||
- Model hint propagation (TASK COMPLEXITY)
|
||||
- Provider-specific execution (Claude CLI, Codex JSON, Gemini)
|
||||
- Fallback logic (claude → codex → gemini)
|
||||
- Sentinel token handling
|
||||
- Error handling per provider
|
||||
|
||||
**Best for:** Understanding how AI provider redundancy works and debugging provider failures.
|
||||
|
||||
---
|
||||
|
||||
### 9. **discussion-stages.puml** 🆕
|
||||
**State machine diagram** showing the complete feature discussion lifecycle through all stages.
|
||||
|
||||
**Shows:**
|
||||
- Feature stage (OPEN → READY_FOR_DESIGN)
|
||||
- Design stage (OPEN → READY_FOR_IMPLEMENTATION)
|
||||
- Implementation stage (IN_PROGRESS → READY_FOR_REVIEW)
|
||||
- Review stage (UNDER_REVIEW → APPROVED)
|
||||
- Status transitions and promotion conditions
|
||||
- Auto-generated files per stage
|
||||
|
||||
**Best for:** Understanding the full feature approval workflow from request to merge.
|
||||
|
||||
---
|
||||
|
||||
### 10. **workflow-marker-extraction.puml** 🆕
|
||||
**Detailed flowchart** of regex-based marker extraction from discussion files.
|
||||
|
||||
**Shows:**
|
||||
- Comment parsing from discussion files
|
||||
- Regex pattern matching for **DECISION**, **QUESTION**, **ACTION**
|
||||
- Support for both plain (DECISION:) and markdown bold (**DECISION**:) formats
|
||||
- Structured data extraction
|
||||
- Summary section generation
|
||||
- Marker block updates in .sum.md files
|
||||
|
||||
**Best for:** Understanding how structured markers are extracted and why regex was chosen over line-start matching.
|
||||
|
||||
---
|
||||
|
||||
## Key Concepts Illustrated
|
||||
|
||||
### Automation Pipeline
|
||||
```
|
||||
Developer commits → Pre-commit hook → runner.py → patcher.py → Claude API
|
||||
→ config.py → .ai-rules.yml
|
||||
Developer commits → Pre-commit hook → runner.py → patcher.py → Multi-Provider AI
|
||||
→ config.py → .ai-rules.yml (claude → codex → gemini)
|
||||
→ workflow.py → summary.py
|
||||
(regex marker extraction)
|
||||
```
|
||||
|
||||
### File Processing
|
||||
### File Processing (Multi-Stage)
|
||||
```
|
||||
request.md (edited) → AI generates → feature.discussion.md (created/updated)
|
||||
→ feature.discussion.sum.md (updated)
|
||||
→ implementation.discussion.md (gated)
|
||||
↓ (votes → READY_FOR_DESIGN)
|
||||
→ design.discussion.md (created)
|
||||
→ design.discussion.sum.md (updated)
|
||||
↓ (votes → READY_FOR_IMPLEMENTATION)
|
||||
→ implementation.discussion.md (created)
|
||||
↓ (votes → READY_FOR_REVIEW)
|
||||
→ review.discussion.md (created)
|
||||
```
|
||||
|
||||
### Voting Flow
|
||||
|
|
@ -171,9 +224,21 @@ Patch fails → Save debug artifacts → Log error → Continue
|
|||
3. Review **commit-workflow.puml** for execution order
|
||||
|
||||
### Understanding Status Transitions
|
||||
1. See **voting-system.puml** for promotion logic
|
||||
2. Check **file-lifecycle.puml** for state machine
|
||||
3. Review discussion file YAML headers for thresholds
|
||||
1. See **discussion-stages.puml** for complete multi-stage flow
|
||||
2. See **voting-system.puml** for promotion logic per stage
|
||||
3. Check **file-lifecycle.puml** for developer workflow
|
||||
4. Review discussion file YAML headers for thresholds
|
||||
|
||||
### Understanding AI Provider System
|
||||
1. See **ai-provider-fallback.puml** for provider chain logic
|
||||
2. Check **patcher-pipeline.puml** for integration details
|
||||
3. Review config/ai.yml for command configuration
|
||||
4. Check .git/ai-rules-debug/ for provider outputs
|
||||
|
||||
### Understanding Marker Extraction
|
||||
1. See **workflow-marker-extraction.puml** for regex patterns
|
||||
2. Review automation/workflow.py for implementation
|
||||
3. Test with **DECISION**, **QUESTION**, **ACTION** markers in discussions
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -183,8 +248,12 @@ Patch fails → Save debug artifacts → Log error → Continue
|
|||
|---------|--------|---------|
|
||||
| Cascading Rules | ✅ Complete | cascading-rules.puml |
|
||||
| AI Patch Generation | ✅ Complete | patcher-pipeline.puml |
|
||||
| Multi-Provider Fallback | ✅ Complete | ai-provider-fallback.puml |
|
||||
| Model Hints (fast/quality) | ✅ Complete | ai-provider-fallback.puml |
|
||||
| Vote Tracking | ✅ Complete | voting-system.puml |
|
||||
| Promotion Logic | ✅ Complete | voting-system.puml |
|
||||
| Multi-Stage Promotion | ✅ Complete | discussion-stages.puml |
|
||||
| Regex Marker Extraction | ✅ Complete | workflow-marker-extraction.puml |
|
||||
| Structured Summaries | ✅ Complete | workflow-marker-extraction.puml |
|
||||
| Implementation Gate | ✅ Complete | file-lifecycle.puml |
|
||||
| Error Handling | ✅ Complete | commit-workflow.puml |
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,148 @@
|
|||
@startuml discussion-stages
|
||||
!theme plain
|
||||
title Feature Discussion Stage Progression with Status Transitions
|
||||
|
||||
state "Feature Stage" as feature {
|
||||
[*] --> OPEN_F : feature.discussion.md created
|
||||
|
||||
OPEN_F : status: OPEN
|
||||
OPEN_F : Participants discuss scope,\nplatform, requirements
|
||||
|
||||
OPEN_F --> READY_FOR_DESIGN : ≥2 READY votes\n(human only if\nallow_agent_votes: false)
|
||||
|
||||
READY_FOR_DESIGN : status: READY_FOR_DESIGN
|
||||
READY_FOR_DESIGN : Scope approved,\nready for technical design
|
||||
|
||||
READY_FOR_DESIGN --> FEATURE_REJECTED : Majority REJECT votes
|
||||
FEATURE_REJECTED : status: FEATURE_REJECTED
|
||||
FEATURE_REJECTED : Feature blocked
|
||||
|
||||
note right of READY_FOR_DESIGN
|
||||
**AI Auto-generates:**
|
||||
design.discussion.md
|
||||
(Initial design proposal)
|
||||
end note
|
||||
}
|
||||
|
||||
state "Design Stage" as design {
|
||||
[*] --> OPEN_D : design.discussion.md created
|
||||
|
||||
OPEN_D : status: OPEN
|
||||
OPEN_D : Discuss architecture,\ntech stack, data models
|
||||
|
||||
OPEN_D --> READY_FOR_IMPLEMENTATION : ≥2 READY votes
|
||||
READY_FOR_IMPLEMENTATION : status: READY_FOR_IMPLEMENTATION
|
||||
READY_FOR_IMPLEMENTATION : Design approved,\nready to implement
|
||||
|
||||
OPEN_D --> DESIGN_REJECTED : Majority REJECT votes
|
||||
DESIGN_REJECTED : status: DESIGN_REJECTED
|
||||
DESIGN_REJECTED : Design needs rework
|
||||
|
||||
note right of READY_FOR_IMPLEMENTATION
|
||||
**AI Auto-generates:**
|
||||
implementation.discussion.md
|
||||
(Implementation tracking)
|
||||
end note
|
||||
}
|
||||
|
||||
state "Implementation Stage" as impl {
|
||||
[*] --> IN_PROGRESS : implementation.discussion.md created
|
||||
|
||||
IN_PROGRESS : status: IN_PROGRESS
|
||||
IN_PROGRESS : Track tasks,\ncode progress,\nblocking issues
|
||||
|
||||
IN_PROGRESS --> READY_FOR_REVIEW : All tasks completed\n≥2 READY votes
|
||||
|
||||
READY_FOR_REVIEW : status: READY_FOR_REVIEW
|
||||
READY_FOR_REVIEW : Implementation complete
|
||||
|
||||
note right of READY_FOR_REVIEW
|
||||
**AI Auto-generates:**
|
||||
review.discussion.md
|
||||
(Code review tracking)
|
||||
end note
|
||||
}
|
||||
|
||||
state "Review Stage" as review {
|
||||
[*] --> UNDER_REVIEW : review.discussion.md created
|
||||
|
||||
UNDER_REVIEW : status: UNDER_REVIEW
|
||||
UNDER_REVIEW : Code review,\ntesting, QA
|
||||
|
||||
UNDER_REVIEW --> APPROVED : ≥2 READY votes
|
||||
UNDER_REVIEW --> NEEDS_CHANGES : CHANGES votes
|
||||
|
||||
APPROVED : status: APPROVED
|
||||
APPROVED : Ready to merge
|
||||
|
||||
NEEDS_CHANGES --> UNDER_REVIEW : Changes addressed
|
||||
}
|
||||
|
||||
[*] --> feature
|
||||
READY_FOR_DESIGN --> design
|
||||
READY_FOR_IMPLEMENTATION --> impl
|
||||
READY_FOR_REVIEW --> review
|
||||
APPROVED --> [*]
|
||||
|
||||
legend bottom
|
||||
**Vote Counting Rules (Configured per stage):**
|
||||
|
||||
promotion_rule:
|
||||
allow_agent_votes: false # Only count human votes
|
||||
ready_min_eligible_votes: 2 # Need 2 READY to promote
|
||||
reject_min_eligible_votes: 1 # Need 1 REJECT to block
|
||||
|
||||
**Vote Format in Discussion Files:**
|
||||
ParticipantName: Comment text. VOTE: READY|CHANGES|REJECT
|
||||
AI_BotName: Comment text. VOTE: CHANGES (excluded if allow_agent_votes: false)
|
||||
|
||||
**Status Transitions:**
|
||||
- Automatic when vote thresholds met
|
||||
- AI updates YAML header: status: field
|
||||
- AI appends consensus comment
|
||||
- Triggers next stage discussion creation
|
||||
|
||||
**Example Progression:**
|
||||
1. Feature discussion: Define WHAT we're building
|
||||
2. Design discussion: Define HOW we'll build it
|
||||
3. Implementation discussion: Track building progress
|
||||
4. Review discussion: Verify quality before merge
|
||||
endlegend
|
||||
|
||||
note right of feature
|
||||
**Participants Use Structured Markers:**
|
||||
**DECISION**: Web platform, React frontend
|
||||
**QUESTION**: Mobile support in MVP?
|
||||
**ACTION**: @Alice research auth options
|
||||
|
||||
These are extracted to .sum.md files
|
||||
for easy reference
|
||||
end note
|
||||
|
||||
note right of design
|
||||
**Design Decisions Tracked:**
|
||||
- Architecture choices
|
||||
- Technology stack
|
||||
- Data models
|
||||
- API contracts
|
||||
- Risk trade-offs
|
||||
end note
|
||||
|
||||
note right of impl
|
||||
**Implementation Tracking:**
|
||||
- Task breakdowns
|
||||
- Blocking issues
|
||||
- Progress updates
|
||||
- Code references
|
||||
end note
|
||||
|
||||
note right of review
|
||||
**Review Checklist:**
|
||||
- Code quality
|
||||
- Test coverage
|
||||
- Documentation
|
||||
- Performance
|
||||
- Security
|
||||
end note
|
||||
|
||||
@enduml
|
||||
|
|
@ -10,32 +10,66 @@ start
|
|||
- Source file diff (staged changes)
|
||||
- Source file full content
|
||||
- Target file current content
|
||||
- Generation instructions from rules;
|
||||
- Generation instructions from rules
|
||||
- Model hint (fast/quality) if specified;
|
||||
|
||||
:Call AI via shell command
|
||||
(configured via git config or env);
|
||||
partition "Multi-Provider Fallback" {
|
||||
:Try Provider 1: Claude CLI;
|
||||
|
||||
if (AI returned output?) then (yes)
|
||||
if (Output contains\n"API Error: Overloaded"?) then (yes)
|
||||
:Raise PatchGenerationError\n"Claude API is overloaded";
|
||||
stop
|
||||
endif
|
||||
|
||||
:Save raw output to\n.git/ai-rules-debug/*.raw.out;
|
||||
|
||||
if (Output contains\n<<<AI_DIFF_START>>>?) then (yes)
|
||||
:Extract content between\nSTART and END markers;
|
||||
else (no)
|
||||
if (Output contains\n"diff --git"?) then (yes)
|
||||
:Extract from\n"diff --git" onward;
|
||||
else (no)
|
||||
:Raise "AI output did not contain a diff";
|
||||
if (Output contains\n"API Error: Overloaded"?) then (yes)
|
||||
:Raise PatchGenerationError\n"Claude API is overloaded";
|
||||
stop
|
||||
endif
|
||||
|
||||
if (Output contains diff markers?) then (yes)
|
||||
:Success! Continue to extraction;
|
||||
else (no - non-diff response)
|
||||
:Log: "Claude non-diff output";
|
||||
:Try Provider 2: Codex CLI;
|
||||
|
||||
if (Codex returned output?) then (yes)
|
||||
:Parse JSON response\nextract agent_message;
|
||||
|
||||
if (Parsed text contains diff?) then (yes)
|
||||
:Success! Continue to extraction;
|
||||
else (no - exit code 1)
|
||||
:Log: "Codex exited with 1";
|
||||
:Try Provider 3: Gemini CLI;
|
||||
|
||||
if (Gemini returned output?) then (yes)
|
||||
if (Gemini returned sentinel?) then (yes)
|
||||
:Log: "No changes needed";
|
||||
stop
|
||||
else (has diff)
|
||||
:Success! Continue to extraction;
|
||||
endif
|
||||
else (no)
|
||||
:Raise "All providers failed";
|
||||
stop
|
||||
endif
|
||||
endif
|
||||
else (no)
|
||||
:Raise "All providers failed";
|
||||
stop
|
||||
endif
|
||||
endif
|
||||
else (no - command failed)
|
||||
:Raise "Provider 1 command failed";
|
||||
stop
|
||||
endif
|
||||
}
|
||||
|
||||
:Save raw output to\n.git/ai-rules-debug/*.raw.out;
|
||||
|
||||
if (Output contains\n<<<AI_DIFF_START>>>?) then (yes)
|
||||
:Extract content between\nSTART and END markers;
|
||||
else (no)
|
||||
:Raise "AI command failed";
|
||||
stop
|
||||
if (Output contains\n"diff --git"?) then (yes)
|
||||
:Extract from\n"diff --git" onward;
|
||||
else (no)
|
||||
:Raise "AI output did not contain a diff";
|
||||
stop
|
||||
endif
|
||||
endif
|
||||
|
||||
:Save to *.clean.diff;
|
||||
|
|
@ -87,6 +121,17 @@ endif
|
|||
stop
|
||||
|
||||
note right
|
||||
**AI Provider Configuration:**
|
||||
config/ai.yml defines fallback chains:
|
||||
- command_chain (default)
|
||||
- command_chain_fast (model_hint: fast)
|
||||
- command_chain_quality (model_hint: quality)
|
||||
|
||||
**Provider Details:**
|
||||
1. Claude: claude -p (auto-selects subagent)
|
||||
2. Codex: codex exec --model gpt-5 --json
|
||||
3. Gemini: gemini --model gemini-2.5-flash
|
||||
|
||||
**Debug Artifacts Location:**
|
||||
.git/ai-rules-debug/
|
||||
|
||||
|
|
|
|||
|
|
@ -44,15 +44,28 @@ partition "Promotion Logic (AI-powered)" {
|
|||
:Count CHANGES votes (neutral);
|
||||
|
||||
if (READY threshold met AND\nREJECT threshold NOT met?) then (yes)
|
||||
:Update status to\n**READY_FOR_IMPLEMENTATION**;
|
||||
|
||||
if (implementation_gate output defined?) then (yes)
|
||||
if (Current stage == feature?) then (yes)
|
||||
:Update status to\n**READY_FOR_DESIGN**;
|
||||
:AI generates\ndesign.discussion.md;
|
||||
else if (Current stage == design?) then (yes)
|
||||
:Update status to\n**READY_FOR_IMPLEMENTATION**;
|
||||
:AI generates\nimplementation.discussion.md;
|
||||
else if (Current stage == implementation?) then (yes)
|
||||
:Update status to\n**READY_FOR_REVIEW**;
|
||||
:AI generates\nreview.discussion.md;
|
||||
else (review stage)
|
||||
:Update status to\n**APPROVED**;
|
||||
endif
|
||||
else if (REJECT threshold met AND\nREADY threshold NOT met?) then (no)
|
||||
:Update status to\n**FEATURE_REJECTED**;
|
||||
if (Current stage == feature?) then (yes)
|
||||
:Update status to\n**FEATURE_REJECTED**;
|
||||
else if (Current stage == design?) then (yes)
|
||||
:Update status to\n**DESIGN_REJECTED**;
|
||||
else (other stages)
|
||||
:Update status to\n**NEEDS_CHANGES**;
|
||||
endif
|
||||
else (no)
|
||||
:Keep status as **OPEN**;
|
||||
:Keep status as **OPEN** or **UNDER_REVIEW**;
|
||||
endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,208 @@
|
|||
@startuml workflow-marker-extraction
|
||||
!theme plain
|
||||
title Workflow Marker Extraction with Regex Pattern Matching
|
||||
|
||||
start
|
||||
|
||||
:Discussion file staged\n(feature.discussion.md,\ndesign.discussion.md, etc);
|
||||
|
||||
:workflow.py reads file content;
|
||||
|
||||
partition "Parse Comments" {
|
||||
:Split file into lines;
|
||||
|
||||
repeat
|
||||
:Read next line;
|
||||
|
||||
if (Line is HTML comment?) then (yes)
|
||||
:Skip (metadata);
|
||||
else if (Line is heading?) then (yes)
|
||||
:Skip (structure);
|
||||
else (participant comment)
|
||||
:Extract participant name\n(before first ":");
|
||||
|
||||
note right
|
||||
**Participant Format:**
|
||||
- Rob: Comment text...
|
||||
- Sarah: Comment text...
|
||||
- AI_Claude: Comment text...
|
||||
|
||||
Names starting with "AI_"
|
||||
are excluded from voting if
|
||||
allow_agent_votes: false
|
||||
end note
|
||||
|
||||
partition "Extract Structured Markers" {
|
||||
:Apply regex patterns\nto comment text;
|
||||
|
||||
if (**DECISION**: found?) then (yes)
|
||||
:Pattern: (?:\\*\\*)?DECISION(?:\\*\\*)?\n\\s*:\\s*(.+?)(?=\\*\\*|VOTE:|$);
|
||||
:Extract decision text;
|
||||
:Store: {
|
||||
participant: "Rob",
|
||||
decision: "text...",
|
||||
rationale: "",
|
||||
supporters: []
|
||||
};
|
||||
endif
|
||||
|
||||
if (**QUESTION**: found?) then (yes)
|
||||
:Pattern: (?:\\*\\*)?(?:QUESTION|Q)(?:\\*\\*)?\n\\s*:\\s*(.+?)(?=\\*\\*|VOTE:|$);
|
||||
:Extract question text;
|
||||
:Store: {
|
||||
participant: "Rob",
|
||||
question: "text...",
|
||||
status: "OPEN"
|
||||
};
|
||||
endif
|
||||
|
||||
if (**ACTION**: found?) then (yes)
|
||||
:Pattern: (?:\\*\\*)?(?:ACTION|TODO)(?:\\*\\*)?\n\\s*:\\s*(.+?)(?=\\*\\*|VOTE:|$);
|
||||
:Extract action text;
|
||||
:Search for @mention in text;
|
||||
:Store: {
|
||||
participant: "Rob",
|
||||
action: "text...",
|
||||
assignee: "Sarah",
|
||||
status: "TODO"
|
||||
};
|
||||
endif
|
||||
|
||||
if (Line ends with "?") then (yes)
|
||||
:Auto-detect as question;
|
||||
note right
|
||||
Fallback heuristic:
|
||||
If no explicit marker but
|
||||
line ends with "?",
|
||||
treat as question
|
||||
end note
|
||||
endif
|
||||
|
||||
if (@mention found?) then (yes)
|
||||
:Extract @mentions;
|
||||
:Store in "Awaiting Replies" list;
|
||||
endif
|
||||
}
|
||||
|
||||
if (VOTE: line found?) then (yes)
|
||||
:Extract vote value:\nREADY|CHANGES|REJECT;
|
||||
:Store latest vote per participant;
|
||||
endif
|
||||
endif
|
||||
|
||||
repeat while (More lines?) is (yes)
|
||||
-> no;
|
||||
}
|
||||
|
||||
partition "Generate Summary Sections" {
|
||||
:Format Decisions section:
|
||||
- Group by participant
|
||||
- Number sequentially
|
||||
- Include rationale if present;
|
||||
|
||||
:Format Open Questions section:
|
||||
- List unanswered questions
|
||||
- Track by participant
|
||||
- Mark status (OPEN/PARTIAL);
|
||||
|
||||
:Format Action Items section:
|
||||
- Group by status (TODO/ASSIGNED/DONE)
|
||||
- Show assignees
|
||||
- Link to requesters;
|
||||
|
||||
:Format Awaiting Replies section:
|
||||
- Group by @mentioned person
|
||||
- Show context of request
|
||||
- Track unresolved mentions;
|
||||
|
||||
:Format Votes section:
|
||||
- Count by value (READY/CHANGES/REJECT)
|
||||
- List latest vote per participant
|
||||
- Exclude AI votes if configured;
|
||||
|
||||
:Format Timeline section:
|
||||
- Chronological order (newest first)
|
||||
- Include status changes
|
||||
- Summarize key events;
|
||||
}
|
||||
|
||||
:Update marker blocks in .sum.md:
|
||||
<!-- SUMMARY:DECISIONS START -->
|
||||
...
|
||||
<!-- SUMMARY:DECISIONS END -->;
|
||||
|
||||
:Stage updated .sum.md file;
|
||||
|
||||
stop
|
||||
|
||||
legend bottom
|
||||
**Example Input (feature.discussion.md):**
|
||||
|
||||
Rob: The architecture looks solid. **DECISION**: We'll use PostgreSQL
|
||||
for the database. **QUESTION**: Should we use TypeScript or JavaScript?
|
||||
**ACTION**: @Sarah please research auth libraries. Looking forward to
|
||||
feedback. VOTE: CHANGES
|
||||
|
||||
**Extracted Output (.sum.md):**
|
||||
|
||||
<!-- SUMMARY:DECISIONS START -->
|
||||
## Decisions (ADR-style)
|
||||
### Decision 1: We'll use PostgreSQL for the database.
|
||||
- **Proposed by:** @Rob
|
||||
<!-- SUMMARY:DECISIONS END -->
|
||||
|
||||
<!-- SUMMARY:OPEN_QUESTIONS START -->
|
||||
## Open Questions
|
||||
- @Rob: Should we use TypeScript or JavaScript?
|
||||
<!-- SUMMARY:OPEN_QUESTIONS END -->
|
||||
|
||||
<!-- SUMMARY:ACTION_ITEMS START -->
|
||||
## Action Items
|
||||
### TODO (unassigned):
|
||||
- [ ] @Sarah please research auth libraries (suggested by @Rob)
|
||||
<!-- SUMMARY:ACTION_ITEMS END -->
|
||||
|
||||
<!-- SUMMARY:AWAITING START -->
|
||||
## Awaiting Replies
|
||||
### @Sarah
|
||||
- @Rob: ... **ACTION**: @Sarah please research auth libraries ...
|
||||
<!-- SUMMARY:AWAITING END -->
|
||||
endlegend
|
||||
|
||||
note right
|
||||
**Regex Pattern Details:**
|
||||
|
||||
**Decision Pattern:**
|
||||
(?:\\*\\*)?DECISION(?:\\*\\*)?\\s*:\\s*(.+?)
|
||||
(?=\\s*(?:\\*\\*QUESTION|\\*\\*ACTION|VOTE:)|$)
|
||||
|
||||
**Features:**
|
||||
- Case-insensitive
|
||||
- Optional markdown bold (**) on both sides
|
||||
- Captures text until next marker or VOTE:
|
||||
- DOTALL mode for multi-line capture
|
||||
|
||||
**Supported Formats:**
|
||||
- DECISION: text
|
||||
- **DECISION**: text
|
||||
- decision: text
|
||||
- **decision**: text
|
||||
end note
|
||||
|
||||
note right
|
||||
**Why Regex Instead of Line-Start Matching?**
|
||||
|
||||
✗ Old approach: `if line.startswith("decision:"):`
|
||||
Problem: Markers embedded mid-sentence fail
|
||||
|
||||
✓ New approach: Regex search anywhere in line
|
||||
Handles: "Good point. **DECISION**: We'll use X."
|
||||
|
||||
**Benefits:**
|
||||
- Natural conversational style
|
||||
- Markdown formatting preserved
|
||||
- Multiple markers per comment
|
||||
- Robust extraction
|
||||
end note
|
||||
|
||||
@enduml
|
||||
Loading…
Reference in New Issue