fix: accept bug_fix workflow_type alias during planning (#240)

* fix(planning): accept bug_fix workflow_type alias

* style(planning): ruff format

* fix: refatored common logic

* fix: remove ruff errors

* fix: remove duplicate _normalize_workflow_type method

Remove the incorrectly placed duplicate method inside ContextLoader class.
The module-level function is the correct implementation being used.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: danielfrey63 <daniel.frey@sbb.ch>
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
Co-authored-by: AndyMik90 <andre@mikalsenutvikling.no>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Daniel Frey
2025-12-25 19:53:55 +01:00
committed by GitHub
parent 6ac8250b5b
commit e74a3dffd2
2 changed files with 42 additions and 25 deletions
+33 -24
View File
@@ -11,6 +11,26 @@ from implementation_plan import WorkflowType
from .models import PlannerContext
def _normalize_workflow_type(value: str) -> str:
"""Normalize workflow type strings for consistent mapping.
Strips whitespace, lowercases the value and removes underscores so variants
like 'bug_fix' or 'BugFix' map to the same key.
"""
normalized = (value or "").strip().lower()
return normalized.replace("_", "")
_WORKFLOW_TYPE_MAPPING: dict[str, WorkflowType] = {
"feature": WorkflowType.FEATURE,
"refactor": WorkflowType.REFACTOR,
"investigation": WorkflowType.INVESTIGATION,
"migration": WorkflowType.MIGRATION,
"simple": WorkflowType.SIMPLE,
"bugfix": WorkflowType.INVESTIGATION,
}
class ContextLoader:
"""Loads context files and determines workflow type."""
@@ -64,13 +84,6 @@ class ContextLoader:
3. spec.md explicit declaration - Spec writer's declaration
4. Keyword-based detection - Last resort fallback
"""
type_mapping = {
"feature": WorkflowType.FEATURE,
"refactor": WorkflowType.REFACTOR,
"investigation": WorkflowType.INVESTIGATION,
"migration": WorkflowType.MIGRATION,
"simple": WorkflowType.SIMPLE,
}
# 1. Check requirements.json (user's explicit intent)
requirements_file = self.spec_dir / "requirements.json"
@@ -78,9 +91,11 @@ class ContextLoader:
try:
with open(requirements_file) as f:
requirements = json.load(f)
declared_type = requirements.get("workflow_type", "").lower()
if declared_type in type_mapping:
return type_mapping[declared_type]
declared_type = _normalize_workflow_type(
requirements.get("workflow_type", "")
)
if declared_type in _WORKFLOW_TYPE_MAPPING:
return _WORKFLOW_TYPE_MAPPING[declared_type]
except (json.JSONDecodeError, KeyError):
pass
@@ -90,9 +105,11 @@ class ContextLoader:
try:
with open(assessment_file) as f:
assessment = json.load(f)
declared_type = assessment.get("workflow_type", "").lower()
if declared_type in type_mapping:
return type_mapping[declared_type]
declared_type = _normalize_workflow_type(
assessment.get("workflow_type", "")
)
if declared_type in _WORKFLOW_TYPE_MAPPING:
return _WORKFLOW_TYPE_MAPPING[declared_type]
except (json.JSONDecodeError, KeyError):
pass
@@ -108,14 +125,6 @@ class ContextLoader:
"""
content_lower = spec_content.lower()
type_mapping = {
"feature": WorkflowType.FEATURE,
"refactor": WorkflowType.REFACTOR,
"investigation": WorkflowType.INVESTIGATION,
"migration": WorkflowType.MIGRATION,
"simple": WorkflowType.SIMPLE,
}
# Check for explicit workflow type declaration in spec
# Look for patterns like "**Type**: feature" or "Type: refactor"
explicit_type_patterns = [
@@ -127,9 +136,9 @@ class ContextLoader:
for pattern in explicit_type_patterns:
match = re.search(pattern, content_lower)
if match:
declared_type = match.group(1).strip()
if declared_type in type_mapping:
return type_mapping[declared_type]
declared_type = _normalize_workflow_type(match.group(1))
if declared_type in _WORKFLOW_TYPE_MAPPING:
return _WORKFLOW_TYPE_MAPPING[declared_type]
# FALLBACK: Keyword-based detection (only if no explicit type found)
# Investigation indicators
+9 -1
View File
@@ -21,7 +21,15 @@ IMPLEMENTATION_PLAN_SCHEMA = {
"workflow_rationale",
"status",
],
"workflow_types": ["feature", "refactor", "investigation", "migration", "simple"],
"workflow_types": [
"feature",
"refactor",
"investigation",
"migration",
"simple",
"bugfix",
"bug_fix",
],
"phase_schema": {
# Support both old format ("phase" number) and new format ("id" string)
"required_fields_either": [["phase", "id"]], # At least one of these