raise-cli 2.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- raise_cli/__init__.py +38 -0
- raise_cli/__main__.py +30 -0
- raise_cli/adapters/__init__.py +91 -0
- raise_cli/adapters/declarative/__init__.py +26 -0
- raise_cli/adapters/declarative/adapter.py +267 -0
- raise_cli/adapters/declarative/discovery.py +94 -0
- raise_cli/adapters/declarative/expressions.py +150 -0
- raise_cli/adapters/declarative/reference/__init__.py +1 -0
- raise_cli/adapters/declarative/reference/github.yaml +143 -0
- raise_cli/adapters/declarative/schema.py +98 -0
- raise_cli/adapters/filesystem.py +299 -0
- raise_cli/adapters/mcp_bridge.py +10 -0
- raise_cli/adapters/mcp_confluence.py +246 -0
- raise_cli/adapters/mcp_jira.py +405 -0
- raise_cli/adapters/models.py +205 -0
- raise_cli/adapters/protocols.py +180 -0
- raise_cli/adapters/registry.py +90 -0
- raise_cli/adapters/sync.py +149 -0
- raise_cli/agents/__init__.py +14 -0
- raise_cli/agents/antigravity.yaml +8 -0
- raise_cli/agents/claude.yaml +8 -0
- raise_cli/agents/copilot.yaml +8 -0
- raise_cli/agents/copilot_plugin.py +124 -0
- raise_cli/agents/cursor.yaml +7 -0
- raise_cli/agents/roo.yaml +8 -0
- raise_cli/agents/windsurf.yaml +8 -0
- raise_cli/artifacts/__init__.py +30 -0
- raise_cli/artifacts/models.py +43 -0
- raise_cli/artifacts/reader.py +55 -0
- raise_cli/artifacts/renderer.py +104 -0
- raise_cli/artifacts/story_design.py +69 -0
- raise_cli/artifacts/writer.py +45 -0
- raise_cli/backlog/__init__.py +1 -0
- raise_cli/backlog/sync.py +115 -0
- raise_cli/cli/__init__.py +3 -0
- raise_cli/cli/commands/__init__.py +3 -0
- raise_cli/cli/commands/_resolve.py +153 -0
- raise_cli/cli/commands/adapters.py +362 -0
- raise_cli/cli/commands/artifact.py +137 -0
- raise_cli/cli/commands/backlog.py +333 -0
- raise_cli/cli/commands/base.py +31 -0
- raise_cli/cli/commands/discover.py +551 -0
- raise_cli/cli/commands/docs.py +130 -0
- raise_cli/cli/commands/doctor.py +177 -0
- raise_cli/cli/commands/gate.py +223 -0
- raise_cli/cli/commands/graph.py +1086 -0
- raise_cli/cli/commands/info.py +81 -0
- raise_cli/cli/commands/init.py +746 -0
- raise_cli/cli/commands/journal.py +167 -0
- raise_cli/cli/commands/mcp.py +524 -0
- raise_cli/cli/commands/memory.py +467 -0
- raise_cli/cli/commands/pattern.py +348 -0
- raise_cli/cli/commands/profile.py +59 -0
- raise_cli/cli/commands/publish.py +80 -0
- raise_cli/cli/commands/release.py +338 -0
- raise_cli/cli/commands/session.py +528 -0
- raise_cli/cli/commands/signal.py +410 -0
- raise_cli/cli/commands/skill.py +350 -0
- raise_cli/cli/commands/skill_set.py +145 -0
- raise_cli/cli/error_handler.py +158 -0
- raise_cli/cli/main.py +163 -0
- raise_cli/compat.py +66 -0
- raise_cli/config/__init__.py +41 -0
- raise_cli/config/agent_plugin.py +105 -0
- raise_cli/config/agent_registry.py +233 -0
- raise_cli/config/agents.py +120 -0
- raise_cli/config/ide.py +32 -0
- raise_cli/config/paths.py +379 -0
- raise_cli/config/settings.py +180 -0
- raise_cli/context/__init__.py +42 -0
- raise_cli/context/analyzers/__init__.py +16 -0
- raise_cli/context/analyzers/models.py +36 -0
- raise_cli/context/analyzers/protocol.py +43 -0
- raise_cli/context/analyzers/python.py +292 -0
- raise_cli/context/builder.py +1569 -0
- raise_cli/context/diff.py +213 -0
- raise_cli/context/extractors/__init__.py +13 -0
- raise_cli/context/extractors/skills.py +121 -0
- raise_cli/core/__init__.py +37 -0
- raise_cli/core/files.py +66 -0
- raise_cli/core/text.py +174 -0
- raise_cli/core/tools.py +441 -0
- raise_cli/discovery/__init__.py +50 -0
- raise_cli/discovery/analyzer.py +691 -0
- raise_cli/discovery/drift.py +355 -0
- raise_cli/discovery/scanner.py +1687 -0
- raise_cli/doctor/__init__.py +4 -0
- raise_cli/doctor/checks/__init__.py +1 -0
- raise_cli/doctor/checks/environment.py +110 -0
- raise_cli/doctor/checks/project.py +238 -0
- raise_cli/doctor/fix.py +80 -0
- raise_cli/doctor/models.py +56 -0
- raise_cli/doctor/protocol.py +43 -0
- raise_cli/doctor/registry.py +100 -0
- raise_cli/doctor/report.py +141 -0
- raise_cli/doctor/runner.py +95 -0
- raise_cli/engines/__init__.py +3 -0
- raise_cli/exceptions.py +215 -0
- raise_cli/gates/__init__.py +19 -0
- raise_cli/gates/builtin/__init__.py +1 -0
- raise_cli/gates/builtin/coverage.py +52 -0
- raise_cli/gates/builtin/lint.py +48 -0
- raise_cli/gates/builtin/tests.py +48 -0
- raise_cli/gates/builtin/types.py +48 -0
- raise_cli/gates/models.py +40 -0
- raise_cli/gates/protocol.py +41 -0
- raise_cli/gates/registry.py +141 -0
- raise_cli/governance/__init__.py +11 -0
- raise_cli/governance/extractor.py +412 -0
- raise_cli/governance/models.py +134 -0
- raise_cli/governance/parsers/__init__.py +35 -0
- raise_cli/governance/parsers/_convert.py +38 -0
- raise_cli/governance/parsers/adr.py +274 -0
- raise_cli/governance/parsers/backlog.py +356 -0
- raise_cli/governance/parsers/constitution.py +119 -0
- raise_cli/governance/parsers/epic.py +323 -0
- raise_cli/governance/parsers/glossary.py +316 -0
- raise_cli/governance/parsers/guardrails.py +345 -0
- raise_cli/governance/parsers/prd.py +112 -0
- raise_cli/governance/parsers/roadmap.py +118 -0
- raise_cli/governance/parsers/vision.py +116 -0
- raise_cli/graph/__init__.py +1 -0
- raise_cli/graph/backends/__init__.py +57 -0
- raise_cli/graph/backends/api.py +137 -0
- raise_cli/graph/backends/dual.py +139 -0
- raise_cli/graph/backends/pending.py +84 -0
- raise_cli/handlers/__init__.py +3 -0
- raise_cli/hooks/__init__.py +54 -0
- raise_cli/hooks/builtin/__init__.py +1 -0
- raise_cli/hooks/builtin/backlog.py +216 -0
- raise_cli/hooks/builtin/gate_bridge.py +83 -0
- raise_cli/hooks/builtin/jira_sync.py +127 -0
- raise_cli/hooks/builtin/memory.py +117 -0
- raise_cli/hooks/builtin/telemetry.py +72 -0
- raise_cli/hooks/emitter.py +184 -0
- raise_cli/hooks/events.py +262 -0
- raise_cli/hooks/protocol.py +38 -0
- raise_cli/hooks/registry.py +117 -0
- raise_cli/mcp/__init__.py +33 -0
- raise_cli/mcp/bridge.py +218 -0
- raise_cli/mcp/models.py +43 -0
- raise_cli/mcp/registry.py +77 -0
- raise_cli/mcp/schema.py +41 -0
- raise_cli/memory/__init__.py +58 -0
- raise_cli/memory/loader.py +247 -0
- raise_cli/memory/migration.py +241 -0
- raise_cli/memory/models.py +169 -0
- raise_cli/memory/writer.py +598 -0
- raise_cli/onboarding/__init__.py +103 -0
- raise_cli/onboarding/bootstrap.py +324 -0
- raise_cli/onboarding/claudemd.py +17 -0
- raise_cli/onboarding/conventions.py +742 -0
- raise_cli/onboarding/detection.py +374 -0
- raise_cli/onboarding/governance.py +443 -0
- raise_cli/onboarding/instructions.py +672 -0
- raise_cli/onboarding/manifest.py +201 -0
- raise_cli/onboarding/memory_md.py +399 -0
- raise_cli/onboarding/migration.py +207 -0
- raise_cli/onboarding/profile.py +624 -0
- raise_cli/onboarding/skill_conflict.py +100 -0
- raise_cli/onboarding/skill_manifest.py +176 -0
- raise_cli/onboarding/skills.py +437 -0
- raise_cli/onboarding/workflows.py +101 -0
- raise_cli/output/__init__.py +28 -0
- raise_cli/output/console.py +394 -0
- raise_cli/output/formatters/__init__.py +9 -0
- raise_cli/output/formatters/adapters.py +135 -0
- raise_cli/output/formatters/discover.py +439 -0
- raise_cli/output/formatters/skill.py +298 -0
- raise_cli/publish/__init__.py +3 -0
- raise_cli/publish/changelog.py +80 -0
- raise_cli/publish/check.py +179 -0
- raise_cli/publish/version.py +172 -0
- raise_cli/rai_base/__init__.py +22 -0
- raise_cli/rai_base/framework/__init__.py +7 -0
- raise_cli/rai_base/framework/methodology.yaml +233 -0
- raise_cli/rai_base/governance/__init__.py +1 -0
- raise_cli/rai_base/governance/architecture/__init__.py +1 -0
- raise_cli/rai_base/governance/architecture/domain-model.md +20 -0
- raise_cli/rai_base/governance/architecture/system-context.md +34 -0
- raise_cli/rai_base/governance/architecture/system-design.md +24 -0
- raise_cli/rai_base/governance/backlog.md +8 -0
- raise_cli/rai_base/governance/guardrails.md +17 -0
- raise_cli/rai_base/governance/prd.md +25 -0
- raise_cli/rai_base/governance/vision.md +16 -0
- raise_cli/rai_base/identity/__init__.py +8 -0
- raise_cli/rai_base/identity/core.md +119 -0
- raise_cli/rai_base/identity/perspective.md +119 -0
- raise_cli/rai_base/memory/__init__.py +7 -0
- raise_cli/rai_base/memory/patterns-base.jsonl +55 -0
- raise_cli/schemas/__init__.py +3 -0
- raise_cli/schemas/journal.py +49 -0
- raise_cli/schemas/session_state.py +117 -0
- raise_cli/session/__init__.py +5 -0
- raise_cli/session/bundle.py +820 -0
- raise_cli/session/close.py +268 -0
- raise_cli/session/journal.py +119 -0
- raise_cli/session/resolver.py +126 -0
- raise_cli/session/state.py +187 -0
- raise_cli/skills/__init__.py +44 -0
- raise_cli/skills/locator.py +141 -0
- raise_cli/skills/name_checker.py +199 -0
- raise_cli/skills/parser.py +145 -0
- raise_cli/skills/scaffold.py +212 -0
- raise_cli/skills/schema.py +132 -0
- raise_cli/skills/skillsets.py +195 -0
- raise_cli/skills/validator.py +197 -0
- raise_cli/skills_base/__init__.py +80 -0
- raise_cli/skills_base/contract-template.md +60 -0
- raise_cli/skills_base/preamble.md +37 -0
- raise_cli/skills_base/rai-architecture-review/SKILL.md +137 -0
- raise_cli/skills_base/rai-debug/SKILL.md +171 -0
- raise_cli/skills_base/rai-discover/SKILL.md +167 -0
- raise_cli/skills_base/rai-discover-document/SKILL.md +128 -0
- raise_cli/skills_base/rai-discover-scan/SKILL.md +147 -0
- raise_cli/skills_base/rai-discover-start/SKILL.md +145 -0
- raise_cli/skills_base/rai-discover-validate/SKILL.md +142 -0
- raise_cli/skills_base/rai-docs-update/SKILL.md +142 -0
- raise_cli/skills_base/rai-doctor/SKILL.md +120 -0
- raise_cli/skills_base/rai-epic-close/SKILL.md +165 -0
- raise_cli/skills_base/rai-epic-close/templates/retrospective.md +68 -0
- raise_cli/skills_base/rai-epic-design/SKILL.md +146 -0
- raise_cli/skills_base/rai-epic-design/templates/design.md +24 -0
- raise_cli/skills_base/rai-epic-design/templates/scope.md +76 -0
- raise_cli/skills_base/rai-epic-plan/SKILL.md +153 -0
- raise_cli/skills_base/rai-epic-plan/_references/sequencing-strategies.md +67 -0
- raise_cli/skills_base/rai-epic-plan/templates/plan-section.md +49 -0
- raise_cli/skills_base/rai-epic-run/SKILL.md +208 -0
- raise_cli/skills_base/rai-epic-start/SKILL.md +136 -0
- raise_cli/skills_base/rai-epic-start/templates/brief.md +34 -0
- raise_cli/skills_base/rai-mcp-add/SKILL.md +176 -0
- raise_cli/skills_base/rai-mcp-remove/SKILL.md +120 -0
- raise_cli/skills_base/rai-mcp-status/SKILL.md +147 -0
- raise_cli/skills_base/rai-problem-shape/SKILL.md +138 -0
- raise_cli/skills_base/rai-project-create/SKILL.md +144 -0
- raise_cli/skills_base/rai-project-onboard/SKILL.md +162 -0
- raise_cli/skills_base/rai-quality-review/SKILL.md +189 -0
- raise_cli/skills_base/rai-research/SKILL.md +143 -0
- raise_cli/skills_base/rai-research/references/research-prompt-template.md +317 -0
- raise_cli/skills_base/rai-session-close/SKILL.md +176 -0
- raise_cli/skills_base/rai-session-start/SKILL.md +110 -0
- raise_cli/skills_base/rai-story-close/SKILL.md +198 -0
- raise_cli/skills_base/rai-story-design/SKILL.md +203 -0
- raise_cli/skills_base/rai-story-design/references/tech-design-story-v2.md +293 -0
- raise_cli/skills_base/rai-story-implement/SKILL.md +115 -0
- raise_cli/skills_base/rai-story-plan/SKILL.md +135 -0
- raise_cli/skills_base/rai-story-review/SKILL.md +178 -0
- raise_cli/skills_base/rai-story-run/SKILL.md +282 -0
- raise_cli/skills_base/rai-story-start/SKILL.md +166 -0
- raise_cli/skills_base/rai-story-start/templates/story.md +38 -0
- raise_cli/skills_base/rai-welcome/SKILL.md +134 -0
- raise_cli/telemetry/__init__.py +42 -0
- raise_cli/telemetry/schemas.py +285 -0
- raise_cli/telemetry/writer.py +217 -0
- raise_cli/tier/__init__.py +0 -0
- raise_cli/tier/context.py +134 -0
- raise_cli/viz/__init__.py +7 -0
- raise_cli/viz/generator.py +406 -0
- raise_cli-2.2.1.dist-info/METADATA +433 -0
- raise_cli-2.2.1.dist-info/RECORD +264 -0
- raise_cli-2.2.1.dist-info/WHEEL +4 -0
- raise_cli-2.2.1.dist-info/entry_points.txt +40 -0
- raise_cli-2.2.1.dist-info/licenses/LICENSE +190 -0
- raise_cli-2.2.1.dist-info/licenses/NOTICE +4 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
"""Validator for SKILL.md files.
|
|
2
|
+
|
|
3
|
+
Validates skill structure against ADR-040 contract including:
|
|
4
|
+
- Required fields (name, description, metadata)
|
|
5
|
+
- Required sections (7 canonical: Purpose through References)
|
|
6
|
+
- Line count target (≤150 body lines)
|
|
7
|
+
- Naming conventions ({domain}-{action})
|
|
8
|
+
- Hook paths (warns if script not found)
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import re
|
|
14
|
+
from enum import Enum
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
|
|
17
|
+
from pydantic import BaseModel, Field, ValidationError
|
|
18
|
+
|
|
19
|
+
from raise_cli.skills.parser import ParseError, parse_skill
|
|
20
|
+
from raise_cli.skills.schema import Skill
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ValidationSeverity(Enum):
|
|
24
|
+
"""Severity level for validation issues."""
|
|
25
|
+
|
|
26
|
+
ERROR = "error"
|
|
27
|
+
WARNING = "warning"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class ValidationResult(BaseModel):
|
|
31
|
+
"""Result of validating a skill file."""
|
|
32
|
+
|
|
33
|
+
path: str = Field(description="Path to the validated file")
|
|
34
|
+
errors: list[str] = Field(
|
|
35
|
+
default_factory=lambda: [], description="Validation errors"
|
|
36
|
+
)
|
|
37
|
+
warnings: list[str] = Field(
|
|
38
|
+
default_factory=lambda: [], description="Validation warnings"
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
@property
|
|
42
|
+
def is_valid(self) -> bool:
|
|
43
|
+
"""Skill is valid if there are no errors (warnings OK)."""
|
|
44
|
+
return len(self.errors) == 0
|
|
45
|
+
|
|
46
|
+
@property
|
|
47
|
+
def error_count(self) -> int:
|
|
48
|
+
"""Number of errors."""
|
|
49
|
+
return len(self.errors)
|
|
50
|
+
|
|
51
|
+
@property
|
|
52
|
+
def warning_count(self) -> int:
|
|
53
|
+
"""Number of warnings."""
|
|
54
|
+
return len(self.warnings)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
# ADR-040 canonical sections (7, fixed order)
|
|
58
|
+
REQUIRED_SECTIONS = [
|
|
59
|
+
"Purpose",
|
|
60
|
+
"Mastery Levels",
|
|
61
|
+
"Context",
|
|
62
|
+
"Steps",
|
|
63
|
+
"Output",
|
|
64
|
+
"Quality Checklist",
|
|
65
|
+
"References",
|
|
66
|
+
]
|
|
67
|
+
|
|
68
|
+
# ADR-040 line count target for skill body
|
|
69
|
+
MAX_BODY_LINES = 150
|
|
70
|
+
|
|
71
|
+
# Pattern for {domain}-{action} naming convention
|
|
72
|
+
NAMING_PATTERN = re.compile(r"^[a-z]+-[a-z]+(-[a-z]+)*$")
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _validate_required_fields(skill: Skill, errors: list[str]) -> None:
|
|
76
|
+
"""Check required frontmatter fields."""
|
|
77
|
+
if not skill.frontmatter.name:
|
|
78
|
+
errors.append("Missing required field: name")
|
|
79
|
+
|
|
80
|
+
if not skill.frontmatter.description:
|
|
81
|
+
errors.append("Missing required field: description")
|
|
82
|
+
|
|
83
|
+
if not skill.frontmatter.metadata:
|
|
84
|
+
errors.append("Missing required field: metadata")
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def _validate_required_sections(skill: Skill, errors: list[str]) -> None:
|
|
88
|
+
"""Check required sections in body (ADR-040: 7 canonical sections)."""
|
|
89
|
+
body_lower = skill.body.lower()
|
|
90
|
+
|
|
91
|
+
for section in REQUIRED_SECTIONS:
|
|
92
|
+
# Match "## Section" with optional suffix (e.g., "## Mastery Levels (ShuHaRi)")
|
|
93
|
+
pattern = f"## {section.lower()}"
|
|
94
|
+
if pattern not in body_lower:
|
|
95
|
+
errors.append(f"Missing required section: {section}")
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def _validate_line_count(skill: Skill, warnings: list[str]) -> None:
|
|
99
|
+
"""Warn if skill body exceeds ADR-040 line count target."""
|
|
100
|
+
body_lines = len(skill.body.strip().splitlines())
|
|
101
|
+
if body_lines > MAX_BODY_LINES:
|
|
102
|
+
warnings.append(f"Body has {body_lines} lines (target: ≤{MAX_BODY_LINES})")
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def _validate_naming_convention(skill: Skill, warnings: list[str]) -> None:
|
|
106
|
+
"""Check naming follows {domain}-{action} pattern."""
|
|
107
|
+
name = skill.frontmatter.name
|
|
108
|
+
if name and not NAMING_PATTERN.match(name):
|
|
109
|
+
warnings.append(
|
|
110
|
+
f"Name '{name}' doesn't follow {{domain}}-{{action}} pattern (e.g., session-start)"
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def _validate_hook_paths(skill: Skill, warnings: list[str]) -> None:
|
|
115
|
+
"""Check that hook script paths exist (warning only)."""
|
|
116
|
+
if not skill.frontmatter.hooks:
|
|
117
|
+
return
|
|
118
|
+
|
|
119
|
+
for hook_name, hook_list in skill.frontmatter.hooks.items():
|
|
120
|
+
for hook in hook_list:
|
|
121
|
+
for cmd in hook.hooks:
|
|
122
|
+
# Extract script path from command
|
|
123
|
+
# Handles: "RAISE_SKILL_NAME=x \"$CLAUDE_PROJECT_DIR\"/.raise/scripts/script.sh"
|
|
124
|
+
# Also handles: "/absolute/path/script.sh"
|
|
125
|
+
command = cmd.command
|
|
126
|
+
|
|
127
|
+
# Skip variable-based paths (we can't resolve them)
|
|
128
|
+
if "$" in command:
|
|
129
|
+
continue
|
|
130
|
+
|
|
131
|
+
# Check if command looks like a path
|
|
132
|
+
if command.startswith("/"):
|
|
133
|
+
path = Path(command.split()[0]) # Get first word (the path)
|
|
134
|
+
if not path.exists():
|
|
135
|
+
warnings.append(f"Hook '{hook_name}' script not found: {path}")
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def validate_skill(skill: Skill) -> ValidationResult:
|
|
139
|
+
"""Validate a parsed Skill object.
|
|
140
|
+
|
|
141
|
+
Args:
|
|
142
|
+
skill: Parsed Skill object.
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
ValidationResult with errors and warnings.
|
|
146
|
+
"""
|
|
147
|
+
errors: list[str] = []
|
|
148
|
+
warnings: list[str] = []
|
|
149
|
+
|
|
150
|
+
_validate_required_fields(skill, errors)
|
|
151
|
+
_validate_required_sections(skill, errors)
|
|
152
|
+
_validate_line_count(skill, warnings)
|
|
153
|
+
_validate_naming_convention(skill, warnings)
|
|
154
|
+
_validate_hook_paths(skill, warnings)
|
|
155
|
+
|
|
156
|
+
return ValidationResult(
|
|
157
|
+
path=skill.path,
|
|
158
|
+
errors=errors,
|
|
159
|
+
warnings=warnings,
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def validate_skill_file(path: str | Path) -> ValidationResult:
|
|
164
|
+
"""Validate a SKILL.md file.
|
|
165
|
+
|
|
166
|
+
Args:
|
|
167
|
+
path: Path to the SKILL.md file.
|
|
168
|
+
|
|
169
|
+
Returns:
|
|
170
|
+
ValidationResult with errors and warnings.
|
|
171
|
+
"""
|
|
172
|
+
path = Path(path)
|
|
173
|
+
str_path = str(path)
|
|
174
|
+
|
|
175
|
+
# Check file exists
|
|
176
|
+
if not path.exists():
|
|
177
|
+
return ValidationResult(
|
|
178
|
+
path=str_path,
|
|
179
|
+
errors=[f"File not found: {path}"],
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
# Try to parse
|
|
183
|
+
try:
|
|
184
|
+
skill = parse_skill(path)
|
|
185
|
+
except ParseError as e:
|
|
186
|
+
return ValidationResult(
|
|
187
|
+
path=str_path,
|
|
188
|
+
errors=[f"Parse error: {e}"],
|
|
189
|
+
)
|
|
190
|
+
except ValidationError as e:
|
|
191
|
+
return ValidationResult(
|
|
192
|
+
path=str_path,
|
|
193
|
+
errors=[f"Schema error: {e}"],
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
# Validate the parsed skill
|
|
197
|
+
return validate_skill(skill)
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""Base skills package for distribution.
|
|
2
|
+
|
|
3
|
+
This package contains the RaiSE skills that ship with raise-cli.
|
|
4
|
+
On `rai init`, skill files are copied to the project's
|
|
5
|
+
`.claude/skills/` directory (Claude Code) or equivalent IDE location.
|
|
6
|
+
|
|
7
|
+
All skills use the `rai-` namespace prefix to prevent collision
|
|
8
|
+
with user-created or third-party skills.
|
|
9
|
+
|
|
10
|
+
Contents:
|
|
11
|
+
Session lifecycle: rai-session-start, rai-session-close
|
|
12
|
+
Story lifecycle: rai-story-start, rai-story-plan, rai-story-design,
|
|
13
|
+
rai-story-implement, rai-story-review, rai-story-close
|
|
14
|
+
Epic lifecycle: rai-epic-start, rai-epic-plan, rai-epic-design, rai-epic-close
|
|
15
|
+
Discovery: rai-discover-start, rai-discover-scan,
|
|
16
|
+
rai-discover-validate, rai-discover-document
|
|
17
|
+
Onboarding: rai-project-create, rai-project-onboard, rai-welcome
|
|
18
|
+
Governance: rai-docs-update
|
|
19
|
+
Quality: rai-architecture-review, rai-quality-review
|
|
20
|
+
MCP: rai-mcp-add, rai-mcp-remove, rai-mcp-status
|
|
21
|
+
Tools: rai-research, rai-debug, rai-doctor, rai-problem-shape
|
|
22
|
+
|
|
23
|
+
Note: Internal skills (rai-framework-sync, rai-publish, rai-skillset-manage,
|
|
24
|
+
rai-bugfix) are excluded from distribution.
|
|
25
|
+
|
|
26
|
+
Usage:
|
|
27
|
+
from importlib.resources import files
|
|
28
|
+
|
|
29
|
+
base_skills = files("raise_cli.skills_base")
|
|
30
|
+
session_start = base_skills / "rai-session-start" / "SKILL.md"
|
|
31
|
+
content = session_start.read_text(encoding="utf-8")
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
from __future__ import annotations
|
|
35
|
+
|
|
36
|
+
__version__ = "2.2.0"
|
|
37
|
+
|
|
38
|
+
DISTRIBUTABLE_SKILLS: list[str] = [
|
|
39
|
+
# Session lifecycle
|
|
40
|
+
"rai-session-close",
|
|
41
|
+
"rai-session-start",
|
|
42
|
+
# Story lifecycle
|
|
43
|
+
"rai-story-close",
|
|
44
|
+
"rai-story-design",
|
|
45
|
+
"rai-story-implement",
|
|
46
|
+
"rai-story-plan",
|
|
47
|
+
"rai-story-review",
|
|
48
|
+
"rai-story-run",
|
|
49
|
+
"rai-story-start",
|
|
50
|
+
# Epic lifecycle
|
|
51
|
+
"rai-epic-close",
|
|
52
|
+
"rai-epic-design",
|
|
53
|
+
"rai-epic-plan",
|
|
54
|
+
"rai-epic-run",
|
|
55
|
+
"rai-epic-start",
|
|
56
|
+
# Discovery
|
|
57
|
+
"rai-discover",
|
|
58
|
+
"rai-discover-document",
|
|
59
|
+
"rai-discover-scan",
|
|
60
|
+
"rai-discover-start",
|
|
61
|
+
"rai-discover-validate",
|
|
62
|
+
# Onboarding
|
|
63
|
+
"rai-project-create",
|
|
64
|
+
"rai-project-onboard",
|
|
65
|
+
"rai-welcome",
|
|
66
|
+
# Governance
|
|
67
|
+
"rai-docs-update",
|
|
68
|
+
# Quality
|
|
69
|
+
"rai-architecture-review",
|
|
70
|
+
"rai-quality-review",
|
|
71
|
+
# MCP
|
|
72
|
+
"rai-mcp-add",
|
|
73
|
+
"rai-mcp-remove",
|
|
74
|
+
"rai-mcp-status",
|
|
75
|
+
# Tools
|
|
76
|
+
"rai-debug",
|
|
77
|
+
"rai-doctor",
|
|
78
|
+
"rai-problem-shape",
|
|
79
|
+
"rai-research",
|
|
80
|
+
]
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Skill Contract Template (ADR-040)
|
|
2
|
+
|
|
3
|
+
> Reference for refactoring skills to canonical structure.
|
|
4
|
+
> Every SKILL.md follows exactly these 7 sections in this order.
|
|
5
|
+
|
|
6
|
+
## Targets
|
|
7
|
+
|
|
8
|
+
| Metric | Target |
|
|
9
|
+
|--------|--------|
|
|
10
|
+
| Sections | Exactly 7, fixed order |
|
|
11
|
+
| Total lines | ≤150 (excluding YAML frontmatter) |
|
|
12
|
+
| Discrete rules | ≤15 |
|
|
13
|
+
| Substance ratio | ≥80% |
|
|
14
|
+
| Examples | 1-2 per skill |
|
|
15
|
+
| Negative phrases | ≤3 (reserve for true guardrails in Quality Checklist) |
|
|
16
|
+
|
|
17
|
+
## Canonical Structure
|
|
18
|
+
|
|
19
|
+
```markdown
|
|
20
|
+
# {Skill Title}
|
|
21
|
+
|
|
22
|
+
## Purpose
|
|
23
|
+
One sentence: what this skill does and what success looks like.
|
|
24
|
+
|
|
25
|
+
## Mastery Levels (ShuHaRi)
|
|
26
|
+
≤5 lines. Behavior deltas SPECIFIC to this skill only.
|
|
27
|
+
Universal ShuHaRi definitions are in the preamble — do not repeat them.
|
|
28
|
+
|
|
29
|
+
## Context
|
|
30
|
+
When to use / when to skip. Inputs required. Prerequisites (gates).
|
|
31
|
+
Use decision tables for conditional logic, not prose paragraphs.
|
|
32
|
+
|
|
33
|
+
## Steps
|
|
34
|
+
### Step N: {Verb Phrase}
|
|
35
|
+
Follow the step format convention from the preamble:
|
|
36
|
+
- Action: what to do (affirmative phrasing)
|
|
37
|
+
- Verification: how to check success
|
|
38
|
+
- If blocked: recovery path
|
|
39
|
+
|
|
40
|
+
Steps use clean integer numbering (1, 2, 3 — no 0.1, 1.5, 4b).
|
|
41
|
+
|
|
42
|
+
## Output
|
|
43
|
+
What this skill produces. Where artifacts go. State changes. Next skill.
|
|
44
|
+
|
|
45
|
+
## Quality Checklist
|
|
46
|
+
Atomic, verifiable items. This is the last thing the agent reads before
|
|
47
|
+
finishing — recency bias means these get highest compliance.
|
|
48
|
+
Place critical guardrails here (≤3 negative "NEVER" items if needed).
|
|
49
|
+
|
|
50
|
+
## References
|
|
51
|
+
Links only — no inline content. File paths, ADRs, related skills.
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Content Principles
|
|
55
|
+
|
|
56
|
+
1. **Affirmative over negative** — "Do X when Y" instead of "Don't do X"
|
|
57
|
+
2. **Decision tables over prose** — Branching logic as tables, not if-else paragraphs
|
|
58
|
+
3. **Examples over rules** — One input/output example replaces 10+ lines of rules
|
|
59
|
+
4. **Atomic instructions** — Each rule is one verifiable statement
|
|
60
|
+
5. **Templates by reference** — Link to template files, don't inline them
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# RaiSE Skill Preamble
|
|
2
|
+
|
|
3
|
+
> Loaded once per session. Skills reference these conventions — they don't repeat them.
|
|
4
|
+
|
|
5
|
+
## ShuHaRi — Developer Experience Level
|
|
6
|
+
|
|
7
|
+
The developer's ShuHaRi level comes from their profile (`~/.rai/developer.yaml`). It reflects their experience with RaiSE, not general skill. Adapt your output verbosity — the process (steps) stays the same.
|
|
8
|
+
|
|
9
|
+
| Level | Developer profile | Agent behavior |
|
|
10
|
+
|-------|------------------|----------------|
|
|
11
|
+
| **Shu** | New to RaiSE | Explain concepts, provide context, detailed step output |
|
|
12
|
+
| **Ha** | Comfortable with RaiSE | Explain only what's new or non-obvious |
|
|
13
|
+
| **Ri** | Veteran | Minimal output, essentials only, no explanations |
|
|
14
|
+
|
|
15
|
+
## Step Format Convention
|
|
16
|
+
|
|
17
|
+
Every step in a skill follows this structure:
|
|
18
|
+
|
|
19
|
+
- **Action:** What to do (affirmative phrasing preferred)
|
|
20
|
+
- **Verification:** How to confirm the step succeeded
|
|
21
|
+
- **If blocked:** Recovery path when the step can't complete
|
|
22
|
+
|
|
23
|
+
When blocked, stop and address the blocker. Do not skip steps or accumulate errors (Jidoka).
|
|
24
|
+
|
|
25
|
+
## Graph Context Loading
|
|
26
|
+
|
|
27
|
+
Skills that need codebase context use these CLI commands as early steps:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Query patterns, decisions, guardrails
|
|
31
|
+
rai graph query "<topic>" --types pattern,decision --limit 5
|
|
32
|
+
|
|
33
|
+
# Load module architectural context
|
|
34
|
+
rai graph context mod-<name>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
If the graph is unavailable, run `rai graph build` first — or proceed without context if the work is self-contained.
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rai-architecture-review
|
|
3
|
+
description: >
|
|
4
|
+
Evaluate design proportionality and necessity using Beck's four rules.
|
|
5
|
+
Catches what correctness gates miss: over-engineering, orphaned abstractions,
|
|
6
|
+
speculative generality, and accumulated complexity. Parametrized for story
|
|
7
|
+
(local) and epic (systemic) scope.
|
|
8
|
+
|
|
9
|
+
license: MIT
|
|
10
|
+
|
|
11
|
+
metadata:
|
|
12
|
+
raise.work_cycle: story, epic
|
|
13
|
+
raise.frequency: on-demand
|
|
14
|
+
raise.prerequisites: story-implement (story scope), last story complete (epic scope)
|
|
15
|
+
raise.version: "1.0.0"
|
|
16
|
+
raise.visibility: internal
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# Architecture Review
|
|
20
|
+
|
|
21
|
+
## Purpose
|
|
22
|
+
|
|
23
|
+
Evaluate whether code is **necessary and proportional** using Beck's four rules of simple design. Core question: "Could we achieve the same outcome with less?"
|
|
24
|
+
|
|
25
|
+
## Mastery Levels (ShuHaRi)
|
|
26
|
+
|
|
27
|
+
- **Shu**: Apply all heuristics systematically, explain each finding
|
|
28
|
+
- **Ha**: Focus on highest-signal heuristics for the scope, skip low-risk areas
|
|
29
|
+
- **Ri**: Pattern-match to known anti-patterns, minimal ceremony
|
|
30
|
+
|
|
31
|
+
## Context
|
|
32
|
+
|
|
33
|
+
| Condition | Action |
|
|
34
|
+
|-----------|--------|
|
|
35
|
+
| After `/rai-story-implement` | Run with `story` scope |
|
|
36
|
+
| After last story in epic | Run with `epic` scope |
|
|
37
|
+
| Accumulated complexity feels disproportionate | Run on-demand |
|
|
38
|
+
|
|
39
|
+
**Inputs:** Scope (`story` or `epic`), design doc, changed files from git diff.
|
|
40
|
+
|
|
41
|
+
## Steps
|
|
42
|
+
|
|
43
|
+
### Step 1: Identify Scope and Changed Files
|
|
44
|
+
|
|
45
|
+
Detect the project language and filter by appropriate extensions:
|
|
46
|
+
|
|
47
|
+
1. **Check `.raise/manifest.yaml`** for `project.language` or `project.project_type`
|
|
48
|
+
2. **Fallback:** Scan extensions of changed files and pick the dominant language
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# Story scope: files changed vs parent branch
|
|
52
|
+
git diff --name-only $(git merge-base HEAD <parent-branch>)..HEAD -- '<extensions>'
|
|
53
|
+
# Epic scope: all files changed vs development branch
|
|
54
|
+
git diff --name-only $(git merge-base HEAD <dev-branch>)..HEAD -- '<extensions>'
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Replace `<extensions>` with language-appropriate patterns (e.g., `'*.py' '*.pyi'` for Python, `'*.ts' '*.tsx'` for TypeScript, `'*.cs'` for C#).
|
|
58
|
+
|
|
59
|
+
Read every changed file and the design doc. You cannot judge proportionality without intent context.
|
|
60
|
+
|
|
61
|
+
### Step 2: Necessity Audit (YAGNI — Beck Rule 4)
|
|
62
|
+
|
|
63
|
+
| # | Heuristic | Red Flag |
|
|
64
|
+
|---|-----------|----------|
|
|
65
|
+
| H1 | Single Implementation | Protocol/ABC with exactly one concrete implementation, no documented consumer |
|
|
66
|
+
| H2 | Wrapper Without Logic | Class delegates all work without adding behavior |
|
|
67
|
+
| H3 | Unused Parameters | Parameters accepted but never used in function body |
|
|
68
|
+
| H4 | Test-Only Consumers | Public function/class used exclusively by test code |
|
|
69
|
+
| H5 | Dead Exports | Public API includes names no consumer imports (e.g., `__all__` in Python, `export` in TS, `public` in C#) |
|
|
70
|
+
|
|
71
|
+
When a heuristic triggers, check: "Does the design doc justify this?" If yes, note as Observation.
|
|
72
|
+
|
|
73
|
+
### Step 3: Proportionality Audit (KISS — Beck Rules 2+4)
|
|
74
|
+
|
|
75
|
+
| # | Heuristic | Red Flag |
|
|
76
|
+
|---|-----------|----------|
|
|
77
|
+
| H6 | Indirection Depth | >2 layers of delegation for a simple operation |
|
|
78
|
+
| H7 | Abstraction-to-LOC Ratio | More scaffolding than logic |
|
|
79
|
+
| H8 | Configuration Over Convention | Configurable with only one valid value in practice |
|
|
80
|
+
|
|
81
|
+
### Step 4: Duplication & Responsibility (Beck Rules 2-3)
|
|
82
|
+
|
|
83
|
+
| # | Heuristic | Red Flag |
|
|
84
|
+
|---|-----------|----------|
|
|
85
|
+
| H9 | Semantic Duplication | Same concept expressed differently in multiple places |
|
|
86
|
+
| H10 | Pattern Duplication | Same structural problem solved differently across modules |
|
|
87
|
+
| H11 | Change Reason Count | Module changes for >1 unrelated reason |
|
|
88
|
+
| H12 | Import Fan-In | File imports from 5+ distinct packages for one function |
|
|
89
|
+
|
|
90
|
+
### Step 5: Systemic Audit (Epic Scope Only)
|
|
91
|
+
|
|
92
|
+
Skip for story scope. Cross-module heuristics:
|
|
93
|
+
|
|
94
|
+
| # | Heuristic | Red Flag |
|
|
95
|
+
|---|-----------|----------|
|
|
96
|
+
| H13 | Orphaned Abstractions | Protocol from early story still has ≤1 implementor at epic end |
|
|
97
|
+
| H14 | Coupling Direction | Stable core imports from volatile/new module |
|
|
98
|
+
| H15 | Cyclic Dependencies | Circular import paths between modules |
|
|
99
|
+
| H16 | Shotgun Surgery | One logical change touches 5+ files across 3+ directories |
|
|
100
|
+
|
|
101
|
+
### Step 6: Present Findings
|
|
102
|
+
|
|
103
|
+
```markdown
|
|
104
|
+
## Architecture Review: {id} (scope: {story|epic})
|
|
105
|
+
|
|
106
|
+
### Critical (fix before merge)
|
|
107
|
+
### Recommended (simplify before next cycle)
|
|
108
|
+
### Questions (require human judgment)
|
|
109
|
+
### Observations (patterns noted)
|
|
110
|
+
### Verdict
|
|
111
|
+
- [ ] PASS / PASS WITH QUESTIONS / SIMPLIFY
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Every finding: specific file:line, heuristic ID, proportionality concern, concrete simplification.
|
|
115
|
+
|
|
116
|
+
## Output
|
|
117
|
+
|
|
118
|
+
| Item | Destination |
|
|
119
|
+
|------|-------------|
|
|
120
|
+
| Review findings | Presented inline, saved if requested |
|
|
121
|
+
| Verdict | PASS, PASS WITH QUESTIONS, or SIMPLIFY |
|
|
122
|
+
| Next | `/rai-story-review` (story) or `/rai-epic-close` (epic) |
|
|
123
|
+
|
|
124
|
+
## Quality Checklist
|
|
125
|
+
|
|
126
|
+
- [ ] Project language detected before filtering files
|
|
127
|
+
- [ ] All changed files for detected language read before reviewing
|
|
128
|
+
- [ ] Design doc loaded for intent context
|
|
129
|
+
- [ ] Every finding cites specific file:line and heuristic ID (H1-H16)
|
|
130
|
+
- [ ] Questions ratio >30% of findings (humility signal)
|
|
131
|
+
- [ ] "No issues found" is a valid outcome — do not invent findings
|
|
132
|
+
|
|
133
|
+
## References
|
|
134
|
+
|
|
135
|
+
- Evidence: `work/research/architecture-review/`
|
|
136
|
+
- Complements: `/rai-quality-review` (correctness), `/rai-story-review` (retrospective)
|
|
137
|
+
- Framework: Beck's Simple Design Rules, Fowler's Code Smells, Silva et al. (ESEM 2024)
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rai-debug
|
|
3
|
+
description: >
|
|
4
|
+
Systematic root cause analysis using lean methods (5 Whys, Ishikawa, Gemba).
|
|
5
|
+
Use when encountering unexpected behavior, errors, or defects to find and
|
|
6
|
+
fix the true root cause rather than symptoms.
|
|
7
|
+
|
|
8
|
+
license: MIT
|
|
9
|
+
|
|
10
|
+
metadata:
|
|
11
|
+
raise.work_cycle: utility
|
|
12
|
+
raise.frequency: as-needed
|
|
13
|
+
raise.fase: "0"
|
|
14
|
+
raise.prerequisites: ""
|
|
15
|
+
raise.next: story-plan
|
|
16
|
+
raise.gate: ""
|
|
17
|
+
raise.adaptable: "true"
|
|
18
|
+
raise.version: "2.1.0"
|
|
19
|
+
raise.visibility: public
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
# Debug
|
|
23
|
+
|
|
24
|
+
## Purpose
|
|
25
|
+
|
|
26
|
+
Systematically identify and fix the root cause of defects using lean methods. Stop fixing symptoms — find the true cause.
|
|
27
|
+
|
|
28
|
+
## Mastery Levels (ShuHaRi)
|
|
29
|
+
|
|
30
|
+
- **Shu**: Follow triage → method → fix strictly; document each step
|
|
31
|
+
- **Ha**: Combine methods (Ishikawa + 5 Whys); adapt depth to complexity
|
|
32
|
+
- **Ri**: Develop domain-specific diagnostic patterns; feed recurring patterns to graph
|
|
33
|
+
|
|
34
|
+
## Context
|
|
35
|
+
|
|
36
|
+
**When to use:** Unexpected behavior, unclear test failures, integration issues, performance problems, bug fix stories.
|
|
37
|
+
|
|
38
|
+
**When to skip:** Obvious typos, simple syntax errors — go directly to fix.
|
|
39
|
+
|
|
40
|
+
**Inputs:** Problem statement, steps to reproduce, error messages/symptoms. **Time boxing:** XS (5 min), S (15 min), M (30 min), L (60 min). Escalate if exceeded.
|
|
41
|
+
|
|
42
|
+
## Steps
|
|
43
|
+
|
|
44
|
+
### Step 0: Triage — Classify Complexity
|
|
45
|
+
|
|
46
|
+
Before choosing a method, classify the bug:
|
|
47
|
+
|
|
48
|
+
| Tier | Criteria | Method | Output |
|
|
49
|
+
|------|----------|--------|--------|
|
|
50
|
+
| **XS** | Cause evident, fix obvious | Skip to Step 3 | One-liner in scope/commit |
|
|
51
|
+
| **S** | Cause obscure, single causal chain | 5 Whys (Step 2) | Summary block |
|
|
52
|
+
| **M/L** | Multiple possible causes | Ishikawa (Step 2b) | `analysis.md` |
|
|
53
|
+
|
|
54
|
+
State the tier explicitly before proceeding.
|
|
55
|
+
|
|
56
|
+
<verification>
|
|
57
|
+
Tier declared. Method selected.
|
|
58
|
+
</verification>
|
|
59
|
+
|
|
60
|
+
### Step 1: Define the Problem (Genchi Genbutsu)
|
|
61
|
+
|
|
62
|
+
Go see the actual problem. Reproduce it, capture evidence:
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
WHAT: [specific behavior observed]
|
|
66
|
+
WHEN: [conditions / triggers]
|
|
67
|
+
WHERE: [file:line or component]
|
|
68
|
+
EXPECTED: [what should happen instead]
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
<verification>
|
|
72
|
+
Problem is specific and reproducible (or minimal fixture built).
|
|
73
|
+
</verification>
|
|
74
|
+
|
|
75
|
+
<if-blocked>
|
|
76
|
+
Cannot reproduce → gather logs, add instrumentation, build minimal fixture.
|
|
77
|
+
</if-blocked>
|
|
78
|
+
|
|
79
|
+
### Step 2: Root Cause Analysis (S bugs — 5 Whys)
|
|
80
|
+
|
|
81
|
+
Ask "Why?" five times, staying on one factual causal chain:
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
Problem: [statement]
|
|
85
|
+
1. Why? → [first-level cause, with evidence]
|
|
86
|
+
2. Why? → [second-level cause]
|
|
87
|
+
3. Why? → [third-level cause]
|
|
88
|
+
4. Why? → [fourth-level cause]
|
|
89
|
+
5. Why? → [root cause]
|
|
90
|
+
Countermeasure: [fix]
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Rules:
|
|
94
|
+
- Each answer must be factual, not speculative
|
|
95
|
+
- Stop when you reach something actionable and changeable
|
|
96
|
+
- "Human error" is never a root cause — ask why the error was possible
|
|
97
|
+
|
|
98
|
+
<verification>
|
|
99
|
+
Root cause is actionable and explains all symptoms.
|
|
100
|
+
</verification>
|
|
101
|
+
|
|
102
|
+
<if-blocked>
|
|
103
|
+
Chain branches → switch to Ishikawa (Step 2b).
|
|
104
|
+
</if-blocked>
|
|
105
|
+
|
|
106
|
+
### Step 2b: Ishikawa Diagram (M/L bugs — multiple causes)
|
|
107
|
+
|
|
108
|
+
Explore 6 M's: Method, Machine, Material, Measurement, Manpower, Milieu (env/config drift).
|
|
109
|
+
|
|
110
|
+
Identify top 2-3 hypotheses, investigate systematically:
|
|
111
|
+
|
|
112
|
+
| Hypothesis | Test | Result | Conclusion |
|
|
113
|
+
|------------|------|--------|------------|
|
|
114
|
+
| [Cause 1] | [How tested] | [What happened] | Confirmed/Eliminated |
|
|
115
|
+
|
|
116
|
+
<verification>
|
|
117
|
+
Root cause confirmed with evidence. Competing hypotheses eliminated.
|
|
118
|
+
</verification>
|
|
119
|
+
|
|
120
|
+
### Step 3: Fix & Prevent
|
|
121
|
+
|
|
122
|
+
Fix the root cause (not symptoms). Write the regression test first (RED), then fix (GREEN).
|
|
123
|
+
|
|
124
|
+
- [ ] Fix addresses confirmed root cause
|
|
125
|
+
- [ ] Regression test written (RED → GREEN)
|
|
126
|
+
- [ ] Original problem no longer reproduces
|
|
127
|
+
- [ ] All existing tests pass
|
|
128
|
+
|
|
129
|
+
Prevention (choose what applies):
|
|
130
|
+
- Regression test (always for S+)
|
|
131
|
+
- Input validation at boundary
|
|
132
|
+
- Documentation or ADR update
|
|
133
|
+
- `rai pattern add` for recurring systemic issues
|
|
134
|
+
|
|
135
|
+
<verification>
|
|
136
|
+
Problem resolved. Tests pass.
|
|
137
|
+
</verification>
|
|
138
|
+
|
|
139
|
+
<if-blocked>
|
|
140
|
+
Fix incomplete → document partial fix, create follow-up task.
|
|
141
|
+
</if-blocked>
|
|
142
|
+
|
|
143
|
+
**Feed `/rai-story-plan`** — after fixing, name the tasks explicitly:
|
|
144
|
+
- Fix task, regression test task, prevention task (if any)
|
|
145
|
+
- Systemic finding: `rai pattern add "[statement]" --context "[keywords]" --type behavioral`
|
|
146
|
+
|
|
147
|
+
## Output
|
|
148
|
+
|
|
149
|
+
| Tier | Artifact | Destination |
|
|
150
|
+
|------|----------|-------------|
|
|
151
|
+
| XS | One-liner root cause + fix | Scope commit or inline |
|
|
152
|
+
| S | Summary block (root cause, fix, prevention) | Story scope doc |
|
|
153
|
+
| M/L | Full analysis | `work/debug/{issue-name}/analysis.md` |
|
|
154
|
+
| Any | Story plan tasks | Fed to `/rai-story-plan` |
|
|
155
|
+
|
|
156
|
+
## Quality Checklist
|
|
157
|
+
|
|
158
|
+
- [ ] Tier declared before any analysis
|
|
159
|
+
- [ ] Problem is specific and reproducible
|
|
160
|
+
- [ ] Root cause identified with evidence (not speculation)
|
|
161
|
+
- [ ] Fix addresses root cause, not symptoms
|
|
162
|
+
- [ ] Regression test written (RED before GREEN)
|
|
163
|
+
- [ ] Time box respected — escalate if exceeded
|
|
164
|
+
- [ ] Story plan tasks named
|
|
165
|
+
- [ ] NEVER guess — hypothesis first, then test. NEVER say "human error" — ask why the error was possible
|
|
166
|
+
|
|
167
|
+
## References
|
|
168
|
+
|
|
169
|
+
- 5 Whys: Taiichi Ohno, Toyota Production System
|
|
170
|
+
- Ishikawa: Kaoru Ishikawa, "Guide to Quality Control"
|
|
171
|
+
- Gemba: "Go and see" — Jidoka: stop on defects, fix immediately
|