moai-adk 0.8.1__py3-none-any.whl → 0.8.3__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.
Potentially problematic release.
This version of moai-adk might be problematic. Click here for more details.
- moai_adk/cli/commands/update.py +15 -4
- moai_adk/core/config/migration.py +1 -1
- moai_adk/core/issue_creator.py +7 -3
- moai_adk/core/tags/__init__.py +86 -0
- moai_adk/core/tags/ci_validator.py +433 -0
- moai_adk/core/tags/cli.py +283 -0
- moai_adk/core/tags/generator.py +109 -0
- moai_adk/core/tags/inserter.py +99 -0
- moai_adk/core/tags/mapper.py +126 -0
- moai_adk/core/tags/parser.py +76 -0
- moai_adk/core/tags/pre_commit_validator.py +355 -0
- moai_adk/core/tags/reporter.py +957 -0
- moai_adk/core/tags/tags.py +149 -0
- moai_adk/core/tags/validator.py +897 -0
- moai_adk/templates/.claude/agents/alfred/cc-manager.md +25 -2
- moai_adk/templates/.claude/agents/alfred/debug-helper.md +24 -12
- moai_adk/templates/.claude/agents/alfred/doc-syncer.md +19 -12
- moai_adk/templates/.claude/agents/alfred/git-manager.md +20 -12
- moai_adk/templates/.claude/agents/alfred/implementation-planner.md +19 -12
- moai_adk/templates/.claude/agents/alfred/project-manager.md +29 -2
- moai_adk/templates/.claude/agents/alfred/quality-gate.md +25 -2
- moai_adk/templates/.claude/agents/alfred/skill-factory.md +30 -2
- moai_adk/templates/.claude/agents/alfred/spec-builder.md +26 -11
- moai_adk/templates/.claude/agents/alfred/tag-agent.md +30 -8
- moai_adk/templates/.claude/agents/alfred/tdd-implementer.md +27 -12
- moai_adk/templates/.claude/agents/alfred/trust-checker.md +25 -2
- moai_adk/templates/.claude/commands/alfred/0-project.md +5 -0
- moai_adk/templates/.claude/commands/alfred/1-plan.md +82 -19
- moai_adk/templates/.claude/commands/alfred/2-run.md +72 -15
- moai_adk/templates/.claude/commands/alfred/3-sync.md +74 -14
- moai_adk/templates/.claude/hooks/alfred/.moai/cache/version-check.json +9 -0
- moai_adk/templates/.claude/hooks/alfred/README.md +258 -145
- moai_adk/templates/.claude/hooks/alfred/TROUBLESHOOTING.md +471 -0
- moai_adk/templates/.claude/hooks/alfred/alfred_hooks.py +92 -57
- moai_adk/templates/.claude/hooks/alfred/core/version_cache.py +198 -0
- moai_adk/templates/.claude/hooks/alfred/notification__handle_events.py +102 -0
- moai_adk/templates/.claude/hooks/alfred/post_tool__log_changes.py +102 -0
- moai_adk/templates/.claude/hooks/alfred/pre_tool__auto_checkpoint.py +108 -0
- moai_adk/templates/.claude/hooks/alfred/session_end__cleanup.py +102 -0
- moai_adk/templates/.claude/hooks/alfred/session_start__show_project_info.py +102 -0
- moai_adk/templates/.claude/hooks/alfred/{core → shared/core}/project.py +286 -19
- moai_adk/templates/.claude/hooks/alfred/shared/core/version_cache.py +198 -0
- moai_adk/templates/.claude/hooks/alfred/{handlers → shared/handlers}/session.py +21 -7
- moai_adk/templates/.claude/hooks/alfred/stop__handle_interrupt.py +102 -0
- moai_adk/templates/.claude/hooks/alfred/subagent_stop__handle_subagent_end.py +102 -0
- moai_adk/templates/.claude/hooks/alfred/user_prompt__jit_load_docs.py +120 -0
- moai_adk/templates/.claude/settings.json +5 -5
- moai_adk/templates/.claude/skills/moai-foundation-ears/SKILL.md +9 -6
- moai_adk/templates/.claude/skills/moai-spec-authoring/README.md +56 -56
- moai_adk/templates/.claude/skills/moai-spec-authoring/SKILL.md +101 -100
- moai_adk/templates/.claude/skills/moai-spec-authoring/examples/validate-spec.sh +3 -3
- moai_adk/templates/.claude/skills/moai-spec-authoring/examples.md +219 -219
- moai_adk/templates/.claude/skills/moai-spec-authoring/reference.md +287 -287
- moai_adk/templates/.github/ISSUE_TEMPLATE/spec.yml +9 -11
- moai_adk/templates/.github/PULL_REQUEST_TEMPLATE.md +9 -21
- moai_adk/templates/.github/workflows/moai-release-create.yml +100 -0
- moai_adk/templates/.github/workflows/moai-release-pipeline.yml +182 -0
- moai_adk/templates/.github/workflows/release.yml +49 -0
- moai_adk/templates/.github/workflows/tag-report.yml +261 -0
- moai_adk/templates/.github/workflows/tag-validation.yml +176 -0
- moai_adk/templates/.moai/config.json +6 -1
- moai_adk/templates/.moai/hooks/install.sh +79 -0
- moai_adk/templates/.moai/hooks/pre-commit.sh +66 -0
- moai_adk/templates/CLAUDE.md +39 -40
- moai_adk/templates/src/moai_adk/core/__init__.py +5 -0
- moai_adk/templates/src/moai_adk/core/tags/__init__.py +86 -0
- moai_adk/templates/src/moai_adk/core/tags/ci_validator.py +433 -0
- moai_adk/templates/src/moai_adk/core/tags/cli.py +283 -0
- moai_adk/templates/src/moai_adk/core/tags/pre_commit_validator.py +355 -0
- moai_adk/templates/src/moai_adk/core/tags/reporter.py +957 -0
- moai_adk/templates/src/moai_adk/core/tags/validator.py +897 -0
- {moai_adk-0.8.1.dist-info → moai_adk-0.8.3.dist-info}/METADATA +240 -14
- {moai_adk-0.8.1.dist-info → moai_adk-0.8.3.dist-info}/RECORD +85 -50
- moai_adk/templates/.claude/hooks/alfred/HOOK_SCHEMA_VALIDATION.md +0 -313
- moai_adk/templates/.moai/memory/config-schema.md +0 -444
- /moai_adk/templates/.claude/hooks/alfred/{core → shared/core}/__init__.py +0 -0
- /moai_adk/templates/.claude/hooks/alfred/{core → shared/core}/checkpoint.py +0 -0
- /moai_adk/templates/.claude/hooks/alfred/{core → shared/core}/context.py +0 -0
- /moai_adk/templates/.claude/hooks/alfred/{core → shared/core}/tags.py +0 -0
- /moai_adk/templates/.claude/hooks/alfred/{handlers → shared/handlers}/__init__.py +0 -0
- /moai_adk/templates/.claude/hooks/alfred/{handlers → shared/handlers}/notification.py +0 -0
- /moai_adk/templates/.claude/hooks/alfred/{handlers → shared/handlers}/tool.py +0 -0
- /moai_adk/templates/.claude/hooks/alfred/{handlers → shared/handlers}/user.py +0 -0
- /moai_adk/templates/.moai/memory/{issue-label-mapping.md → ISSUE-LABEL-MAPPING.md} +0 -0
- {moai_adk-0.8.1.dist-info → moai_adk-0.8.3.dist-info}/WHEEL +0 -0
- {moai_adk-0.8.1.dist-info → moai_adk-0.8.3.dist-info}/entry_points.txt +0 -0
- {moai_adk-0.8.1.dist-info → moai_adk-0.8.3.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,177 +1,177 @@
|
|
|
1
1
|
# SPEC Authoring Reference
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## Complete Metadata Field Reference
|
|
4
4
|
|
|
5
|
-
###
|
|
5
|
+
### Seven Required Fields
|
|
6
6
|
|
|
7
|
-
#### 1. `id` –
|
|
7
|
+
#### 1. `id` – Unique SPEC Identifier
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
**Format**: `<DOMAIN>-<NUMBER>`
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
11
|
+
**Rules**:
|
|
12
|
+
- Immutable after assignment
|
|
13
|
+
- Use uppercase domain names (e.g., `AUTH`, `PAYMENT`, `CONFIG`)
|
|
14
|
+
- Three-digit numbers (001–999)
|
|
15
|
+
- Check for duplicates: `rg "@SPEC:AUTH-001" -n .moai/specs/`
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
- `AUTH-001` (
|
|
19
|
-
- `INSTALLER-SEC-001` (
|
|
20
|
-
- `TRUST-001` (TRUST
|
|
21
|
-
- `CONFIG-001` (
|
|
17
|
+
**Examples**:
|
|
18
|
+
- `AUTH-001` (authentication)
|
|
19
|
+
- `INSTALLER-SEC-001` (installer security)
|
|
20
|
+
- `TRUST-001` (TRUST principles)
|
|
21
|
+
- `CONFIG-001` (configuration schema)
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
**Directory Structure**:
|
|
24
24
|
```
|
|
25
25
|
.moai/specs/SPEC-AUTH-001/
|
|
26
|
-
├── spec.md #
|
|
27
|
-
├── diagrams/ #
|
|
28
|
-
└── examples/ #
|
|
26
|
+
├── spec.md # Main SPEC document
|
|
27
|
+
├── diagrams/ # Optional: architecture diagrams
|
|
28
|
+
└── examples/ # Optional: code examples
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
#### 2. `version` –
|
|
31
|
+
#### 2. `version` – Semantic Versioning
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
**Format**: `MAJOR.MINOR.PATCH`
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
**Lifecycle**:
|
|
36
36
|
|
|
37
37
|
| Version | Status | Description | Trigger |
|
|
38
38
|
|---------|--------|-------------|---------|
|
|
39
|
-
| `0.0.1` | draft |
|
|
40
|
-
| `0.0.x` | draft |
|
|
41
|
-
| `0.1.0` | completed |
|
|
42
|
-
| `0.1.x` | completed |
|
|
43
|
-
| `0.x.0` | completed |
|
|
44
|
-
| `1.0.0` | completed |
|
|
45
|
-
|
|
46
|
-
|
|
39
|
+
| `0.0.1` | draft | Initial draft | SPEC creation |
|
|
40
|
+
| `0.0.x` | draft | Draft improvements | Content editing |
|
|
41
|
+
| `0.1.0` | completed | Implementation complete | TDD finished + `/alfred:3-sync` |
|
|
42
|
+
| `0.1.x` | completed | Bug fixes, doc updates | Post-implementation patches |
|
|
43
|
+
| `0.x.0` | completed | Feature additions | Minor enhancements |
|
|
44
|
+
| `1.0.0` | completed | Production stable | Stakeholder approval |
|
|
45
|
+
|
|
46
|
+
**Version Update Example**:
|
|
47
47
|
```markdown
|
|
48
48
|
## HISTORY
|
|
49
49
|
|
|
50
50
|
### v0.2.0 (2025-11-15)
|
|
51
|
-
- **ADDED**:
|
|
52
|
-
- **CHANGED**:
|
|
51
|
+
- **ADDED**: Multi-factor authentication support
|
|
52
|
+
- **CHANGED**: Token expiration extended from 15 to 30 minutes
|
|
53
53
|
- **AUTHOR**: @YourHandle
|
|
54
54
|
|
|
55
55
|
### v0.1.0 (2025-10-30)
|
|
56
|
-
- **COMPLETED**: TDD
|
|
56
|
+
- **COMPLETED**: TDD implementation finished
|
|
57
57
|
- **EVIDENCE**: Commits 4c66076, 34e1bd9
|
|
58
58
|
- **TEST COVERAGE**: 89.13%
|
|
59
59
|
|
|
60
60
|
### v0.0.2 (2025-10-25)
|
|
61
|
-
- **REFINED**:
|
|
61
|
+
- **REFINED**: Added password reset flow requirements
|
|
62
62
|
- **AUTHOR**: @YourHandle
|
|
63
63
|
|
|
64
64
|
### v0.0.1 (2025-10-23)
|
|
65
|
-
- **INITIAL**: JWT
|
|
65
|
+
- **INITIAL**: JWT authentication SPEC draft created
|
|
66
66
|
```
|
|
67
67
|
|
|
68
|
-
#### 3. `status` –
|
|
68
|
+
#### 3. `status` – Progress State
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
**Values**: `draft` | `active` | `completed` | `deprecated`
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
**Lifecycle Flow**:
|
|
73
73
|
```
|
|
74
74
|
draft → active → completed → [deprecated]
|
|
75
75
|
↓ ↓ ↓
|
|
76
76
|
/alfred:1-plan /alfred:2-run /alfred:3-sync
|
|
77
77
|
```
|
|
78
78
|
|
|
79
|
-
|
|
80
|
-
- `draft`:
|
|
81
|
-
- `active`:
|
|
82
|
-
- `completed`:
|
|
83
|
-
- `deprecated`:
|
|
79
|
+
**Transitions**:
|
|
80
|
+
- `draft`: Authoring phase (v0.0.x)
|
|
81
|
+
- `active`: Implementation in progress (v0.0.x → v0.1.0)
|
|
82
|
+
- `completed`: Implementation finished (v0.1.0+)
|
|
83
|
+
- `deprecated`: Marked for removal
|
|
84
84
|
|
|
85
|
-
#### 4. `created` –
|
|
85
|
+
#### 4. `created` – Creation Date
|
|
86
86
|
|
|
87
|
-
|
|
87
|
+
**Format**: `YYYY-MM-DD`
|
|
88
88
|
|
|
89
|
-
|
|
90
|
-
-
|
|
91
|
-
- ISO 8601
|
|
92
|
-
-
|
|
89
|
+
**Rules**:
|
|
90
|
+
- Set once, never changed
|
|
91
|
+
- ISO 8601 date format
|
|
92
|
+
- Initial draft date
|
|
93
93
|
|
|
94
|
-
|
|
94
|
+
**Example**: `created: 2025-10-29`
|
|
95
95
|
|
|
96
|
-
#### 5. `updated` –
|
|
96
|
+
#### 5. `updated` – Last Modified Date
|
|
97
97
|
|
|
98
|
-
|
|
98
|
+
**Format**: `YYYY-MM-DD`
|
|
99
99
|
|
|
100
|
-
|
|
101
|
-
-
|
|
102
|
-
-
|
|
103
|
-
-
|
|
100
|
+
**Rules**:
|
|
101
|
+
- Update on every content change
|
|
102
|
+
- Initially same as `created`
|
|
103
|
+
- Reflects latest edit date
|
|
104
104
|
|
|
105
|
-
|
|
105
|
+
**Update Pattern**:
|
|
106
106
|
```yaml
|
|
107
|
-
created: 2025-10-
|
|
108
|
-
updated: 2025-10-
|
|
107
|
+
created: 2025-10-29 # Never change
|
|
108
|
+
updated: 2025-10-31 # Update on edit
|
|
109
109
|
```
|
|
110
110
|
|
|
111
|
-
#### 6. `author` –
|
|
111
|
+
#### 6. `author` – Primary Author
|
|
112
112
|
|
|
113
|
-
|
|
113
|
+
**Format**: `@{GitHubHandle}`
|
|
114
114
|
|
|
115
|
-
|
|
116
|
-
-
|
|
117
|
-
-
|
|
118
|
-
-
|
|
119
|
-
-
|
|
115
|
+
**Rules**:
|
|
116
|
+
- Single value (not an array)
|
|
117
|
+
- @ prefix required
|
|
118
|
+
- Case-sensitive (e.g., `@Goos`, not `@goos`)
|
|
119
|
+
- Additional contributors documented in HISTORY section
|
|
120
120
|
|
|
121
|
-
|
|
121
|
+
**Examples**:
|
|
122
122
|
```yaml
|
|
123
|
-
#
|
|
123
|
+
# Correct
|
|
124
124
|
author: @Goos
|
|
125
125
|
|
|
126
|
-
#
|
|
127
|
-
author: goos # @
|
|
128
|
-
authors: [@Goos] #
|
|
129
|
-
author: @goos #
|
|
126
|
+
# Incorrect
|
|
127
|
+
author: goos # Missing @
|
|
128
|
+
authors: [@Goos] # Array not allowed
|
|
129
|
+
author: @goos # Case mismatch
|
|
130
130
|
```
|
|
131
131
|
|
|
132
|
-
#### 7. `priority` –
|
|
132
|
+
#### 7. `priority` – Task Priority
|
|
133
133
|
|
|
134
|
-
|
|
134
|
+
**Values**: `critical` | `high` | `medium` | `low`
|
|
135
135
|
|
|
136
|
-
|
|
136
|
+
**Guidelines**:
|
|
137
137
|
|
|
138
138
|
| Priority | Description | Examples |
|
|
139
139
|
|----------|-------------|----------|
|
|
140
|
-
| `critical` |
|
|
141
|
-
| `high` |
|
|
142
|
-
| `medium` |
|
|
143
|
-
| `low` |
|
|
140
|
+
| `critical` | Production blocker, security vulnerability | Security patches, critical bugs |
|
|
141
|
+
| `high` | Major features, core functionality | Authentication, payment systems |
|
|
142
|
+
| `medium` | Improvements, enhancements | UI polish, performance optimization |
|
|
143
|
+
| `low` | Nice-to-have, documentation | README updates, minor refactoring |
|
|
144
144
|
|
|
145
145
|
---
|
|
146
146
|
|
|
147
|
-
###
|
|
147
|
+
### Nine Optional Fields
|
|
148
148
|
|
|
149
|
-
#### 8. `category` –
|
|
149
|
+
#### 8. `category` – Change Type
|
|
150
150
|
|
|
151
|
-
|
|
151
|
+
**Values**: `feature` | `bugfix` | `refactor` | `security` | `docs` | `perf`
|
|
152
152
|
|
|
153
|
-
|
|
153
|
+
**Usage**:
|
|
154
154
|
```yaml
|
|
155
|
-
category: feature #
|
|
156
|
-
category: bugfix #
|
|
157
|
-
category: refactor #
|
|
158
|
-
category: security #
|
|
159
|
-
category: docs #
|
|
160
|
-
category: perf #
|
|
155
|
+
category: feature # New capability
|
|
156
|
+
category: bugfix # Defect resolution
|
|
157
|
+
category: refactor # Code structure improvement
|
|
158
|
+
category: security # Security enhancement
|
|
159
|
+
category: docs # Documentation update
|
|
160
|
+
category: perf # Performance optimization
|
|
161
161
|
```
|
|
162
162
|
|
|
163
|
-
#### 9. `labels` –
|
|
163
|
+
#### 9. `labels` – Classification Tags
|
|
164
164
|
|
|
165
|
-
|
|
165
|
+
**Format**: String array
|
|
166
166
|
|
|
167
|
-
|
|
167
|
+
**Purpose**: Search, filtering, grouping
|
|
168
168
|
|
|
169
|
-
|
|
170
|
-
-
|
|
171
|
-
-
|
|
172
|
-
- `category
|
|
169
|
+
**Best Practices**:
|
|
170
|
+
- Use lowercase, kebab-case
|
|
171
|
+
- 2-5 labels per SPEC
|
|
172
|
+
- Avoid duplication with `category`
|
|
173
173
|
|
|
174
|
-
|
|
174
|
+
**Examples**:
|
|
175
175
|
```yaml
|
|
176
176
|
labels:
|
|
177
177
|
- authentication
|
|
@@ -189,59 +189,59 @@ labels:
|
|
|
189
189
|
- cross-platform
|
|
190
190
|
```
|
|
191
191
|
|
|
192
|
-
#### 10-13.
|
|
192
|
+
#### 10-13. Relationship Fields (Dependency Graph)
|
|
193
193
|
|
|
194
|
-
##### `depends_on` –
|
|
194
|
+
##### `depends_on` – Required SPECs
|
|
195
195
|
|
|
196
|
-
|
|
196
|
+
**Meaning**: SPECs that must complete first
|
|
197
197
|
|
|
198
|
-
|
|
198
|
+
**Example**:
|
|
199
199
|
```yaml
|
|
200
200
|
depends_on:
|
|
201
|
-
- USER-001 #
|
|
202
|
-
- TOKEN-001 #
|
|
201
|
+
- USER-001 # User model SPEC
|
|
202
|
+
- TOKEN-001 # Token generation SPEC
|
|
203
203
|
```
|
|
204
204
|
|
|
205
|
-
|
|
205
|
+
**Use Case**: Execution order, parallelization decisions
|
|
206
206
|
|
|
207
|
-
##### `blocks` –
|
|
207
|
+
##### `blocks` – Blocked SPECs
|
|
208
208
|
|
|
209
|
-
|
|
209
|
+
**Meaning**: SPECs blocked until this SPEC completes
|
|
210
210
|
|
|
211
|
-
|
|
211
|
+
**Example**:
|
|
212
212
|
```yaml
|
|
213
213
|
blocks:
|
|
214
|
-
- AUTH-002 # OAuth
|
|
215
|
-
- PAYMENT-001 #
|
|
214
|
+
- AUTH-002 # OAuth integration waits for base auth
|
|
215
|
+
- PAYMENT-001 # Payment requires authentication
|
|
216
216
|
```
|
|
217
217
|
|
|
218
|
-
##### `related_specs` –
|
|
218
|
+
##### `related_specs` – Related SPECs
|
|
219
219
|
|
|
220
|
-
|
|
220
|
+
**Meaning**: Related items without direct dependencies
|
|
221
221
|
|
|
222
|
-
|
|
222
|
+
**Example**:
|
|
223
223
|
```yaml
|
|
224
224
|
related_specs:
|
|
225
|
-
- SESSION-001 #
|
|
226
|
-
- AUDIT-001 #
|
|
225
|
+
- SESSION-001 # Session management (related but independent)
|
|
226
|
+
- AUDIT-001 # Audit logging (cross-cutting concern)
|
|
227
227
|
```
|
|
228
228
|
|
|
229
|
-
##### `related_issue` –
|
|
229
|
+
##### `related_issue` – Linked GitHub Issue
|
|
230
230
|
|
|
231
|
-
|
|
231
|
+
**Format**: Full GitHub issue URL
|
|
232
232
|
|
|
233
|
-
|
|
233
|
+
**Example**:
|
|
234
234
|
```yaml
|
|
235
235
|
related_issue: "https://github.com/modu-ai/moai-adk/issues/42"
|
|
236
236
|
```
|
|
237
237
|
|
|
238
|
-
#### 14-15.
|
|
238
|
+
#### 14-15. Scope Fields (Impact Analysis)
|
|
239
239
|
|
|
240
|
-
##### `scope.packages` –
|
|
240
|
+
##### `scope.packages` – Affected Packages
|
|
241
241
|
|
|
242
|
-
|
|
242
|
+
**Purpose**: Track which packages/modules are affected
|
|
243
243
|
|
|
244
|
-
|
|
244
|
+
**Example**:
|
|
245
245
|
```yaml
|
|
246
246
|
scope:
|
|
247
247
|
packages:
|
|
@@ -250,11 +250,11 @@ scope:
|
|
|
250
250
|
- src/api/routes/auth
|
|
251
251
|
```
|
|
252
252
|
|
|
253
|
-
##### `scope.files` –
|
|
253
|
+
##### `scope.files` – Key Files
|
|
254
254
|
|
|
255
|
-
|
|
255
|
+
**Purpose**: Reference principal implementation files
|
|
256
256
|
|
|
257
|
-
|
|
257
|
+
**Example**:
|
|
258
258
|
```yaml
|
|
259
259
|
scope:
|
|
260
260
|
files:
|
|
@@ -265,237 +265,237 @@ scope:
|
|
|
265
265
|
|
|
266
266
|
---
|
|
267
267
|
|
|
268
|
-
## EARS
|
|
268
|
+
## EARS Requirement Syntax
|
|
269
269
|
|
|
270
|
-
###
|
|
270
|
+
### Five EARS Patterns
|
|
271
271
|
|
|
272
|
-
EARS (Easy Approach to Requirements Syntax)
|
|
272
|
+
EARS (Easy Approach to Requirements Syntax) uses familiar keywords to provide systematic, testable requirements.
|
|
273
273
|
|
|
274
|
-
####
|
|
274
|
+
#### Pattern 1: Ubiquitous Requirements
|
|
275
275
|
|
|
276
|
-
|
|
276
|
+
**Template**: `The system shall [capability].`
|
|
277
277
|
|
|
278
|
-
|
|
278
|
+
**Purpose**: Always-active base functionality
|
|
279
279
|
|
|
280
|
-
|
|
281
|
-
-
|
|
282
|
-
-
|
|
283
|
-
-
|
|
280
|
+
**Characteristics**:
|
|
281
|
+
- No preconditions
|
|
282
|
+
- Always applicable
|
|
283
|
+
- Core functionality definition
|
|
284
284
|
|
|
285
|
-
|
|
285
|
+
**Examples**:
|
|
286
286
|
```markdown
|
|
287
|
-
**UR-001**:
|
|
287
|
+
**UR-001**: The system shall provide user authentication.
|
|
288
288
|
|
|
289
|
-
**UR-002**:
|
|
289
|
+
**UR-002**: The system shall support HTTPS connections.
|
|
290
290
|
|
|
291
|
-
**UR-003**:
|
|
291
|
+
**UR-003**: The system shall securely store user credentials.
|
|
292
292
|
|
|
293
|
-
**UR-004**:
|
|
293
|
+
**UR-004**: The mobile app size shall not exceed 50 MB.
|
|
294
294
|
|
|
295
|
-
**UR-005**: API
|
|
295
|
+
**UR-005**: API response time shall not exceed 200ms for 95% of requests.
|
|
296
296
|
```
|
|
297
297
|
|
|
298
|
-
|
|
299
|
-
- ✅
|
|
300
|
-
- ✅
|
|
301
|
-
- ✅
|
|
302
|
-
- ❌
|
|
298
|
+
**Best Practices**:
|
|
299
|
+
- ✅ Use active voice
|
|
300
|
+
- ✅ Single responsibility per requirement
|
|
301
|
+
- ✅ Measurable outcomes
|
|
302
|
+
- ❌ Avoid ambiguous terms ("user-friendly", "fast")
|
|
303
303
|
|
|
304
|
-
####
|
|
304
|
+
#### Pattern 2: Event-driven Requirements
|
|
305
305
|
|
|
306
|
-
|
|
306
|
+
**Template**: `WHEN [trigger], the system shall [response].`
|
|
307
307
|
|
|
308
|
-
|
|
308
|
+
**Purpose**: Behavior triggered by specific events
|
|
309
309
|
|
|
310
|
-
|
|
311
|
-
-
|
|
312
|
-
-
|
|
313
|
-
-
|
|
310
|
+
**Characteristics**:
|
|
311
|
+
- Triggered by discrete events
|
|
312
|
+
- Single-shot responses
|
|
313
|
+
- Cause-effect relationships
|
|
314
314
|
|
|
315
|
-
|
|
315
|
+
**Examples**:
|
|
316
316
|
```markdown
|
|
317
|
-
**ER-001**: WHEN
|
|
317
|
+
**ER-001**: WHEN the user submits valid credentials, the system shall issue a JWT token.
|
|
318
318
|
|
|
319
|
-
**ER-002**: WHEN
|
|
319
|
+
**ER-002**: WHEN a token expires, the system shall return HTTP 401 Unauthorized.
|
|
320
320
|
|
|
321
|
-
**ER-003**: WHEN
|
|
321
|
+
**ER-003**: WHEN the user clicks "Forgot Password", the system shall send a password reset email.
|
|
322
322
|
|
|
323
|
-
**ER-004**: WHEN
|
|
323
|
+
**ER-004**: WHEN database connection fails, the system shall retry 3 times with exponential backoff.
|
|
324
324
|
|
|
325
|
-
**ER-005**: WHEN
|
|
325
|
+
**ER-005**: WHEN file upload exceeds 10 MB, the system shall reject the upload with an error message.
|
|
326
326
|
```
|
|
327
327
|
|
|
328
|
-
|
|
328
|
+
**Advanced Pattern** (with postconditions):
|
|
329
329
|
```markdown
|
|
330
|
-
**ER-006**: WHEN
|
|
330
|
+
**ER-006**: WHEN payment transaction completes, the system shall send confirmation email, then update order status to "paid".
|
|
331
331
|
```
|
|
332
332
|
|
|
333
|
-
|
|
334
|
-
- ✅
|
|
335
|
-
- ✅
|
|
336
|
-
- ✅
|
|
337
|
-
- ❌
|
|
333
|
+
**Best Practices**:
|
|
334
|
+
- ✅ Single trigger per requirement
|
|
335
|
+
- ✅ Concrete, testable response
|
|
336
|
+
- ✅ Include error conditions
|
|
337
|
+
- ❌ Avoid chaining multiple WHEN clauses
|
|
338
338
|
|
|
339
|
-
####
|
|
339
|
+
#### Pattern 3: State-driven Requirements
|
|
340
340
|
|
|
341
|
-
|
|
341
|
+
**Template**: `WHILE [state], the system shall [behavior].`
|
|
342
342
|
|
|
343
|
-
|
|
343
|
+
**Purpose**: Persistent behavior during state
|
|
344
344
|
|
|
345
|
-
|
|
346
|
-
-
|
|
347
|
-
-
|
|
348
|
-
-
|
|
345
|
+
**Characteristics**:
|
|
346
|
+
- Active while state persists
|
|
347
|
+
- Continuous monitoring
|
|
348
|
+
- State-dependent behavior
|
|
349
349
|
|
|
350
|
-
|
|
350
|
+
**Examples**:
|
|
351
351
|
```markdown
|
|
352
|
-
**SR-001**: WHILE
|
|
352
|
+
**SR-001**: WHILE the user is in an authenticated state, the system shall permit access to protected routes.
|
|
353
353
|
|
|
354
|
-
**SR-002**: WHILE
|
|
354
|
+
**SR-002**: WHILE a token is valid, the system shall extract user ID from token claims.
|
|
355
355
|
|
|
356
|
-
**SR-003**: WHILE
|
|
356
|
+
**SR-003**: WHILE the system is in maintenance mode, the system shall return HTTP 503 Service Unavailable.
|
|
357
357
|
|
|
358
|
-
**SR-004**: WHILE
|
|
358
|
+
**SR-004**: WHILE battery level is below 20%, the mobile app shall reduce background sync frequency.
|
|
359
359
|
|
|
360
|
-
**SR-005**: WHILE
|
|
360
|
+
**SR-005**: WHILE file upload is in progress, the UI shall display a progress bar.
|
|
361
361
|
```
|
|
362
362
|
|
|
363
|
-
|
|
364
|
-
- ✅
|
|
365
|
-
- ✅
|
|
366
|
-
- ✅
|
|
367
|
-
- ❌
|
|
363
|
+
**Best Practices**:
|
|
364
|
+
- ✅ Clearly define state boundaries
|
|
365
|
+
- ✅ Specify state entry/exit conditions
|
|
366
|
+
- ✅ Test state transitions
|
|
367
|
+
- ❌ Avoid overlapping states
|
|
368
368
|
|
|
369
|
-
####
|
|
369
|
+
#### Pattern 4: Optional Features
|
|
370
370
|
|
|
371
|
-
|
|
371
|
+
**Template**: `WHERE [feature], the system can [behavior].`
|
|
372
372
|
|
|
373
|
-
|
|
373
|
+
**Purpose**: Feature-flag-based conditional functionality
|
|
374
374
|
|
|
375
|
-
|
|
376
|
-
-
|
|
377
|
-
-
|
|
378
|
-
-
|
|
375
|
+
**Characteristics**:
|
|
376
|
+
- Only applies when feature exists
|
|
377
|
+
- Configuration-dependent
|
|
378
|
+
- Product variant support
|
|
379
379
|
|
|
380
|
-
|
|
380
|
+
**Examples**:
|
|
381
381
|
```markdown
|
|
382
|
-
**OF-001**: WHERE
|
|
382
|
+
**OF-001**: WHERE multi-factor authentication is enabled, the system can require OTP verification after password confirmation.
|
|
383
383
|
|
|
384
|
-
**OF-002**: WHERE
|
|
384
|
+
**OF-002**: WHERE session logging is enabled, the system can record login timestamp and IP address.
|
|
385
385
|
|
|
386
|
-
**OF-003**: WHERE
|
|
386
|
+
**OF-003**: WHERE premium subscription is enabled, the system can permit unlimited API calls.
|
|
387
387
|
|
|
388
|
-
**OF-004**: WHERE
|
|
388
|
+
**OF-004**: WHERE dark mode is selected, the UI can render in dark color scheme.
|
|
389
389
|
|
|
390
|
-
**OF-005**: WHERE
|
|
390
|
+
**OF-005**: WHERE analytics consent is granted, the system can track user behavior.
|
|
391
391
|
```
|
|
392
392
|
|
|
393
|
-
|
|
394
|
-
- ✅ "
|
|
395
|
-
- ✅
|
|
396
|
-
- ✅
|
|
397
|
-
- ❌
|
|
393
|
+
**Best Practices**:
|
|
394
|
+
- ✅ Use "can" (permissive) not "shall" (mandatory)
|
|
395
|
+
- ✅ Clearly define feature flag condition
|
|
396
|
+
- ✅ Specify default behavior without feature
|
|
397
|
+
- ❌ Don't make core functionality optional
|
|
398
398
|
|
|
399
|
-
####
|
|
399
|
+
#### Pattern 5: Unwanted Behaviors
|
|
400
400
|
|
|
401
|
-
|
|
401
|
+
**Template**: `IF [condition], THEN the system shall [respond appropriately].`
|
|
402
402
|
|
|
403
|
-
|
|
403
|
+
**Purpose**: Error handling, quality gates, business rule enforcement
|
|
404
404
|
|
|
405
|
-
|
|
406
|
-
-
|
|
407
|
-
-
|
|
408
|
-
-
|
|
405
|
+
**Characteristics**:
|
|
406
|
+
- Conditional enforcement
|
|
407
|
+
- Quality gates and constraints
|
|
408
|
+
- Business rule validation
|
|
409
409
|
|
|
410
|
-
|
|
410
|
+
**Examples**:
|
|
411
411
|
```markdown
|
|
412
|
-
**
|
|
412
|
+
**UB-001**: IF a token has expired, THEN the system shall deny access and return HTTP 401.
|
|
413
413
|
|
|
414
|
-
**
|
|
414
|
+
**UB-002**: IF 5 or more login failures occur within 10 minutes, THEN the system shall temporarily lock the account.
|
|
415
415
|
|
|
416
|
-
**
|
|
416
|
+
**UB-003**: Response processing time shall not exceed 5 seconds.
|
|
417
417
|
|
|
418
|
-
**
|
|
418
|
+
**UB-004**: IF password length is less than 8 characters, THEN the system shall reject registration.
|
|
419
419
|
|
|
420
|
-
**
|
|
420
|
+
**UB-005**: IF API rate limit is exceeded, THEN the system shall return HTTP 429 Too Many Requests.
|
|
421
421
|
```
|
|
422
422
|
|
|
423
|
-
|
|
423
|
+
**Simplified Constraints** (no condition):
|
|
424
424
|
```markdown
|
|
425
|
-
**
|
|
425
|
+
**UB-006**: The system shall never store passwords in plaintext.
|
|
426
426
|
|
|
427
|
-
**
|
|
427
|
+
**UB-007**: All API endpoints except /health and /login shall require authentication.
|
|
428
428
|
```
|
|
429
429
|
|
|
430
|
-
|
|
431
|
-
- ✅
|
|
432
|
-
- ✅
|
|
433
|
-
- ✅
|
|
434
|
-
- ❌
|
|
430
|
+
**Best Practices**:
|
|
431
|
+
- ✅ Use SHALL for strict constraints, SHOULD for recommendations
|
|
432
|
+
- ✅ Quantify limits (time, size, count)
|
|
433
|
+
- ✅ Specify enforcement mechanism
|
|
434
|
+
- ❌ Avoid vague constraints
|
|
435
435
|
|
|
436
436
|
---
|
|
437
437
|
|
|
438
|
-
## EARS
|
|
438
|
+
## EARS Pattern Selection Guide
|
|
439
439
|
|
|
440
|
-
|
|
|
440
|
+
| Pattern | Keyword | Use When | Context Example |
|
|
441
441
|
|---------|---------|----------|-----------------|
|
|
442
|
-
| **Ubiquitous** | shall |
|
|
443
|
-
| **Event-driven** | WHEN |
|
|
444
|
-
| **State-driven** | WHILE |
|
|
445
|
-
| **Optional** | WHERE |
|
|
446
|
-
| **
|
|
442
|
+
| **Ubiquitous** | shall | Core feature, always active | "System shall provide login" |
|
|
443
|
+
| **Event-driven** | WHEN | Response to specific event | "WHEN login fails, show error" |
|
|
444
|
+
| **State-driven** | WHILE | Continuous during state | "WHILE logged in, allow access" |
|
|
445
|
+
| **Optional** | WHERE | Feature flag or config | "WHERE premium enabled, unlock" |
|
|
446
|
+
| **Unwanted Behaviors** | IF-THEN | Error handling, quality gates | "IF expired, deny and return 401" |
|
|
447
447
|
|
|
448
448
|
---
|
|
449
449
|
|
|
450
|
-
## HISTORY
|
|
450
|
+
## HISTORY Section Format
|
|
451
451
|
|
|
452
|
-
HISTORY
|
|
452
|
+
The HISTORY section documents all SPEC versions and changes.
|
|
453
453
|
|
|
454
|
-
###
|
|
454
|
+
### Structure
|
|
455
455
|
|
|
456
456
|
```markdown
|
|
457
457
|
## HISTORY
|
|
458
458
|
|
|
459
459
|
### v{MAJOR}.{MINOR}.{PATCH} ({YYYY-MM-DD})
|
|
460
|
-
- **{CHANGE_TYPE}**: {
|
|
461
|
-
- **AUTHOR**: {GitHub
|
|
462
|
-
- **{
|
|
460
|
+
- **{CHANGE_TYPE}**: {Description}
|
|
461
|
+
- **AUTHOR**: {GitHub handle}
|
|
462
|
+
- **{Additional context}**: {Details}
|
|
463
463
|
```
|
|
464
464
|
|
|
465
|
-
###
|
|
465
|
+
### Change Types
|
|
466
466
|
|
|
467
467
|
| Type | Description | Example |
|
|
468
468
|
|------|-------------|---------|
|
|
469
|
-
| **INITIAL** |
|
|
470
|
-
| **REFINED** |
|
|
471
|
-
| **COMPLETED** |
|
|
472
|
-
| **ADDED** |
|
|
473
|
-
| **CHANGED** |
|
|
474
|
-
| **FIXED** |
|
|
475
|
-
| **DEPRECATED** |
|
|
469
|
+
| **INITIAL** | First draft | `v0.0.1: INITIAL draft created` |
|
|
470
|
+
| **REFINED** | Content update during draft | `v0.0.2: REFINED requirements based on review` |
|
|
471
|
+
| **COMPLETED** | Implementation finished | `v0.1.0: COMPLETED TDD implementation` |
|
|
472
|
+
| **ADDED** | New requirements/features | `v0.2.0: ADDED multi-factor authentication` |
|
|
473
|
+
| **CHANGED** | Modified requirement | `v0.2.0: CHANGED token expiration 15→30 minutes` |
|
|
474
|
+
| **FIXED** | Post-implementation bug fix | `v0.1.1: FIXED token refresh race condition` |
|
|
475
|
+
| **DEPRECATED** | Mark for removal | `v1.5.0: DEPRECATED legacy auth endpoint` |
|
|
476
476
|
|
|
477
|
-
###
|
|
477
|
+
### Complete HISTORY Example
|
|
478
478
|
|
|
479
479
|
```markdown
|
|
480
480
|
## HISTORY
|
|
481
481
|
|
|
482
482
|
### v0.2.0 (2025-11-15)
|
|
483
|
-
- **ADDED**:
|
|
484
|
-
- **CHANGED**:
|
|
483
|
+
- **ADDED**: Multi-factor authentication via OTP
|
|
484
|
+
- **CHANGED**: Token expiration extended to 30 minutes based on user feedback
|
|
485
485
|
- **AUTHOR**: @Goos
|
|
486
486
|
- **REVIEWER**: @SecurityTeam
|
|
487
|
-
- **RATIONALE**:
|
|
487
|
+
- **RATIONALE**: Maintain security posture while improving UX
|
|
488
488
|
|
|
489
489
|
### v0.1.1 (2025-11-01)
|
|
490
|
-
- **FIXED**:
|
|
490
|
+
- **FIXED**: Token refresh race condition
|
|
491
491
|
- **EVIDENCE**: Commit 3f9a2b7
|
|
492
492
|
- **AUTHOR**: @Goos
|
|
493
493
|
|
|
494
494
|
### v0.1.0 (2025-10-30)
|
|
495
|
-
- **COMPLETED**: TDD
|
|
495
|
+
- **COMPLETED**: TDD implementation finished
|
|
496
496
|
- **AUTHOR**: @Goos
|
|
497
497
|
- **EVIDENCE**: Commits 4c66076, 34e1bd9, 1dec08f
|
|
498
|
-
- **TEST COVERAGE**: 89.13% (
|
|
498
|
+
- **TEST COVERAGE**: 89.13% (target: 85%)
|
|
499
499
|
- **QUALITY METRICS**:
|
|
500
500
|
- Test Pass Rate: 100% (42/42 tests)
|
|
501
501
|
- Linting: ruff ✅
|
|
@@ -506,39 +506,39 @@ HISTORY 섹션은 모든 SPEC 버전과 변경 사항을 문서화합니다.
|
|
|
506
506
|
- @CODE:AUTH-001: 12 occurrences
|
|
507
507
|
|
|
508
508
|
### v0.0.2 (2025-10-25)
|
|
509
|
-
- **REFINED**:
|
|
510
|
-
- **REFINED**:
|
|
509
|
+
- **REFINED**: Added password reset flow requirements
|
|
510
|
+
- **REFINED**: Clarified token lifetime constraints
|
|
511
511
|
- **AUTHOR**: @Goos
|
|
512
512
|
|
|
513
513
|
### v0.0.1 (2025-10-23)
|
|
514
|
-
- **INITIAL**: JWT
|
|
514
|
+
- **INITIAL**: JWT authentication SPEC draft created
|
|
515
515
|
- **AUTHOR**: @Goos
|
|
516
|
-
- **SCOPE**:
|
|
517
|
-
- **CONTEXT**: 2025
|
|
516
|
+
- **SCOPE**: User authentication, token generation, token validation
|
|
517
|
+
- **CONTEXT**: Q4 2025 product roadmap requirements
|
|
518
518
|
```
|
|
519
519
|
|
|
520
520
|
---
|
|
521
521
|
|
|
522
|
-
## TAG
|
|
522
|
+
## TAG Integration
|
|
523
523
|
|
|
524
|
-
### TAG
|
|
524
|
+
### TAG Block Format
|
|
525
525
|
|
|
526
|
-
|
|
526
|
+
All SPEC documents start with a TAG block after the title:
|
|
527
527
|
|
|
528
528
|
```markdown
|
|
529
529
|
# @SPEC:AUTH-001: JWT Authentication System
|
|
530
530
|
```
|
|
531
531
|
|
|
532
|
-
### TAG
|
|
532
|
+
### TAG Chain Reference
|
|
533
533
|
|
|
534
|
-
|
|
534
|
+
Link related TAGs in SPEC:
|
|
535
535
|
|
|
536
536
|
```markdown
|
|
537
537
|
## Traceability (@TAG Chain)
|
|
538
538
|
|
|
539
|
-
### TAG
|
|
539
|
+
### TAG Chain Structure
|
|
540
540
|
```
|
|
541
|
-
@SPEC:AUTH-001 (
|
|
541
|
+
@SPEC:AUTH-001 (this document)
|
|
542
542
|
↓
|
|
543
543
|
@TEST:AUTH-001 (tests/auth/service.test.ts)
|
|
544
544
|
↓
|
|
@@ -547,70 +547,70 @@ SPEC에서 관련 TAG 연결:
|
|
|
547
547
|
@DOC:AUTH-001 (docs/api/authentication.md)
|
|
548
548
|
```
|
|
549
549
|
|
|
550
|
-
###
|
|
550
|
+
### Validation Commands
|
|
551
551
|
```bash
|
|
552
|
-
# SPEC TAG
|
|
552
|
+
# Validate SPEC TAG
|
|
553
553
|
rg '@SPEC:AUTH-001' -n .moai/specs/
|
|
554
554
|
|
|
555
|
-
#
|
|
555
|
+
# Check for duplicate IDs
|
|
556
556
|
rg '@SPEC:AUTH' -n .moai/specs/
|
|
557
557
|
rg 'AUTH-001' -n
|
|
558
558
|
|
|
559
|
-
#
|
|
559
|
+
# Scan full TAG chain
|
|
560
560
|
rg '@(SPEC|TEST|CODE|DOC):AUTH-001' -n
|
|
561
561
|
```
|
|
562
562
|
```
|
|
563
563
|
|
|
564
564
|
---
|
|
565
565
|
|
|
566
|
-
##
|
|
566
|
+
## Validation Commands
|
|
567
567
|
|
|
568
|
-
###
|
|
568
|
+
### Quick Validation Script
|
|
569
569
|
|
|
570
570
|
```bash
|
|
571
571
|
#!/usr/bin/env bash
|
|
572
|
-
# validate-spec.sh - SPEC
|
|
572
|
+
# validate-spec.sh - SPEC validation helper
|
|
573
573
|
|
|
574
574
|
SPEC_DIR="$1"
|
|
575
575
|
|
|
576
|
-
echo "SPEC
|
|
576
|
+
echo "Validating SPEC: $SPEC_DIR"
|
|
577
577
|
|
|
578
|
-
#
|
|
579
|
-
echo -n "
|
|
578
|
+
# Check required fields
|
|
579
|
+
echo -n "Required fields... "
|
|
580
580
|
rg "^(id|version|status|created|updated|author|priority):" "$SPEC_DIR/spec.md" | wc -l | grep -q "7" && echo "✅" || echo "❌"
|
|
581
581
|
|
|
582
|
-
#
|
|
583
|
-
echo -n "
|
|
582
|
+
# Check author format
|
|
583
|
+
echo -n "Author format... "
|
|
584
584
|
rg "^author: @[A-Z]" "$SPEC_DIR/spec.md" > /dev/null && echo "✅" || echo "❌"
|
|
585
585
|
|
|
586
|
-
#
|
|
587
|
-
echo -n "
|
|
586
|
+
# Check version format
|
|
587
|
+
echo -n "Version format... "
|
|
588
588
|
rg "^version: 0\.\d+\.\d+" "$SPEC_DIR/spec.md" > /dev/null && echo "✅" || echo "❌"
|
|
589
589
|
|
|
590
|
-
# HISTORY
|
|
591
|
-
echo -n "HISTORY
|
|
590
|
+
# Check HISTORY section
|
|
591
|
+
echo -n "HISTORY section... "
|
|
592
592
|
rg "^## HISTORY" "$SPEC_DIR/spec.md" > /dev/null && echo "✅" || echo "❌"
|
|
593
593
|
|
|
594
|
-
# TAG
|
|
595
|
-
echo -n "TAG
|
|
594
|
+
# Check TAG block
|
|
595
|
+
echo -n "TAG block... "
|
|
596
596
|
rg "^# @SPEC:" "$SPEC_DIR/spec.md" > /dev/null && echo "✅" || echo "❌"
|
|
597
597
|
|
|
598
|
-
#
|
|
598
|
+
# Check for duplicate IDs
|
|
599
599
|
SPEC_ID=$(basename "$SPEC_DIR" | sed 's/SPEC-//')
|
|
600
600
|
DUPLICATE_COUNT=$(rg "@SPEC:$SPEC_ID" -n .moai/specs/ | wc -l)
|
|
601
|
-
echo -n "
|
|
601
|
+
echo -n "Duplicate ID check... "
|
|
602
602
|
[ "$DUPLICATE_COUNT" -eq 1 ] && echo "✅" || echo "❌ (found $DUPLICATE_COUNT occurrences)"
|
|
603
603
|
|
|
604
|
-
echo "
|
|
604
|
+
echo "Validation complete!"
|
|
605
605
|
```
|
|
606
606
|
|
|
607
|
-
###
|
|
607
|
+
### Usage
|
|
608
608
|
|
|
609
609
|
```bash
|
|
610
|
-
#
|
|
610
|
+
# Validate single SPEC
|
|
611
611
|
./validate-spec.sh .moai/specs/SPEC-AUTH-001
|
|
612
612
|
|
|
613
|
-
#
|
|
613
|
+
# Validate all SPECs
|
|
614
614
|
for spec in .moai/specs/SPEC-*/; do
|
|
615
615
|
./validate-spec.sh "$spec"
|
|
616
616
|
done
|
|
@@ -618,5 +618,5 @@ done
|
|
|
618
618
|
|
|
619
619
|
---
|
|
620
620
|
|
|
621
|
-
**Last Updated**: 2025-10-
|
|
622
|
-
**Version**: 1.
|
|
621
|
+
**Last Updated**: 2025-10-29
|
|
622
|
+
**Version**: 1.2.0
|