ai-sdlc-kit 0.1.0__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.
- ai_sdlc/__init__.py +1 -0
- ai_sdlc/cli.py +144 -0
- ai_sdlc/skills/architecture-diagram/SKILL.md +163 -0
- ai_sdlc/skills/architecture-diagram/assets/template.html +319 -0
- ai_sdlc/skills/build/SKILL.md +43 -0
- ai_sdlc/skills/qa/SKILL.md +52 -0
- ai_sdlc/skills/roadmap/SKILL.md +53 -0
- ai_sdlc/skills/sdlc-init/SKILL.md +91 -0
- ai_sdlc/skills/ship/SKILL.md +52 -0
- ai_sdlc/skills/spec/SKILL.md +106 -0
- ai_sdlc_kit-0.1.0.dist-info/METADATA +178 -0
- ai_sdlc_kit-0.1.0.dist-info/RECORD +15 -0
- ai_sdlc_kit-0.1.0.dist-info/WHEEL +4 -0
- ai_sdlc_kit-0.1.0.dist-info/entry_points.txt +2 -0
- ai_sdlc_kit-0.1.0.dist-info/licenses/LICENSE +21 -0
ai_sdlc/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""AI-SDLC — spec-driven SDLC skills for AI coding agents."""
|
ai_sdlc/cli.py
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"""AI-SDLC CLI — installs bundled skills into your project or home directory."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
import importlib.metadata as metadata
|
|
7
|
+
import importlib.resources as resources
|
|
8
|
+
import shutil
|
|
9
|
+
import sys
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
AGENT_DIRS = {
|
|
13
|
+
"claude": ".claude/skills",
|
|
14
|
+
"cursor": ".cursor/skills",
|
|
15
|
+
"windsurf": ".windsurf/skills",
|
|
16
|
+
"gemini": ".gemini/skills",
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
DIST_NAME = "ai-sdlc-kit"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _skills_root():
|
|
23
|
+
bundled = resources.files("ai_sdlc") / "skills"
|
|
24
|
+
if bundled.is_dir():
|
|
25
|
+
return bundled
|
|
26
|
+
fallback = Path(__file__).resolve().parents[2] / "skills"
|
|
27
|
+
if fallback.is_dir():
|
|
28
|
+
return fallback
|
|
29
|
+
raise FileNotFoundError(
|
|
30
|
+
"could not locate the bundled 'skills' directory — "
|
|
31
|
+
"the ai-sdlc-kit package may be installed incorrectly"
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _copy_tree(src, dst: Path) -> None:
|
|
36
|
+
dst.mkdir(parents=True, exist_ok=True)
|
|
37
|
+
for entry in src.iterdir():
|
|
38
|
+
target = dst / entry.name
|
|
39
|
+
if entry.is_dir():
|
|
40
|
+
_copy_tree(entry, target)
|
|
41
|
+
else:
|
|
42
|
+
target.write_bytes(entry.read_bytes())
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _install_for_agent(agent: str, target: Path, force: bool) -> None:
|
|
46
|
+
agent_dir = target / AGENT_DIRS[agent]
|
|
47
|
+
installed = 0
|
|
48
|
+
skipped = 0
|
|
49
|
+
for skill in sorted(_skills_root().iterdir(), key=lambda p: p.name):
|
|
50
|
+
if not skill.is_dir():
|
|
51
|
+
continue
|
|
52
|
+
dest = agent_dir / skill.name
|
|
53
|
+
if dest.exists() and not force:
|
|
54
|
+
print(f"skip {skill.name} (exists)")
|
|
55
|
+
skipped += 1
|
|
56
|
+
continue
|
|
57
|
+
if dest.exists():
|
|
58
|
+
shutil.rmtree(dest)
|
|
59
|
+
_copy_tree(skill, dest)
|
|
60
|
+
print(f"installed {skill.name}")
|
|
61
|
+
installed += 1
|
|
62
|
+
print(f"installed {installed}, skipped {skipped} → {agent_dir}")
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _cmd_install(args: argparse.Namespace) -> int:
|
|
66
|
+
target = Path.home() if args.global_ else Path(args.target)
|
|
67
|
+
agents = list(AGENT_DIRS) if args.agent == "all" else [args.agent]
|
|
68
|
+
for agent in agents:
|
|
69
|
+
_install_for_agent(agent, target, args.force)
|
|
70
|
+
return 0
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _cmd_list(args: argparse.Namespace) -> int:
|
|
74
|
+
for skill in sorted(_skills_root().iterdir(), key=lambda p: p.name):
|
|
75
|
+
if skill.is_dir():
|
|
76
|
+
print(skill.name)
|
|
77
|
+
return 0
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def _version() -> str:
|
|
81
|
+
try:
|
|
82
|
+
return metadata.version(DIST_NAME)
|
|
83
|
+
except metadata.PackageNotFoundError:
|
|
84
|
+
return "0.0.0-dev"
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def build_parser() -> argparse.ArgumentParser:
|
|
88
|
+
parser = argparse.ArgumentParser(
|
|
89
|
+
prog="ai-sdlc", description="Install AI-SDLC skills for your coding agent."
|
|
90
|
+
)
|
|
91
|
+
parser.add_argument("--version", action="store_true", help="print the version and exit")
|
|
92
|
+
|
|
93
|
+
subparsers = parser.add_subparsers(dest="command")
|
|
94
|
+
|
|
95
|
+
install_parser = subparsers.add_parser(
|
|
96
|
+
"install", help="install skills into an agent's skills directory"
|
|
97
|
+
)
|
|
98
|
+
install_parser.add_argument(
|
|
99
|
+
"--agent",
|
|
100
|
+
choices=[*AGENT_DIRS, "all"],
|
|
101
|
+
default="claude",
|
|
102
|
+
help="which agent to install skills for (default: claude)",
|
|
103
|
+
)
|
|
104
|
+
install_parser.add_argument(
|
|
105
|
+
"--target", default=".", help="target project directory (default: current directory)"
|
|
106
|
+
)
|
|
107
|
+
install_parser.add_argument(
|
|
108
|
+
"--global",
|
|
109
|
+
dest="global_",
|
|
110
|
+
action="store_true",
|
|
111
|
+
help="install into your home directory instead of --target",
|
|
112
|
+
)
|
|
113
|
+
install_parser.add_argument(
|
|
114
|
+
"--force", action="store_true", help="overwrite existing skill folders"
|
|
115
|
+
)
|
|
116
|
+
install_parser.set_defaults(func=_cmd_install)
|
|
117
|
+
|
|
118
|
+
list_parser = subparsers.add_parser("list", help="list bundled skills")
|
|
119
|
+
list_parser.set_defaults(func=_cmd_list)
|
|
120
|
+
|
|
121
|
+
return parser
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def main(argv: list[str] | None = None) -> int:
|
|
125
|
+
parser = build_parser()
|
|
126
|
+
args = parser.parse_args(argv)
|
|
127
|
+
|
|
128
|
+
if args.version:
|
|
129
|
+
print(_version())
|
|
130
|
+
return 0
|
|
131
|
+
|
|
132
|
+
if not getattr(args, "command", None):
|
|
133
|
+
parser.print_help()
|
|
134
|
+
return 1
|
|
135
|
+
|
|
136
|
+
try:
|
|
137
|
+
return args.func(args)
|
|
138
|
+
except FileNotFoundError as exc:
|
|
139
|
+
print(f"error: {exc}", file=sys.stderr)
|
|
140
|
+
return 1
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
if __name__ == "__main__":
|
|
144
|
+
sys.exit(main())
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: architecture-diagram
|
|
3
|
+
description: Create professional, dark-themed architecture diagrams as standalone HTML files with SVG graphics. Use when the user asks for system architecture diagrams, infrastructure diagrams, cloud architecture visualizations, security diagrams, network topology diagrams, or any technical diagram showing system components and their relationships.
|
|
4
|
+
license: MIT
|
|
5
|
+
metadata:
|
|
6
|
+
version: "1.0"
|
|
7
|
+
author: Cocoon AI (hello@cocoon-ai.com)
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Architecture Diagram Skill
|
|
11
|
+
|
|
12
|
+
Create professional technical architecture diagrams as self-contained HTML files with inline SVG graphics and CSS styling.
|
|
13
|
+
|
|
14
|
+
## Design System
|
|
15
|
+
|
|
16
|
+
### Color Palette
|
|
17
|
+
|
|
18
|
+
Use these semantic colors for component types:
|
|
19
|
+
|
|
20
|
+
| Component Type | Fill (rgba) | Stroke |
|
|
21
|
+
|---------------|-------------|--------|
|
|
22
|
+
| Frontend | `rgba(8, 51, 68, 0.4)` | `#22d3ee` (cyan-400) |
|
|
23
|
+
| Backend | `rgba(6, 78, 59, 0.4)` | `#34d399` (emerald-400) |
|
|
24
|
+
| Database | `rgba(76, 29, 149, 0.4)` | `#a78bfa` (violet-400) |
|
|
25
|
+
| AWS/Cloud | `rgba(120, 53, 15, 0.3)` | `#fbbf24` (amber-400) |
|
|
26
|
+
| Security | `rgba(136, 19, 55, 0.4)` | `#fb7185` (rose-400) |
|
|
27
|
+
| Message Bus | `rgba(251, 146, 60, 0.3)` | `#fb923c` (orange-400) |
|
|
28
|
+
| External/Generic | `rgba(30, 41, 59, 0.5)` | `#94a3b8` (slate-400) |
|
|
29
|
+
|
|
30
|
+
### Typography
|
|
31
|
+
|
|
32
|
+
Use JetBrains Mono for all text (monospace, technical aesthetic):
|
|
33
|
+
```html
|
|
34
|
+
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Font sizes: 12px for component names, 9px for sublabels, 8px for annotations, 7px for tiny labels.
|
|
38
|
+
|
|
39
|
+
### Visual Elements
|
|
40
|
+
|
|
41
|
+
**Background:** `#020617` (slate-950) with subtle grid pattern:
|
|
42
|
+
```svg
|
|
43
|
+
<pattern id="grid" width="40" height="40" patternUnits="userSpaceOnUse">
|
|
44
|
+
<path d="M 40 0 L 0 0 0 40" fill="none" stroke="#1e293b" stroke-width="0.5"/>
|
|
45
|
+
</pattern>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**Component boxes:** Rounded rectangles (`rx="6"`) with 1.5px stroke, semi-transparent fills.
|
|
49
|
+
|
|
50
|
+
**Security groups:** Dashed stroke (`stroke-dasharray="4,4"`), transparent fill, rose color.
|
|
51
|
+
|
|
52
|
+
**Region boundaries:** Larger dashed stroke (`stroke-dasharray="8,4"`), amber color, `rx="12"`.
|
|
53
|
+
|
|
54
|
+
**Arrows:** Use SVG marker for arrowheads:
|
|
55
|
+
```svg
|
|
56
|
+
<marker id="arrowhead" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
|
|
57
|
+
<polygon points="0 0, 10 3.5, 0 7" fill="#64748b" />
|
|
58
|
+
</marker>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**Arrow z-order:** Draw connection arrows early in the SVG (after the background grid) so they render behind component boxes. SVG elements are painted in document order, so arrows drawn first will appear behind shapes drawn later.
|
|
62
|
+
|
|
63
|
+
**Masking arrows behind transparent fills:** Since component boxes use semi-transparent fills (`rgba(..., 0.4)`), arrows behind them will show through. To fully mask arrows, draw an opaque background rect (e.g., `fill="#0f172a"`) at the same position before drawing the semi-transparent styled rect on top:
|
|
64
|
+
```svg
|
|
65
|
+
<!-- Opaque background to mask arrows -->
|
|
66
|
+
<rect x="X" y="Y" width="W" height="H" rx="6" fill="#0f172a"/>
|
|
67
|
+
<!-- Styled component on top -->
|
|
68
|
+
<rect x="X" y="Y" width="W" height="H" rx="6" fill="rgba(76, 29, 149, 0.4)" stroke="#a78bfa" stroke-width="1.5"/>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**Auth/security flows:** Dashed lines in rose color (`#fb7185`).
|
|
72
|
+
|
|
73
|
+
**Message buses / Event buses:** Small connector elements between services. Use orange color (`#fb923c` stroke, `rgba(251, 146, 60, 0.3)` fill):
|
|
74
|
+
```svg
|
|
75
|
+
<rect x="X" y="Y" width="120" height="20" rx="4" fill="rgba(251, 146, 60, 0.3)" stroke="#fb923c" stroke-width="1"/>
|
|
76
|
+
<text x="CENTER_X" y="Y+14" fill="#fb923c" font-size="7" text-anchor="middle">Kafka / RabbitMQ</text>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Spacing Rules
|
|
80
|
+
|
|
81
|
+
**CRITICAL:** When stacking components vertically, ensure proper spacing to avoid overlaps:
|
|
82
|
+
|
|
83
|
+
- **Standard component height:** 60px for services, 80-120px for larger components
|
|
84
|
+
- **Minimum vertical gap between components:** 40px
|
|
85
|
+
- **Inline connectors (message buses):** Place IN the gap between components, not overlapping
|
|
86
|
+
|
|
87
|
+
**Example vertical layout:**
|
|
88
|
+
```
|
|
89
|
+
Component A: y=70, height=60 → ends at y=130
|
|
90
|
+
Gap: y=130 to y=170 → 40px gap, place bus at y=140 (20px tall)
|
|
91
|
+
Component B: y=170, height=60 → ends at y=230
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Wrong:** Placing a message bus at y=160 when Component B starts at y=170 (causes overlap)
|
|
95
|
+
**Right:** Placing a message bus at y=140, centered in the 40px gap (y=130 to y=170)
|
|
96
|
+
|
|
97
|
+
### Legend Placement
|
|
98
|
+
|
|
99
|
+
**CRITICAL:** Place legends OUTSIDE all boundary boxes (region boundaries, cluster boundaries, security groups).
|
|
100
|
+
|
|
101
|
+
- Calculate where all boundaries end (y position + height)
|
|
102
|
+
- Place legend at least 20px below the lowest boundary
|
|
103
|
+
- Expand SVG viewBox height if needed to accommodate
|
|
104
|
+
|
|
105
|
+
**Example:**
|
|
106
|
+
```
|
|
107
|
+
Kubernetes Cluster: y=30, height=460 → ends at y=490
|
|
108
|
+
Legend should start at: y=510 or below
|
|
109
|
+
SVG viewBox height: at least 560 to fit legend
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**Wrong:** Legend at y=470 inside a cluster boundary that ends at y=490
|
|
113
|
+
**Right:** Legend at y=510, below the cluster boundary, with viewBox height extended
|
|
114
|
+
|
|
115
|
+
### Layout Structure
|
|
116
|
+
|
|
117
|
+
1. **Header** - Title with pulsing dot indicator, subtitle
|
|
118
|
+
2. **Main SVG diagram** - Contained in rounded border card
|
|
119
|
+
3. **Summary cards** - Grid of 3 cards below diagram with key details
|
|
120
|
+
4. **Footer** - Minimal metadata line
|
|
121
|
+
|
|
122
|
+
### Component Box Pattern
|
|
123
|
+
|
|
124
|
+
```svg
|
|
125
|
+
<rect x="X" y="Y" width="W" height="H" rx="6" fill="FILL_COLOR" stroke="STROKE_COLOR" stroke-width="1.5"/>
|
|
126
|
+
<text x="CENTER_X" y="Y+20" fill="white" font-size="11" font-weight="600" text-anchor="middle">LABEL</text>
|
|
127
|
+
<text x="CENTER_X" y="Y+36" fill="#94a3b8" font-size="9" text-anchor="middle">sublabel</text>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Info Card Pattern
|
|
131
|
+
|
|
132
|
+
```html
|
|
133
|
+
<div class="card">
|
|
134
|
+
<div class="card-header">
|
|
135
|
+
<div class="card-dot COLOR"></div>
|
|
136
|
+
<h3>Title</h3>
|
|
137
|
+
</div>
|
|
138
|
+
<ul>
|
|
139
|
+
<li>• Item one</li>
|
|
140
|
+
<li>• Item two</li>
|
|
141
|
+
</ul>
|
|
142
|
+
</div>
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Template
|
|
146
|
+
|
|
147
|
+
Copy and customize the template at `assets/template.html`. Key customization points:
|
|
148
|
+
|
|
149
|
+
1. Update the `<title>` and header text
|
|
150
|
+
2. Modify SVG viewBox dimensions if needed (default: `1000 x 680`)
|
|
151
|
+
3. Add/remove/reposition component boxes
|
|
152
|
+
4. Draw connection arrows between components
|
|
153
|
+
5. Update the three summary cards
|
|
154
|
+
6. Update footer metadata
|
|
155
|
+
|
|
156
|
+
## Output
|
|
157
|
+
|
|
158
|
+
Always produce a single self-contained `.html` file with:
|
|
159
|
+
- Embedded CSS (no external stylesheets except Google Fonts)
|
|
160
|
+
- Inline SVG (no external images)
|
|
161
|
+
- No JavaScript required (pure CSS animations)
|
|
162
|
+
|
|
163
|
+
The file should render correctly when opened directly in any modern browser.
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>[PROJECT NAME] Architecture Diagram</title>
|
|
7
|
+
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
8
|
+
<style>
|
|
9
|
+
* {
|
|
10
|
+
margin: 0;
|
|
11
|
+
padding: 0;
|
|
12
|
+
box-sizing: border-box;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
body {
|
|
16
|
+
font-family: 'JetBrains Mono', monospace;
|
|
17
|
+
background: #020617;
|
|
18
|
+
min-height: 100vh;
|
|
19
|
+
padding: 2rem;
|
|
20
|
+
color: white;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.container {
|
|
24
|
+
max-width: 1200px;
|
|
25
|
+
margin: 0 auto;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.header {
|
|
29
|
+
margin-bottom: 2rem;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.header-row {
|
|
33
|
+
display: flex;
|
|
34
|
+
align-items: center;
|
|
35
|
+
gap: 1rem;
|
|
36
|
+
margin-bottom: 0.5rem;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.pulse-dot {
|
|
40
|
+
width: 12px;
|
|
41
|
+
height: 12px;
|
|
42
|
+
background: #22d3ee;
|
|
43
|
+
border-radius: 50%;
|
|
44
|
+
animation: pulse 2s infinite;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@keyframes pulse {
|
|
48
|
+
0%, 100% { opacity: 1; }
|
|
49
|
+
50% { opacity: 0.5; }
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
h1 {
|
|
53
|
+
font-size: 1.5rem;
|
|
54
|
+
font-weight: 700;
|
|
55
|
+
letter-spacing: -0.025em;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.subtitle {
|
|
59
|
+
color: #94a3b8;
|
|
60
|
+
font-size: 0.875rem;
|
|
61
|
+
margin-left: 1.75rem;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.diagram-container {
|
|
65
|
+
background: rgba(15, 23, 42, 0.5);
|
|
66
|
+
border-radius: 1rem;
|
|
67
|
+
border: 1px solid #1e293b;
|
|
68
|
+
padding: 1.5rem;
|
|
69
|
+
overflow-x: auto;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
svg {
|
|
73
|
+
width: 100%;
|
|
74
|
+
min-width: 900px;
|
|
75
|
+
display: block;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.cards {
|
|
79
|
+
display: grid;
|
|
80
|
+
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
|
81
|
+
gap: 1rem;
|
|
82
|
+
margin-top: 2rem;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.card {
|
|
86
|
+
background: rgba(15, 23, 42, 0.5);
|
|
87
|
+
border-radius: 0.75rem;
|
|
88
|
+
border: 1px solid #1e293b;
|
|
89
|
+
padding: 1.25rem;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.card-header {
|
|
93
|
+
display: flex;
|
|
94
|
+
align-items: center;
|
|
95
|
+
gap: 0.5rem;
|
|
96
|
+
margin-bottom: 0.75rem;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.card-dot {
|
|
100
|
+
width: 8px;
|
|
101
|
+
height: 8px;
|
|
102
|
+
border-radius: 50%;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.card-dot.cyan { background: #22d3ee; }
|
|
106
|
+
.card-dot.emerald { background: #34d399; }
|
|
107
|
+
.card-dot.violet { background: #a78bfa; }
|
|
108
|
+
.card-dot.amber { background: #fbbf24; }
|
|
109
|
+
.card-dot.rose { background: #fb7185; }
|
|
110
|
+
|
|
111
|
+
.card h3 {
|
|
112
|
+
font-size: 0.875rem;
|
|
113
|
+
font-weight: 600;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.card ul {
|
|
117
|
+
list-style: none;
|
|
118
|
+
color: #94a3b8;
|
|
119
|
+
font-size: 0.75rem;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.card li {
|
|
123
|
+
margin-bottom: 0.375rem;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.footer {
|
|
127
|
+
text-align: center;
|
|
128
|
+
margin-top: 1.5rem;
|
|
129
|
+
color: #475569;
|
|
130
|
+
font-size: 0.75rem;
|
|
131
|
+
}
|
|
132
|
+
</style>
|
|
133
|
+
</head>
|
|
134
|
+
<body>
|
|
135
|
+
<div class="container">
|
|
136
|
+
<!-- Header -->
|
|
137
|
+
<div class="header">
|
|
138
|
+
<div class="header-row">
|
|
139
|
+
<div class="pulse-dot"></div>
|
|
140
|
+
<h1>[PROJECT NAME] Architecture</h1>
|
|
141
|
+
</div>
|
|
142
|
+
<p class="subtitle">[Subtitle description]</p>
|
|
143
|
+
</div>
|
|
144
|
+
|
|
145
|
+
<!-- Main Diagram -->
|
|
146
|
+
<div class="diagram-container">
|
|
147
|
+
<svg viewBox="0 0 1000 680">
|
|
148
|
+
<!-- Definitions -->
|
|
149
|
+
<defs>
|
|
150
|
+
<marker id="arrowhead" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
|
|
151
|
+
<polygon points="0 0, 10 3.5, 0 7" fill="#64748b" />
|
|
152
|
+
</marker>
|
|
153
|
+
<pattern id="grid" width="40" height="40" patternUnits="userSpaceOnUse">
|
|
154
|
+
<path d="M 40 0 L 0 0 0 40" fill="none" stroke="#1e293b" stroke-width="0.5"/>
|
|
155
|
+
</pattern>
|
|
156
|
+
</defs>
|
|
157
|
+
|
|
158
|
+
<!-- Background Grid -->
|
|
159
|
+
<rect width="100%" height="100%" fill="url(#grid)" />
|
|
160
|
+
|
|
161
|
+
<!-- =================================================================
|
|
162
|
+
COMPONENT EXAMPLES - Copy and customize these patterns
|
|
163
|
+
================================================================= -->
|
|
164
|
+
|
|
165
|
+
<!-- External/Generic Component -->
|
|
166
|
+
<rect x="30" y="280" width="100" height="50" rx="6" fill="rgba(30, 41, 59, 0.5)" stroke="#94a3b8" stroke-width="1.5"/>
|
|
167
|
+
<text x="80" y="300" fill="white" font-size="11" font-weight="600" text-anchor="middle">Users</text>
|
|
168
|
+
<text x="80" y="316" fill="#94a3b8" font-size="9" text-anchor="middle">Browser/Mobile</text>
|
|
169
|
+
|
|
170
|
+
<!-- Security Component -->
|
|
171
|
+
<rect x="30" y="80" width="100" height="60" rx="6" fill="rgba(136, 19, 55, 0.4)" stroke="#fb7185" stroke-width="1.5"/>
|
|
172
|
+
<text x="80" y="105" fill="white" font-size="11" font-weight="600" text-anchor="middle">Auth Provider</text>
|
|
173
|
+
<text x="80" y="121" fill="#94a3b8" font-size="9" text-anchor="middle">OAuth 2.0</text>
|
|
174
|
+
|
|
175
|
+
<!-- Region/Cloud Boundary -->
|
|
176
|
+
<rect x="160" y="40" width="820" height="620" rx="12" fill="rgba(251, 191, 36, 0.05)" stroke="#fbbf24" stroke-width="1" stroke-dasharray="8,4"/>
|
|
177
|
+
<text x="172" y="58" fill="#fbbf24" font-size="10" font-weight="600">AWS Region: us-west-2</text>
|
|
178
|
+
|
|
179
|
+
<!-- AWS/Cloud Service -->
|
|
180
|
+
<rect x="200" y="280" width="110" height="50" rx="6" fill="rgba(120, 53, 15, 0.3)" stroke="#fbbf24" stroke-width="1.5"/>
|
|
181
|
+
<text x="255" y="300" fill="white" font-size="11" font-weight="600" text-anchor="middle">CloudFront</text>
|
|
182
|
+
<text x="255" y="316" fill="#94a3b8" font-size="9" text-anchor="middle">CDN</text>
|
|
183
|
+
|
|
184
|
+
<!-- Multi-line AWS Component (S3 Buckets example) -->
|
|
185
|
+
<rect x="200" y="380" width="110" height="100" rx="6" fill="rgba(120, 53, 15, 0.3)" stroke="#fbbf24" stroke-width="1.5"/>
|
|
186
|
+
<text x="255" y="400" fill="white" font-size="11" font-weight="600" text-anchor="middle">S3 Buckets</text>
|
|
187
|
+
<text x="255" y="420" fill="#94a3b8" font-size="8" text-anchor="middle">• bucket-one</text>
|
|
188
|
+
<text x="255" y="434" fill="#94a3b8" font-size="8" text-anchor="middle">• bucket-two</text>
|
|
189
|
+
<text x="255" y="448" fill="#94a3b8" font-size="8" text-anchor="middle">• bucket-three</text>
|
|
190
|
+
<text x="255" y="466" fill="#fbbf24" font-size="7" text-anchor="middle">OAI Protected</text>
|
|
191
|
+
|
|
192
|
+
<!-- Security Group (dashed boundary) -->
|
|
193
|
+
<rect x="350" y="265" width="120" height="80" rx="8" fill="transparent" stroke="#fb7185" stroke-width="1" stroke-dasharray="4,4"/>
|
|
194
|
+
<text x="358" y="279" fill="#fb7185" font-size="8">sg-name :port</text>
|
|
195
|
+
|
|
196
|
+
<!-- Component inside security group -->
|
|
197
|
+
<rect x="360" y="280" width="100" height="50" rx="6" fill="rgba(120, 53, 15, 0.3)" stroke="#fbbf24" stroke-width="1.5"/>
|
|
198
|
+
<text x="410" y="300" fill="white" font-size="11" font-weight="600" text-anchor="middle">Load Balancer</text>
|
|
199
|
+
<text x="410" y="316" fill="#94a3b8" font-size="9" text-anchor="middle">HTTPS :443</text>
|
|
200
|
+
|
|
201
|
+
<!-- Backend Component -->
|
|
202
|
+
<rect x="510" y="280" width="110" height="50" rx="6" fill="rgba(6, 78, 59, 0.4)" stroke="#34d399" stroke-width="1.5"/>
|
|
203
|
+
<text x="565" y="300" fill="white" font-size="11" font-weight="600" text-anchor="middle">API Server</text>
|
|
204
|
+
<text x="565" y="316" fill="#94a3b8" font-size="9" text-anchor="middle">FastAPI :8000</text>
|
|
205
|
+
|
|
206
|
+
<!-- Database Component -->
|
|
207
|
+
<rect x="700" y="280" width="120" height="50" rx="6" fill="rgba(76, 29, 149, 0.4)" stroke="#a78bfa" stroke-width="1.5"/>
|
|
208
|
+
<text x="760" y="300" fill="white" font-size="11" font-weight="600" text-anchor="middle">Database</text>
|
|
209
|
+
<text x="760" y="316" fill="#94a3b8" font-size="9" text-anchor="middle">PostgreSQL</text>
|
|
210
|
+
|
|
211
|
+
<!-- Frontend Component -->
|
|
212
|
+
<rect x="200" y="520" width="200" height="110" rx="8" fill="rgba(8, 51, 68, 0.4)" stroke="#22d3ee" stroke-width="1.5"/>
|
|
213
|
+
<text x="300" y="545" fill="white" font-size="12" font-weight="600" text-anchor="middle">Frontend</text>
|
|
214
|
+
<text x="300" y="565" fill="#94a3b8" font-size="9" text-anchor="middle">React + TypeScript</text>
|
|
215
|
+
<text x="300" y="580" fill="#94a3b8" font-size="9" text-anchor="middle">Additional detail</text>
|
|
216
|
+
<text x="300" y="595" fill="#94a3b8" font-size="9" text-anchor="middle">More info</text>
|
|
217
|
+
<text x="300" y="615" fill="#22d3ee" font-size="8" text-anchor="middle">domain.example.com</text>
|
|
218
|
+
|
|
219
|
+
<!-- =================================================================
|
|
220
|
+
ARROW EXAMPLES
|
|
221
|
+
================================================================= -->
|
|
222
|
+
|
|
223
|
+
<!-- Standard arrow with label -->
|
|
224
|
+
<line x1="130" y1="305" x2="198" y2="305" stroke="#22d3ee" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
225
|
+
<text x="164" y="299" fill="#94a3b8" font-size="9" text-anchor="middle">HTTPS</text>
|
|
226
|
+
|
|
227
|
+
<!-- Simple arrow (no label) -->
|
|
228
|
+
<line x1="310" y1="305" x2="358" y2="305" stroke="#22d3ee" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
229
|
+
|
|
230
|
+
<!-- Vertical arrow -->
|
|
231
|
+
<line x1="255" y1="330" x2="255" y2="378" stroke="#fbbf24" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
232
|
+
<text x="270" y="358" fill="#94a3b8" font-size="9">OAI</text>
|
|
233
|
+
|
|
234
|
+
<!-- Dashed arrow (for auth/security flows) -->
|
|
235
|
+
<line x1="460" y1="305" x2="508" y2="305" stroke="#34d399" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
236
|
+
<line x1="620" y1="305" x2="698" y2="305" stroke="#a78bfa" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
237
|
+
<text x="655" y="299" fill="#94a3b8" font-size="9">TLS</text>
|
|
238
|
+
|
|
239
|
+
<!-- Curved path for auth flow -->
|
|
240
|
+
<path d="M 80 140 L 80 200 Q 80 220 100 220 L 200 220 Q 220 220 220 240 L 220 278" fill="none" stroke="#fb7185" stroke-width="1.5" stroke-dasharray="5,5"/>
|
|
241
|
+
<text x="150" y="210" fill="#fb7185" font-size="8">JWT + PKCE</text>
|
|
242
|
+
|
|
243
|
+
<!-- =================================================================
|
|
244
|
+
LEGEND
|
|
245
|
+
================================================================= -->
|
|
246
|
+
<text x="720" y="70" fill="white" font-size="10" font-weight="600">Legend</text>
|
|
247
|
+
|
|
248
|
+
<rect x="720" y="82" width="16" height="10" rx="2" fill="rgba(8, 51, 68, 0.4)" stroke="#22d3ee" stroke-width="1"/>
|
|
249
|
+
<text x="742" y="90" fill="#94a3b8" font-size="8">Frontend</text>
|
|
250
|
+
|
|
251
|
+
<rect x="720" y="98" width="16" height="10" rx="2" fill="rgba(6, 78, 59, 0.4)" stroke="#34d399" stroke-width="1"/>
|
|
252
|
+
<text x="742" y="106" fill="#94a3b8" font-size="8">Backend</text>
|
|
253
|
+
|
|
254
|
+
<rect x="720" y="114" width="16" height="10" rx="2" fill="rgba(120, 53, 15, 0.3)" stroke="#fbbf24" stroke-width="1"/>
|
|
255
|
+
<text x="742" y="122" fill="#94a3b8" font-size="8">Cloud Service</text>
|
|
256
|
+
|
|
257
|
+
<rect x="720" y="130" width="16" height="10" rx="2" fill="rgba(76, 29, 149, 0.4)" stroke="#a78bfa" stroke-width="1"/>
|
|
258
|
+
<text x="742" y="138" fill="#94a3b8" font-size="8">Database</text>
|
|
259
|
+
|
|
260
|
+
<rect x="720" y="146" width="16" height="10" rx="2" fill="rgba(136, 19, 55, 0.4)" stroke="#fb7185" stroke-width="1"/>
|
|
261
|
+
<text x="742" y="154" fill="#94a3b8" font-size="8">Security</text>
|
|
262
|
+
|
|
263
|
+
<line x1="720" y1="168" x2="736" y2="168" stroke="#fb7185" stroke-width="1" stroke-dasharray="3,3"/>
|
|
264
|
+
<text x="742" y="171" fill="#94a3b8" font-size="8">Auth Flow</text>
|
|
265
|
+
|
|
266
|
+
<rect x="720" y="178" width="16" height="10" rx="2" fill="transparent" stroke="#fb7185" stroke-width="1" stroke-dasharray="3,3"/>
|
|
267
|
+
<text x="742" y="186" fill="#94a3b8" font-size="8">Security Group</text>
|
|
268
|
+
</svg>
|
|
269
|
+
</div>
|
|
270
|
+
|
|
271
|
+
<!-- Info Cards -->
|
|
272
|
+
<div class="cards">
|
|
273
|
+
<div class="card">
|
|
274
|
+
<div class="card-header">
|
|
275
|
+
<div class="card-dot rose"></div>
|
|
276
|
+
<h3>Card Title 1</h3>
|
|
277
|
+
</div>
|
|
278
|
+
<ul>
|
|
279
|
+
<li>• Item one</li>
|
|
280
|
+
<li>• Item two</li>
|
|
281
|
+
<li>• Item three</li>
|
|
282
|
+
<li>• Item four</li>
|
|
283
|
+
</ul>
|
|
284
|
+
</div>
|
|
285
|
+
|
|
286
|
+
<div class="card">
|
|
287
|
+
<div class="card-header">
|
|
288
|
+
<div class="card-dot amber"></div>
|
|
289
|
+
<h3>Card Title 2</h3>
|
|
290
|
+
</div>
|
|
291
|
+
<ul>
|
|
292
|
+
<li>• Item one</li>
|
|
293
|
+
<li>• Item two</li>
|
|
294
|
+
<li>• Item three</li>
|
|
295
|
+
<li>• Item four</li>
|
|
296
|
+
</ul>
|
|
297
|
+
</div>
|
|
298
|
+
|
|
299
|
+
<div class="card">
|
|
300
|
+
<div class="card-header">
|
|
301
|
+
<div class="card-dot violet"></div>
|
|
302
|
+
<h3>Card Title 3</h3>
|
|
303
|
+
</div>
|
|
304
|
+
<ul>
|
|
305
|
+
<li>• Item one</li>
|
|
306
|
+
<li>• Item two</li>
|
|
307
|
+
<li>• Item three</li>
|
|
308
|
+
<li>• Item four</li>
|
|
309
|
+
</ul>
|
|
310
|
+
</div>
|
|
311
|
+
</div>
|
|
312
|
+
|
|
313
|
+
<!-- Footer -->
|
|
314
|
+
<p class="footer">
|
|
315
|
+
[Project Name] • [Additional metadata]
|
|
316
|
+
</p>
|
|
317
|
+
</div>
|
|
318
|
+
</body>
|
|
319
|
+
</html>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: build
|
|
3
|
+
description: "Implement a spec task-by-task with a verify gate after every task and a full-suite checkpoint every 2 tasks. USE WHEN: 'build X', 'implement the spec', 'continue building X', or after /spec produced .sdlc/specs/<feature>.md. Executes the spec exactly — it does not redesign. Resumable: always continues from the first unchecked task."
|
|
4
|
+
argument-hint: "The feature to build (must have a spec in .sdlc/specs/)"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# build
|
|
8
|
+
|
|
9
|
+
Executes `.sdlc/specs/<feature>.md`. The spec is the authority: `Files` lists are a whitelist, `Do` bullets are the instructions, `Verify` commands are the gate. Progress lives in the spec's checkboxes, so a fresh session resumes exactly where the last one stopped.
|
|
10
|
+
|
|
11
|
+
## Setup
|
|
12
|
+
|
|
13
|
+
1. Read `.sdlc/PROJECT.md` (conventions, commands, boundaries) and the spec. Spec missing → tell the user to run /spec first. Do not improvise a plan.
|
|
14
|
+
2. If spec Status is `draft`, set it to `building`.
|
|
15
|
+
3. `git branch --show-current` — on main/master/develop/staging/release/* → create and switch to `feat/<feature>` before touching anything.
|
|
16
|
+
|
|
17
|
+
## Task loop — repeat until no `[ ]` tasks remain
|
|
18
|
+
|
|
19
|
+
1. **Pick** the first `[ ]` task, top to bottom.
|
|
20
|
+
2. **Read only** the files in its `Files:` and `Pattern:` lines — not the whole codebase.
|
|
21
|
+
3. **Implement** exactly what the Do bullets say:
|
|
22
|
+
- Mirror the Pattern file's style: naming, error handling, imports, structure.
|
|
23
|
+
- Obey every PROJECT.md convention and boundary.
|
|
24
|
+
- Touch ONLY the listed files. If another file needs changing → STOP, report which file and why, propose the spec edit, wait for approval.
|
|
25
|
+
- No new dependencies unless the task names them. No drive-by refactors. No TODO/FIXME placeholders.
|
|
26
|
+
4. **Verify.** Run the task's Verify command.
|
|
27
|
+
- Pass → continue.
|
|
28
|
+
- Fail → fix and rerun, up to 3 attempts. Still failing → mark the task `[!]` in the spec, STOP, report the exact failing output.
|
|
29
|
+
5. **Mark done.** Flip `[ ]` to `[x]` in the spec. Tell the user one line: `T3 done — <name> (verify: pass)`.
|
|
30
|
+
6. **Checkpoint** — after every 2 completed tasks and after the final task: run the full `test:` command from PROJECT.md.
|
|
31
|
+
- A previously-passing test now failing is a regression → fix it NOW, before the next task. Not fixed in 3 attempts → STOP and report.
|
|
32
|
+
|
|
33
|
+
## Finish
|
|
34
|
+
|
|
35
|
+
When every task is `[x]` and the final checkpoint is green:
|
|
36
|
+
1. Set spec Status: `qa`.
|
|
37
|
+
2. Report in ≤ 6 lines: tasks completed, files created/edited, suite result, then: "Run `/qa <feature>`."
|
|
38
|
+
|
|
39
|
+
## Hard rules
|
|
40
|
+
- Never mark a task `[x]` without its Verify passing. No exceptions, no "fix later".
|
|
41
|
+
- Never weaken a failing test to make it pass — fix the code. If the test itself is wrong, say so and ask.
|
|
42
|
+
- Stop conditions are stops, not suggestions: unlisted file needed · 3 failed verify attempts · unfixable regression · missing spec.
|
|
43
|
+
- Fix-tasks appended by /qa (`F1`, `F2`, …) are ordinary tasks — the same loop executes them.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: qa
|
|
3
|
+
description: "Mechanical QA gate for a built feature — re-runs every task Verify, runs Acceptance checks, full-suite regression, and a convention diff scan, then appends a verdict to the spec. Failures become fix-tasks /build can execute. USE WHEN: 'qa X', 'test the feature', 'verify the implementation', after /build finishes."
|
|
4
|
+
argument-hint: "The feature to QA (must have a spec in .sdlc/specs/)"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# qa
|
|
8
|
+
|
|
9
|
+
Verifies a feature against its own spec. Mechanical by design: the spec already defines every check — QA executes them, it does not wander the codebase. QA reports; /build fixes.
|
|
10
|
+
|
|
11
|
+
## Procedure
|
|
12
|
+
|
|
13
|
+
**1. Load** `.sdlc/PROJECT.md` + the spec. Spec name unclear → list `.sdlc/specs/` and ask.
|
|
14
|
+
|
|
15
|
+
**2. Task verifies.** Re-run the Verify command of every `[x]` task. Record pass/fail per task.
|
|
16
|
+
|
|
17
|
+
**3. Acceptance checks.** Run each command under Acceptance checks; compare actual vs expected. If a check needs a live app, start it with PROJECT.md's `run:` command and stop it afterwards.
|
|
18
|
+
|
|
19
|
+
**4. Regression.** Run the full `test:` suite. Any failure outside this feature's own tests — especially in areas named under `Touches → Risk` — is a regression: always CRITICAL, always blocks PASS.
|
|
20
|
+
|
|
21
|
+
**5. Coverage gap.** Any acceptance check not covered by a test in the suite → write ONE minimal test for it (following the project's test pattern), run it, keep it.
|
|
22
|
+
|
|
23
|
+
**6. Diff scan.** `git diff --name-only` (plus `git status --short` for untracked). Exactly two checks:
|
|
24
|
+
- Every changed file appears in some task's `Files:` list — unlisted changes get flagged.
|
|
25
|
+
- Each changed file respects PROJECT.md Conventions and Boundaries — walk the bullets mechanically.
|
|
26
|
+
|
|
27
|
+
**7. Verdict.**
|
|
28
|
+
- **PASS** — all task verifies, acceptance checks, and the suite are green; no unlisted changes. Convention nits alone don't block — list them as notes.
|
|
29
|
+
- **FAIL** — anything else. For each failure, append a fix-task to the spec's Tasks section — `### [ ] F1 — fix: <what>` with Files / Do / Verify filled in — so `/build <feature>` can execute the fixes directly.
|
|
30
|
+
|
|
31
|
+
**8. Append to the spec's QA log** (≤ 20 lines per run):
|
|
32
|
+
|
|
33
|
+
```markdown
|
|
34
|
+
### QA <date> — PASS | FAIL
|
|
35
|
+
Task verifies: 6/6 · Acceptance: 3/3 · Suite: 42 passed, 0 failed · Regressions: 0
|
|
36
|
+
Unlisted changes: none
|
|
37
|
+
Failures: <one line per F-task, or "none">
|
|
38
|
+
Notes: <convention nits, or "none">
|
|
39
|
+
Try it:
|
|
40
|
+
1. <command or click-path with concrete sample data>
|
|
41
|
+
2. <expected result>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The **Try it** block is 2–5 steps any human — technical or not — can follow to see the feature working: concrete sample data, exact expected outcome.
|
|
45
|
+
|
|
46
|
+
**9. Report in ≤ 8 lines:** verdict, the counts line, failures if any, next step — `/build <feature>` to execute fixes, or `/ship <feature>` on PASS.
|
|
47
|
+
|
|
48
|
+
## Rules
|
|
49
|
+
- Never PASS with a failing acceptance check or a regression. There is no "pass with warnings" for those.
|
|
50
|
+
- Never fix code here — failures become F-tasks for /build. (Sole exception: the minimal coverage test in step 5.)
|
|
51
|
+
- Scope is this feature's diff plus the test suite — do not re-review the whole codebase.
|
|
52
|
+
- Environment blocks a check (no DB, no network)? Record it as SKIPPED with the reason — never silently count it as passing.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: roadmap
|
|
3
|
+
description: "Break a whole project (PRD or description) into an ordered list of shippable features — creates .sdlc/ROADMAP.md. Optional: for greenfield projects or large multi-feature efforts. USE WHEN: 'divide this project', 'break down this PRD', 'create a development plan'. NOT for a single feature — use /spec directly."
|
|
4
|
+
argument-hint: "The PRD, project description, or doc path to break down"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# roadmap
|
|
8
|
+
|
|
9
|
+
Turns a PRD into an ordered feature list where each feature fits one `/spec → /build → /qa → /ship` cycle. It decides WHAT to build and in what order — never HOW (no file lists, no schemas; that is /spec's job).
|
|
10
|
+
|
|
11
|
+
## Procedure
|
|
12
|
+
|
|
13
|
+
**1.** Read `.sdlc/PROJECT.md`. Missing → run the sdlc-init skill first (follow its SKILL.md), then return here.
|
|
14
|
+
|
|
15
|
+
**2.** Read the PRD/description fully. Extract: purpose, features, constraints, non-functional needs (auth, scale, deploy).
|
|
16
|
+
|
|
17
|
+
**3. Gaps → MCQ.** Ask only what changes the breakdown: rough scale, auth needs, deploy target, what is out of scope for v1. Max 5 questions; options A–D with one `(Recommended)`. ≤ 3 → ask in chat; > 3 → write `.sdlc/questions.md`, wait for **done**, read answers, delete the file.
|
|
18
|
+
|
|
19
|
+
**4. Divide.** Rules:
|
|
20
|
+
- Each feature = one meaningful capability, shippable and testable on its own. Target size: one focused /build session.
|
|
21
|
+
- Order by dependency: skeleton → data layer → auth → core features → integrations → polish. Auth before anything protected; schema before anything that uses it.
|
|
22
|
+
- On greenfield, feature 1 is always the project skeleton (installs, runs, lints, health check).
|
|
23
|
+
- Max 10 lines per feature block. If a feature needs more, it is two features.
|
|
24
|
+
|
|
25
|
+
**5. Write `.sdlc/ROADMAP.md`:**
|
|
26
|
+
|
|
27
|
+
```markdown
|
|
28
|
+
# Roadmap — <project>
|
|
29
|
+
|
|
30
|
+
| # | Feature | Needs | Status |
|
|
31
|
+
|---|---------|-------|--------|
|
|
32
|
+
| 1 | skeleton | — | todo |
|
|
33
|
+
| 2 | user-auth | 1 | todo |
|
|
34
|
+
|
|
35
|
+
## 1. skeleton
|
|
36
|
+
Goal: <one line>
|
|
37
|
+
Scope: <3–6 bullets>
|
|
38
|
+
Done when: <2–3 verifiable criteria — "returns 401 unauthenticated", not "works">
|
|
39
|
+
|
|
40
|
+
## 2. user-auth
|
|
41
|
+
…
|
|
42
|
+
|
|
43
|
+
## Out of v1
|
|
44
|
+
- <anything deliberately dropped, one line each>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**6. Report in ≤ 6 lines:** feature count, phase summary, and the next command: `/spec <feature-1>`.
|
|
48
|
+
|
|
49
|
+
## Rules
|
|
50
|
+
- Cover the ENTIRE PRD scope — anything skipped goes under "Out of v1", never silently dropped.
|
|
51
|
+
- Feature names are kebab-case; they become spec filenames (`.sdlc/specs/<feature>.md`).
|
|
52
|
+
- The Status column is owned by /ship — it flips `todo → done` as features ship. Don't pre-fill anything else.
|
|
53
|
+
- "Done when" criteria flow into the spec's Acceptance checks — write them so a command can prove them.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sdlc-init
|
|
3
|
+
description: "Set up AI-SDLC for a project — creates .sdlc/PROJECT.md (stack, layout, commands, conventions) and .sdlc/STATE.md (feature log). Run once per project, before any other SDLC skill. USE WHEN: 'set up sdlc', 'init project context', or any SDLC skill finds no .sdlc/ folder."
|
|
4
|
+
argument-hint: "Optionally: a PRD/description, a doc path, or 'analyze the codebase'"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# sdlc-init
|
|
8
|
+
|
|
9
|
+
Creates the two files every other SDLC skill reads. Both are loaded on every skill run, so every line must earn its place — facts only, no prose.
|
|
10
|
+
|
|
11
|
+
## Output contract
|
|
12
|
+
|
|
13
|
+
| File | Contains | Budget |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| `.sdlc/PROJECT.md` | Stack, layout, commands, conventions, boundaries | ≤ 80 lines |
|
|
16
|
+
| `.sdlc/STATE.md` | Feature status table + cross-feature notes | grows ~1 line per feature |
|
|
17
|
+
|
|
18
|
+
## Procedure
|
|
19
|
+
|
|
20
|
+
**1. Existing setup check.** If `.sdlc/PROJECT.md` exists and is non-empty: show a 3-line summary, ask — update, replace, or cancel. Wait for the answer.
|
|
21
|
+
|
|
22
|
+
**2. Gather facts — use the first source that applies:**
|
|
23
|
+
- **PRD or description provided** → read it. Extract: purpose, users, features, stack, constraints.
|
|
24
|
+
- **Codebase exists** → detect, don't interrogate:
|
|
25
|
+
- Read manifests (`package.json` / `pyproject.toml` / `go.mod` / `Cargo.toml` / …), `docker-compose.yml`, `.env.example`, README.
|
|
26
|
+
- Read the entry point, 2–3 representative source files (one per layer), and 1 test file.
|
|
27
|
+
- Do NOT scan the whole codebase — ~10 file reads maximum.
|
|
28
|
+
- **Neither (greenfield, no PRD)** → question mode; step 3 collects everything.
|
|
29
|
+
|
|
30
|
+
**3. Close remaining gaps with MCQs.** Only ask what steps 1–2 didn't answer and PROJECT.md needs: language + version, framework, DB, package manager, test runner, repo layout, auth approach, deploy target.
|
|
31
|
+
- Format: options A–D, one marked `(Recommended)` where a best practice exists. Blank answer = recommended.
|
|
32
|
+
- ≤ 3 questions → ask directly in chat.
|
|
33
|
+
- \> 3 questions → write `.sdlc/questions.md` (same A–D format, each with an `Answer:` line), tell the user to fill it and reply **done**. Wait, read the answers, then delete the file.
|
|
34
|
+
- Hard cap: 7 questions.
|
|
35
|
+
|
|
36
|
+
**4. Write `.sdlc/PROJECT.md`** from the template below.
|
|
37
|
+
- Conventions: max 12 bullets, each mechanically checkable ("type hints on all functions" — not "write clean code").
|
|
38
|
+
- Commands must be real: run the test command once to confirm it works (skip on greenfield).
|
|
39
|
+
- No placeholders left in the final file.
|
|
40
|
+
|
|
41
|
+
**5. Write `.sdlc/STATE.md`** from the template below (empty table).
|
|
42
|
+
|
|
43
|
+
**6. Report in ≤ 6 lines:** files created, detected stack, and the next step — `/roadmap` for a whole project, `/spec <feature>` for one feature.
|
|
44
|
+
|
|
45
|
+
## PROJECT.md template
|
|
46
|
+
|
|
47
|
+
```markdown
|
|
48
|
+
# <project name>
|
|
49
|
+
<one line: what it is and who uses it>
|
|
50
|
+
|
|
51
|
+
## Stack
|
|
52
|
+
- <language + version, package manager>
|
|
53
|
+
- <framework> | <database + ORM> | <frontend or "none">
|
|
54
|
+
- <anything else an implementer must know: queue, cache, auth method>
|
|
55
|
+
|
|
56
|
+
## Layout
|
|
57
|
+
- <dir>/ → <responsibility + the one rule that matters, e.g. "routes/ → HTTP only, delegate to services">
|
|
58
|
+
- <dir>/ → <…>
|
|
59
|
+
- <test location + naming, e.g. "tests/<area>/test_*.py">
|
|
60
|
+
> Repos: <single | list each path + purpose if multi-repo>
|
|
61
|
+
|
|
62
|
+
## Commands
|
|
63
|
+
- test: <exact command>
|
|
64
|
+
- lint: <exact command>
|
|
65
|
+
- run: <exact command>
|
|
66
|
+
- migrate: <exact command or "n/a">
|
|
67
|
+
|
|
68
|
+
## Conventions
|
|
69
|
+
- <max 12 checkable bullets>
|
|
70
|
+
|
|
71
|
+
## Boundaries
|
|
72
|
+
- Never edit: <e.g. migrations/versions/*, generated files>
|
|
73
|
+
- Never commit: .env*, secrets, build artifacts
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## STATE.md template
|
|
77
|
+
|
|
78
|
+
```markdown
|
|
79
|
+
# State
|
|
80
|
+
|
|
81
|
+
| Feature | Spec | Status | Shipped |
|
|
82
|
+
|---|---|---|---|
|
|
83
|
+
|
|
84
|
+
## Notes
|
|
85
|
+
<!-- cross-feature facts an implementer must know; one line each -->
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Edge cases
|
|
89
|
+
- Multiple languages in the workspace → list all in Stack, ask which is primary (1 MCQ).
|
|
90
|
+
- Monorepo / multi-repo → one PROJECT.md at the workspace root; Layout lists each repo path + purpose.
|
|
91
|
+
- User says "skip questions" → use recommended defaults, mark them `(assumed)` in PROJECT.md.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ship
|
|
3
|
+
description: "Commit a QA-passed feature safely — branch guard, explicit staging, conventional commit built from the spec, STATE.md + roadmap update. Never pushes, never commits on protected branches. USE WHEN: 'ship X', 'commit the feature', 'commit my changes', after /qa passes."
|
|
4
|
+
argument-hint: "The feature to ship (e.g. 'ship user-auth')"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# ship
|
|
8
|
+
|
|
9
|
+
Commit-only. Reads the spec for the message, guards the branch, stages files by name, updates the feature log. Never pushes.
|
|
10
|
+
|
|
11
|
+
## Procedure
|
|
12
|
+
|
|
13
|
+
**1. Gate.** Read the spec. The latest QA log entry must be PASS. Not PASS, or no QA log → say so and offer `/qa <feature>`. Proceed anyway only on an explicit user override ("ship anyway") — note the override in the commit body.
|
|
14
|
+
|
|
15
|
+
**2. Branch guard** (per repo, if multi-repo). `git branch --show-current`. On main / master / develop / development / staging / integration / release/* or detached HEAD → refuse and offer:
|
|
16
|
+
- A) create `feat/<feature>` and continue
|
|
17
|
+
- B) user switches manually
|
|
18
|
+
- C) cancel
|
|
19
|
+
|
|
20
|
+
**3. Update records first, so they ride in the same commit:**
|
|
21
|
+
- Spec `Status:` → `done`
|
|
22
|
+
- `.sdlc/STATE.md` → add or update the row: `| <feature> | specs/<feature>.md | done | <YYYY-MM-DD> |`
|
|
23
|
+
- `.sdlc/ROADMAP.md` (if the feature is on it) → flip its Status to `done`
|
|
24
|
+
|
|
25
|
+
**4. Stage.** `git status --short`. Stage by name — never `git add .` or `-A`:
|
|
26
|
+
- every file from the spec's task `Files:` lists
|
|
27
|
+
- the spec itself, STATE.md, ROADMAP.md if touched
|
|
28
|
+
- never `.env*`, secrets, build artifacts, dependency dirs
|
|
29
|
+
- changed files NOT in the spec → list them, ask include / exclude
|
|
30
|
+
|
|
31
|
+
**5. Build the message** (Conventional Commits):
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
<type>(<feature>): <spec Goal, imperative, ≤ 72 chars>
|
|
35
|
+
|
|
36
|
+
- <one bullet per task — the behavior, not the file names>
|
|
37
|
+
|
|
38
|
+
Spec: .sdlc/specs/<feature>.md
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Type: feat | fix | refactor | test | chore — whichever the spec actually did.
|
|
42
|
+
|
|
43
|
+
**6. Confirm.** Show branch, staged file list, and the message. Wait for **yes** (or apply requested edits). Then commit — multi-line via `git commit -F .sdlc/commit-msg.txt`, delete the temp file after.
|
|
44
|
+
|
|
45
|
+
**7. Report in ≤ 5 lines:** short hash, branch, file count, and the push command as reference only. Do not push. Do not open a PR.
|
|
46
|
+
|
|
47
|
+
## Rules
|
|
48
|
+
- Never push. Never commit on a protected branch. Never stage secrets.
|
|
49
|
+
- Merge-conflict markers anywhere → refuse; user resolves first.
|
|
50
|
+
- Multi-repo: run guard → stage → commit per repo that has changes; each repo gets its own message.
|
|
51
|
+
- Clean working tree → show status, exit cleanly.
|
|
52
|
+
- Branch named `trunk` or `mainline` → treat as protected, ask before proceeding.
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: spec
|
|
3
|
+
description: "Plan one feature into a single executable spec — .sdlc/specs/<feature>.md with decisions (why), integration map, and small verifiable tasks (instructions + contracts, NOT code). USE WHEN: 'plan X', 'spec the auth feature', 'plan roadmap feature 3', before building anything non-trivial. Produces the file /build executes."
|
|
4
|
+
argument-hint: "The feature to spec (e.g. 'user auth', 'roadmap feature 3', 'payment webhooks')"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# spec
|
|
8
|
+
|
|
9
|
+
Produces ONE file containing everything about a feature — what, why, and how — as tasks small enough that a weak model can implement each one without judgment calls. Tasks carry contracts and instructions, never full code. The developer reads the Decisions section and can explain the design to anyone.
|
|
10
|
+
|
|
11
|
+
## Procedure
|
|
12
|
+
|
|
13
|
+
**1. Load context — these files and nothing else:**
|
|
14
|
+
- `.sdlc/PROJECT.md` — missing → run the sdlc-init skill first, then return here.
|
|
15
|
+
- `.sdlc/STATE.md` — what already shipped; never re-plan existing work.
|
|
16
|
+
- `.sdlc/ROADMAP.md` — only if the user referenced a roadmap feature; pull its goal, scope, done-when.
|
|
17
|
+
|
|
18
|
+
**2. Understand.** Restate the feature in ≤ 2 sentences: what the user gets, what changes in the system. This becomes `Goal`. Then draft the **What & why** section — 3–6 plain-English sentences describing what this feature is and how it will work once built (the journey from the user's action to the result). No jargon: a smart 12th-grader with zero coding background must be able to follow it.
|
|
19
|
+
|
|
20
|
+
**3. Research the unknowns (no code yet).** List the components the feature needs (e.g. "JWT refresh flow", "webhook signature verification", "cursor pagination"). For each one not already solved in this codebase:
|
|
21
|
+
- Find the standard production approach — official docs / web search if tools are available, otherwise known best practice.
|
|
22
|
+
- Write a **Decision** in the template's format, ≤ 5 lines, in plain English:
|
|
23
|
+
1. what the component IS — one simple line, assume the reader has never heard of it
|
|
24
|
+
2. what we chose
|
|
25
|
+
3. why, in everyday words
|
|
26
|
+
4. what we rejected and why not
|
|
27
|
+
- Define every technical term in brackets at first use — e.g. "JWT (a signed pass the server can verify without a database lookup)".
|
|
28
|
+
- Audience rule: **What & why** and **Decisions** are written for the developer and anyone they must explain the feature to — a boss, a client, a teammate — NOT for the model. If a sentence needs a CS degree, rewrite it.
|
|
29
|
+
|
|
30
|
+
**4. Integration scan.** Read ONLY the existing files this feature touches or extends. Record in `Touches`:
|
|
31
|
+
- files to be edited, and what changes in each
|
|
32
|
+
- pattern files — existing code the new code must mirror (the style-drift guard)
|
|
33
|
+
- existing behavior this could break (shared utils, routes, schema) → these become QA regression targets
|
|
34
|
+
|
|
35
|
+
**5. Gaps → MCQ.** Only unknowns that change the design. Max 5; options A–D with one `(Recommended)`. ≤ 3 → ask in chat; > 3 → write `.sdlc/questions.md`, wait for **done**, read answers, delete the file.
|
|
36
|
+
|
|
37
|
+
**6. Write `.sdlc/specs/<feature>.md`** (kebab-case filename) from the template below. Task rules — /build depends on these:
|
|
38
|
+
- **≤ 8 tasks.** Need more → split the feature; tell the user.
|
|
39
|
+
- Order by dependency. Each task independently verifiable.
|
|
40
|
+
- Each task ≤ 20 lines with exactly these fields:
|
|
41
|
+
- `Files:` explicit CREATE / EDIT list — /build treats this as a whitelist
|
|
42
|
+
- `Pattern:` existing file to mirror (omit if none)
|
|
43
|
+
- `Do:` 3–7 imperative bullets — exact names, signatures, routes, data shapes, edge cases
|
|
44
|
+
- `Verify:` one runnable command + expected outcome
|
|
45
|
+
- Code appears ONLY as: function/route signatures, request/response/schema shapes, and ≤ 5-line pseudocode for genuinely tricky logic. NEVER full file bodies.
|
|
46
|
+
- Every Do bullet must be decidable without judgment: "hash with bcrypt, cost 12" — not "hash securely".
|
|
47
|
+
- If tests aren't built into each task, the last task is the feature's tests.
|
|
48
|
+
|
|
49
|
+
**7. Report in ≤ 6 lines:** spec path, task count, key decisions (1 line each), then: "Review Decisions and Tasks — edit anything — then run `/build <feature>`."
|
|
50
|
+
|
|
51
|
+
## Spec template
|
|
52
|
+
|
|
53
|
+
```markdown
|
|
54
|
+
# <feature>
|
|
55
|
+
Status: draft <!-- draft → building → qa → done · owned by build/qa/ship -->
|
|
56
|
+
Goal: <one line>
|
|
57
|
+
Done when:
|
|
58
|
+
- <verifiable criterion>
|
|
59
|
+
- <verifiable criterion>
|
|
60
|
+
|
|
61
|
+
## What & why — plain English
|
|
62
|
+
<3–6 sentences anyone can understand: what this feature is, how it works once
|
|
63
|
+
built — the flow from the user's action to the result — and where it fits in
|
|
64
|
+
the app. Optional: a ≤ 8-line ASCII flow of that journey.>
|
|
65
|
+
|
|
66
|
+
## Decisions
|
|
67
|
+
<!-- One block per choice · ≤ 5 lines each · plain English · define jargon in
|
|
68
|
+
brackets at first use. A non-programmer must be able to read these. -->
|
|
69
|
+
- **<Component>** — <what this thing is, one simple line>.
|
|
70
|
+
Chose: <choice>. Why: <reason in everyday words>.
|
|
71
|
+
Rejected: <alternative> — <why not>.
|
|
72
|
+
|
|
73
|
+
## Touches
|
|
74
|
+
- Edits: <existing files + what changes in each>
|
|
75
|
+
- Mirrors: <pattern file(s) new code must match>
|
|
76
|
+
- Risk: <existing behavior that could break — QA checks these>
|
|
77
|
+
|
|
78
|
+
## Tasks
|
|
79
|
+
|
|
80
|
+
### [ ] T1 — <name>
|
|
81
|
+
Files: CREATE src/…, EDIT src/…
|
|
82
|
+
Pattern: src/…
|
|
83
|
+
Do:
|
|
84
|
+
- <exact imperative instruction>
|
|
85
|
+
- <signature / shape where needed>
|
|
86
|
+
Verify: `<command>` → <expected>
|
|
87
|
+
|
|
88
|
+
### [ ] T2 — <name>
|
|
89
|
+
…
|
|
90
|
+
|
|
91
|
+
## Acceptance checks
|
|
92
|
+
- [ ] `<command>` → <expected observable result>
|
|
93
|
+
- [ ] `<command>` → <expected>
|
|
94
|
+
|
|
95
|
+
## QA log
|
|
96
|
+
<!-- appended by /qa -->
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Quality bar — check before saving
|
|
100
|
+
- [ ] A model with ONLY this spec + PROJECT.md could implement every task
|
|
101
|
+
- [ ] Every task has a runnable Verify; every "Done when" maps to an Acceptance check
|
|
102
|
+
- [ ] No full code bodies; no vague bullets ("handle errors properly")
|
|
103
|
+
- [ ] Touches lists every existing file that will change
|
|
104
|
+
- [ ] **What & why** + **Decisions** pass the 12th-grader test: a reader with no coding
|
|
105
|
+
background can say what is being built, how it will work, and why each choice
|
|
106
|
+
was made — every technical term is defined at first use
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ai-sdlc-kit
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Spec-driven SDLC skills for AI coding agents — Claude Code, Cursor, Windsurf, Gemini CLI
|
|
5
|
+
Project-URL: Homepage, https://github.com/xajeel/AI-SDLC
|
|
6
|
+
Author: xajeel
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Keywords: agents,ai,claude-code,cursor,sdlc,skills,spec-driven
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Topic :: Software Development
|
|
14
|
+
Requires-Python: >=3.9
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
# AI-SDLC v2 — Spec-Driven Skills for AI Coding Agents
|
|
18
|
+
|
|
19
|
+
A lean, token-efficient Software Development Life Cycle for AI coding agents (Claude Code, Cursor, Windsurf, Gemini CLI). Six skills that make an agent work the way a senior engineer does: **understand → decide → plan in verifiable steps → build with checks after every step → gate → ship**.
|
|
20
|
+
|
|
21
|
+
Designed so that **even a small model can execute reliably**: the planning skill (run once, ideally with a strong model) removes every judgment call up front, and the execution skills are mechanical loops with hard stop conditions.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Design principles (what changed from v1)
|
|
26
|
+
|
|
27
|
+
| v1 problem | v2 fix |
|
|
28
|
+
|---|---|
|
|
29
|
+
| Huge token use | Skills are 4–10× smaller; artifacts have hard size budgets; every skill reads only the files it names — never "scan the codebase" |
|
|
30
|
+
| Implementation files full of code, impossible to review | Specs contain **instructions + contracts** (signatures, shapes, exact steps) — never code bodies. You review decisions and contracts, not walls of code |
|
|
31
|
+
| QA didn't catch bugs | Checks are **defined at plan time** (every task has a `Verify` command, every goal an acceptance check). QA just executes them — nothing left to a model's mood |
|
|
32
|
+
| Too many files per feature | **One spec file per feature.** Plan, decisions, tasks, and QA log all live in `.sdlc/specs/<feature>.md` |
|
|
33
|
+
| Features silently broke each other | `/build` runs the full test suite every 2 tasks (not only at the end); `/qa` treats any regression as an automatic FAIL |
|
|
34
|
+
| Style drift, copied bugs | Every task names a `Pattern:` file the new code must mirror; PROJECT.md carries ≤ 12 checkable convention rules |
|
|
35
|
+
| Black-box output | Every spec opens with **What & why** (plain-English story of the feature) and a **Decisions** section: what each component is, what was chosen, why, and what was rejected — written to pass the "12th-grader test", so you can explain the design to anyone |
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Install
|
|
40
|
+
|
|
41
|
+
Copy the folders inside `skills/` into your agent's skills directory at the project root:
|
|
42
|
+
|
|
43
|
+
| Agent / IDE | Path |
|
|
44
|
+
|---|---|
|
|
45
|
+
| Claude Code | `.claude/skills/` |
|
|
46
|
+
| Cursor | `.cursor/skills/` |
|
|
47
|
+
| Windsurf | `.windsurf/skills/` |
|
|
48
|
+
| Gemini CLI | `.gemini/skills/` |
|
|
49
|
+
|
|
50
|
+
The skills appear as slash commands: `/sdlc-init`, `/roadmap`, `/spec`, `/build`, `/qa`, `/ship`.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## The flow
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
/sdlc-init one-time setup → .sdlc/PROJECT.md + STATE.md
|
|
58
|
+
│
|
|
59
|
+
/roadmap (optional) whole project → features → .sdlc/ROADMAP.md
|
|
60
|
+
│
|
|
61
|
+
/spec <feature> plan one feature → .sdlc/specs/<feature>.md
|
|
62
|
+
│ (research, decisions, tasks with contracts + verify commands)
|
|
63
|
+
/build <feature> implement task-by-task → code; verify gate after EVERY task,
|
|
64
|
+
│ full-suite checkpoint every 2 tasks
|
|
65
|
+
/qa <feature> mechanical gate → verdict appended to the spec;
|
|
66
|
+
│ failures become fix-tasks for /build
|
|
67
|
+
/ship <feature> safe commit → feature branch only, STATE.md updated
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
The `/build → /qa → /build` loop is the self-healing part: QA never fixes code, it appends `F1, F2…` fix-tasks to the spec, and `/build` executes them like any other task.
|
|
71
|
+
|
|
72
|
+
## The six skills
|
|
73
|
+
|
|
74
|
+
| Skill | Does | Reads | Writes |
|
|
75
|
+
|---|---|---|---|
|
|
76
|
+
| `sdlc-init` | One-time project setup: stack, layout, commands, conventions, boundaries | manifests + a few source files, or PRD, or your answers | `PROJECT.md`, `STATE.md` |
|
|
77
|
+
| `roadmap` | Splits a PRD into ordered, shippable features (what + order, never how) | PROJECT.md, the PRD | `ROADMAP.md` |
|
|
78
|
+
| `spec` | Plans one feature: researches unknowns, records decisions, writes ≤ 8 tasks with `Files / Pattern / Do / Verify` | PROJECT.md, STATE.md, only the files the feature touches | `specs/<feature>.md` |
|
|
79
|
+
| `build` | Executes the spec exactly: whitelist files, mirror patterns, verify after every task, checkpoint every 2 | PROJECT.md, the spec, only listed files | code + spec checkboxes |
|
|
80
|
+
| `qa` | Re-runs all verifies + acceptance checks + full suite + diff scan; PASS/FAIL verdict; failures → fix-tasks | PROJECT.md, the spec, the diff | QA log in the spec |
|
|
81
|
+
| `ship` | Branch guard, explicit staging, conventional commit from the spec, records update. Never pushes | the spec | git commit, STATE.md, ROADMAP.md |
|
|
82
|
+
|
|
83
|
+
Bonus: `architecture-diagram` — renders a self-contained HTML/SVG architecture diagram (unchanged from v1).
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## The `.sdlc/` folder — 4 file types, that's all
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
.sdlc/
|
|
91
|
+
├── PROJECT.md # ≤ 80 lines: stack, layout, commands, conventions, boundaries
|
|
92
|
+
├── STATE.md # one table: feature | spec | status | shipped date (+ cross-feature notes)
|
|
93
|
+
├── ROADMAP.md # optional: ordered feature list for a whole project
|
|
94
|
+
└── specs/
|
|
95
|
+
└── <feature>.md # everything about one feature: goal, decisions, touches,
|
|
96
|
+
# tasks (with checkboxes = live progress), acceptance checks, QA log
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
A spec file looks like this (abridged):
|
|
100
|
+
|
|
101
|
+
```markdown
|
|
102
|
+
# user-auth
|
|
103
|
+
Status: building
|
|
104
|
+
Goal: Email+password auth issuing JWT access/refresh tokens
|
|
105
|
+
Done when:
|
|
106
|
+
- POST /v1/auth/login returns tokens for valid credentials
|
|
107
|
+
- Protected routes return 401 without a valid token
|
|
108
|
+
|
|
109
|
+
## What & why — plain English
|
|
110
|
+
When someone signs up, we store their account with a scrambled (hashed) password —
|
|
111
|
+
we never keep the real one. When they log in, we check the password and hand back
|
|
112
|
+
two digital passes: a short-lived access token shown on every request, and a
|
|
113
|
+
longer-lived refresh token used to get a new pass when the old one expires.
|
|
114
|
+
Any protected page simply refuses visitors without a valid pass.
|
|
115
|
+
|
|
116
|
+
## Decisions
|
|
117
|
+
- **JWT tokens** — a JWT is a signed digital pass the server can verify without a
|
|
118
|
+
database lookup. Chose: 15-min access token + rotating 7-day refresh token.
|
|
119
|
+
Why: servers don't have to remember who is logged in, so the app scales by just
|
|
120
|
+
adding more servers. Rejected: cookie sessions — they need shared session
|
|
121
|
+
storage, which complicates scaling.
|
|
122
|
+
- **bcrypt (cost 12)** — a slow-by-design password scrambler, so stolen data is
|
|
123
|
+
useless to attackers. Why: the battle-tested standard. Rejected: argon2 —
|
|
124
|
+
slightly stronger but adds a native dependency our stack doesn't need.
|
|
125
|
+
|
|
126
|
+
## Touches
|
|
127
|
+
- Edits: src/main.py (register router)
|
|
128
|
+
- Mirrors: src/routes/items.py, src/services/items.py
|
|
129
|
+
- Risk: shared error handler in src/exceptions.py
|
|
130
|
+
|
|
131
|
+
## Tasks
|
|
132
|
+
### [x] T1 — User model + migration
|
|
133
|
+
Files: CREATE src/models/user.py, CREATE migrations/…
|
|
134
|
+
Pattern: src/models/item.py
|
|
135
|
+
Do:
|
|
136
|
+
- Table users: id UUID pk, email unique not-null, password_hash str, created_at
|
|
137
|
+
- Migration with upgrade + downgrade
|
|
138
|
+
Verify: `uv run alembic upgrade head` → applies cleanly
|
|
139
|
+
|
|
140
|
+
### [ ] T2 — Auth service
|
|
141
|
+
Files: CREATE src/services/auth.py
|
|
142
|
+
Pattern: src/services/items.py
|
|
143
|
+
Do:
|
|
144
|
+
- register(email, password) -> User — reject duplicate email with ConflictError
|
|
145
|
+
- login(email, password) -> TokenPair(access: str, refresh: str)
|
|
146
|
+
- Hash with bcrypt cost 12; never log passwords
|
|
147
|
+
Verify: `uv run pytest tests/auth -q` → pass
|
|
148
|
+
|
|
149
|
+
## Acceptance checks
|
|
150
|
+
- [ ] `curl -s -X POST :8000/v1/auth/login -d '{…}'` → 200 with access + refresh tokens
|
|
151
|
+
- [ ] `curl -s :8000/v1/items` (no token) → 401
|
|
152
|
+
|
|
153
|
+
## QA log
|
|
154
|
+
### QA 2026-07-12 — PASS
|
|
155
|
+
Task verifies: 5/5 · Acceptance: 3/3 · Suite: 42 passed · Regressions: 0
|
|
156
|
+
Try it:
|
|
157
|
+
1. Run `uv run uvicorn src.main:app`, POST /v1/auth/register with {"email":"test@example.com","password":"Pass123!"}
|
|
158
|
+
2. Expect 201 and a user id; then login with the same credentials → 200 with two tokens
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Notice: an implementer needs **no other document**, a reviewer reads Decisions + contracts in minutes, the checkboxes are resumable progress state, and QA's checklist was fixed the moment the spec was written.
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Why this works with small models
|
|
166
|
+
|
|
167
|
+
1. **Judgment happens once, at spec time.** Use your best model for `/spec`. After that, `/build` and `/qa` are deterministic loops — pick task, read 2–3 listed files, follow exact bullets, run a command, check a box.
|
|
168
|
+
2. **Whitelists instead of freedom.** A task's `Files:` list is a hard boundary; needing another file is a stop-and-report, not an improvisation.
|
|
169
|
+
3. **Patterns instead of taste.** "Mirror `src/services/items.py`" keeps style consistent without describing style.
|
|
170
|
+
4. **Verification is a command, not an opinion.** Every task and every acceptance criterion is proven by running something and comparing output.
|
|
171
|
+
5. **Tiny context.** PROJECT.md ≤ 80 lines, one spec per feature, skills that forbid whole-codebase scans — the model's window stays small and focused.
|
|
172
|
+
|
|
173
|
+
## Roadmap for this kit
|
|
174
|
+
|
|
175
|
+
- pip / npm installer that copies skills into the right folder per agent and scaffolds `.sdlc/`
|
|
176
|
+
- Optional CI hook: run `/qa` checks headlessly on pull requests
|
|
177
|
+
|
|
178
|
+
Related prior art: [github/spec-kit](https://github.com/github/spec-kit).
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
ai_sdlc/__init__.py,sha256=gbdBYQ8g-h1ARESgDVQbfngnSYJl6bTvd_bgMpquR_0,64
|
|
2
|
+
ai_sdlc/cli.py,sha256=yYe1UMIfxvLOGDA0hxZiP4-1KLXMSD0ZV07B2VYY6P0,4135
|
|
3
|
+
ai_sdlc/skills/architecture-diagram/SKILL.md,sha256=j9B03K8VqoiHnQcj2pkxpS-5do58_SnkHBB3-lFRAPM,6386
|
|
4
|
+
ai_sdlc/skills/architecture-diagram/assets/template.html,sha256=-OGPVK7gDUbmtFCc2QM6iBbAs-bDvamd9kRhEkezzpw,12482
|
|
5
|
+
ai_sdlc/skills/build/SKILL.md,sha256=HB2E_k0S0zP43oEvgQpPOkCEyHiWqD32QJt-XK-swKU,2941
|
|
6
|
+
ai_sdlc/skills/qa/SKILL.md,sha256=RNPwT-Q-4yrAphd_FET0BWy_sJ2bNFXe8EHB7mHlF1E,3214
|
|
7
|
+
ai_sdlc/skills/roadmap/SKILL.md,sha256=lQHR_7cKchcNkqafbhaVEuuzA8rGxHncbS7L234JMW4,2647
|
|
8
|
+
ai_sdlc/skills/sdlc-init/SKILL.md,sha256=1jqZRp4rjzNp6kJ2Q_cfCqTuAuy09emLEmpTkNpQ-bQ,3985
|
|
9
|
+
ai_sdlc/skills/ship/SKILL.md,sha256=qZygTsGaWiBn0VlMLMLWKlgkL2BnOMyV_HZhfu3K6QI,2626
|
|
10
|
+
ai_sdlc/skills/spec/SKILL.md,sha256=klaOGevmnWU-XIFn3zrrGJEtj3TpfUvmqtKvy4ExQlA,6028
|
|
11
|
+
ai_sdlc_kit-0.1.0.dist-info/METADATA,sha256=b_Sly7FOLU5XzwdLzlpgftl8593liNOofB05swaIy7s,9634
|
|
12
|
+
ai_sdlc_kit-0.1.0.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
|
|
13
|
+
ai_sdlc_kit-0.1.0.dist-info/entry_points.txt,sha256=fGUpqBfCpkoZP2GkwmZpbEMll5AvDoatao928B5QRXs,45
|
|
14
|
+
ai_sdlc_kit-0.1.0.dist-info/licenses/LICENSE,sha256=l7UBWQC4JuYyqyEBmDyhoiQJ3mB_TX24wpFkCfimRJM,1063
|
|
15
|
+
ai_sdlc_kit-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 xajeel
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|