speckeeper 0.9.2 → 0.9.3
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.
- package/README.md +2 -0
- package/cli-contract.yaml +574 -0
- package/docs/cli-reference.md +449 -0
- package/docs/design/actors.md +72 -0
- package/docs/design/arch-actors.md +42 -0
- package/docs/design/artifacts.md +69 -0
- package/docs/design/cli-commands.md +332 -0
- package/docs/design/constraints.md +66 -0
- package/docs/design/containers.md +86 -0
- package/docs/design/entities.md +161 -0
- package/docs/design/external-systems.md +42 -0
- package/docs/design/functional-requirements.md +810 -0
- package/docs/design/glossary.md +242 -0
- package/docs/design/nonfunctional-requirements.md +242 -0
- package/docs/design/test-refs.md +258 -0
- package/docs/design/usecases.md +114 -0
- package/docs/directory-entries.md +22 -0
- package/docs/framework_requirements_spec.md +1052 -0
- package/docs/model-guide.md +762 -0
- package/docs/model_entity_catalog.md +67 -0
- package/docs/scaffold-mermaid-spec.md +357 -0
- package/package.json +7 -2
|
@@ -0,0 +1,1052 @@
|
|
|
1
|
+
# Requirements Specification for Framework Managing Requirements and Design in TypeScript with Markdown Generation (Draft)
|
|
2
|
+
|
|
3
|
+
Created: 2026-02-03
|
|
4
|
+
Version: 0.1
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 1. Background and Purpose
|
|
9
|
+
|
|
10
|
+
To maximize consistency and review quality in requirements definition, architecture design, and high-level design (upstream), upstream artifacts are managed with **TypeScript models as SSOT**, and review documents/diagrams are **automatically generated from TS**. Additionally, artifacts managed by existing tools/formats (OpenAPI, DDL, etc.) are treated as **external SSOT**, and **consistency checks** are performed with TS models.
|
|
11
|
+
|
|
12
|
+
Specifically:
|
|
13
|
+
|
|
14
|
+
- **Requirements definition** is maintained as structured data in TypeScript, generating Markdown
|
|
15
|
+
- **Logical architecture** is modeled in TypeScript, generating **Mermaid C4**
|
|
16
|
+
- **Conceptual model** (main entities/relations) is modeled in TypeScript, generating **Mermaid erDiagram**
|
|
17
|
+
- **Screen specifications** (screen list/transitions/forms/states) are modeled in TypeScript, generating **Mermaid flowchart/stateDiagram**
|
|
18
|
+
- **API specifications** (OpenAPI), **DB definitions** (DDL), etc. are directly managed as external SSOT, with **consistency checks** against TS models
|
|
19
|
+
|
|
20
|
+
Design artifacts (API specifications, screen specifications, DB schemas, etc.) and requirements are linked by ID, establishing a state where **artifact existence and consistency** can be mechanically checked.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 2. Goals (Desired State)
|
|
25
|
+
|
|
26
|
+
- Requirements definition and design core can be managed with **TypeScript** as the source of truth (Single Source of Truth)
|
|
27
|
+
- **Logical architecture** can be modeled in TypeScript, generating **Mermaid C4 diagrams**
|
|
28
|
+
- **Conceptual model** (Entity/Relation/key attributes) can be modeled in TypeScript, generating **Mermaid erDiagram**
|
|
29
|
+
- **Screen specifications** (screen list/transitions/forms/states) can be modeled in TypeScript, generating **Mermaid flowchart/stateDiagram**
|
|
30
|
+
- Generated Markdown/Mermaid is **always reproducible from TS**, and CI fails if manual edits are mixed in
|
|
31
|
+
- **Consistency can be automatically checked** between **external SSOT** (OpenAPI, DDL, IaC, etc.) and TS models
|
|
32
|
+
- Traceability from requirements → design artifacts (HLD: API specs/logical architecture/conceptual model/screen specs, LLD: schemas, etc.) can be reliably linked by ID
|
|
33
|
+
- **TBD allowance/prohibition** gates can be enforced according to phase (REQ/HLD/LLD/OPS)
|
|
34
|
+
- Requirements in areas prone to omission, such as monitoring requirements (CloudWatch) and data model requirements, can be **made mandatory through types** and inspected
|
|
35
|
+
- Object types for modeling targets (monitoring, conceptual model, screen specifications, security, etc.) are **extensible by designers**
|
|
36
|
+
- **Existing artifact formats** (OpenAPI, DDL, Terraform, etc.) can be leveraged, coexisting with the ecosystem
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 3. Non-Goals (Not Covered by This Framework)
|
|
41
|
+
|
|
42
|
+
- Automatic "creation" of requirements (text generation) is not the primary purpose (input is done by humans)
|
|
43
|
+
- Formal verification of all logic specifications (model checking with TLA+/Alloy, etc.) is not a mandatory requirement (future extension is possible)
|
|
44
|
+
- Completely replacing requirements management tools (Jama/DOORS, etc.)
|
|
45
|
+
- However, **export to ReqIF, etc.** will be considered in the future (for audit, baseline, collaboration with external partners)
|
|
46
|
+
- Complete management of review/approval workflows and audit trails (substituted by PR-based operations)
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## 4. Terms and Definitions
|
|
51
|
+
|
|
52
|
+
<!--@embedoc:model_data model="term" format="spec-terms" include="terms"-->
|
|
53
|
+
- **TS-SSOT**: A policy where TypeScript is the source of truth and generated artifacts are regeneratable derivatives
|
|
54
|
+
- **External SSOT(External SSOT)**: Artifacts managed by existing tools/formats (OpenAPI, DDL, IaC, etc.). This framework does not generate them but checks consistency against them
|
|
55
|
+
- **External SSOT Reference(External SSOT Reference)**: Minimal interface for referencing external SSOT from TS models (ID, path, correspondence, etc.)
|
|
56
|
+
- **Model(Model)**: A unit of design information defined in TypeScript. Inherits from Model base class and has schema, lint rules, renderers, etc.
|
|
57
|
+
- **Design Artifact(Artifact)**: Design artifacts to satisfy requirements such as monitoring, Runbook, Dashboard, data schema, etc.
|
|
58
|
+
- **Concretization Slot(Concretization slot)**: Items to be filled in subsequent phases (allows TBD while having a deadline phase)
|
|
59
|
+
- **ID Linkage**: A mechanism that ensures componentId/entityId/requirementId from TS models appear in external SSOT, generated artifacts, implementation, and IaC to connect design and implementation
|
|
60
|
+
- **Drift(drift)**: A state where docs//specs/ that should have been generated from TS have differences due to manual edits, etc.
|
|
61
|
+
- **Reconciliation(Reconciliation)**: Checks to bridge gaps between design and external SSOT/implementation (design consistency, external SSOT consistency, implementation existence verification)
|
|
62
|
+
- **User-defined Model(User-defined Model)**: Project-specific models defined by users inheriting from the Model base class. The standard way to use speckeeper
|
|
63
|
+
<!--@embedoc:end-->
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## 5. Stakeholders
|
|
68
|
+
|
|
69
|
+
<!--@embedoc:model_data model="actor" format="list" include="human"-->
|
|
70
|
+
- 👤 **Requirements Engineer**: PO/PM/Business representative. Defines requirements and acceptance criteria in TS models and generates documentation
|
|
71
|
+
- 👤 **Design Engineer**: Architect/Development lead. Defines logical architecture and concept models in TS models and generates C4/ER diagrams
|
|
72
|
+
- 👤 **Implementation Engineer**: App/Infrastructure developer. Defines screen specifications and process flows, checks consistency with external SSOT
|
|
73
|
+
- 👤 **Operations Engineer**: SRE/Operations staff. Manages observability requirements, Runbook and monitoring configuration consistency
|
|
74
|
+
- 👤 **Reviewer**: Quality/Security staff. Performs design reviews and verifies consistency check results
|
|
75
|
+
<!--@embedoc:end-->
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## 6. Expected Workflow (Standard)
|
|
80
|
+
|
|
81
|
+
### 6.1 Overall Pipeline
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
85
|
+
│ 1) SSOT (design/ TypeScript models) │
|
|
86
|
+
│ - requirements.ts : Requirements (requests/acceptance criteria/TBD slots) │
|
|
87
|
+
│ - architecture.ts : Logical architecture (component/boundary/layer) │
|
|
88
|
+
│ - concept-model.ts : Conceptual model (entity/relation + rules) │
|
|
89
|
+
│ - usecases.ts : Use cases/actors │
|
|
90
|
+
│ - glossary.ts : Glossary/abbreviations │
|
|
91
|
+
│ - artifacts.ts : Artifacts/directory structure │
|
|
92
|
+
│ - cli-commands.ts : CLI command specifications │
|
|
93
|
+
│ - test-refs.ts : Test definitions/requirement linkage │
|
|
94
|
+
│ - _models/ : Model definitions (schema/Lint/output) │
|
|
95
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
96
|
+
↓ npm run ci
|
|
97
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
98
|
+
│ 2) CI Pipeline (3 phases) │
|
|
99
|
+
├─────────────────────────────────────────────────────────────────┤
|
|
100
|
+
│ Phase 1: ci:validate (Validation) │
|
|
101
|
+
│ ① tsc --noEmit : Type checking │
|
|
102
|
+
│ ② eslint src/ : Source code quality │
|
|
103
|
+
│ ③ eslint design/ : Design file quality │
|
|
104
|
+
│ ④ tsup : Build (dist/ generation) │
|
|
105
|
+
│ ⑤ speckeeper lint : Model consistency (references/ID/phase gates) │
|
|
106
|
+
│ ⑥ vitest run : Unit tests (288 cases) │
|
|
107
|
+
├─────────────────────────────────────────────────────────────────┤
|
|
108
|
+
│ Phase 2: ci:generate (Generation) │
|
|
109
|
+
│ ⑦ embedoc build : docs/ marker update │
|
|
110
|
+
├─────────────────────────────────────────────────────────────────┤
|
|
111
|
+
│ Phase 3: ci:verify (Reconciliation) │
|
|
112
|
+
│ ⑧ speckeeper check external-ssot : External SSOT consistency │
|
|
113
|
+
│ ⑨ speckeeper check test : Test-requirement linkage │
|
|
114
|
+
│ ⑩ speckeeper check test --coverage : Coverage verification │
|
|
115
|
+
│ - TestRef → Requirement (acceptanceCriteria) │
|
|
116
|
+
│ - Requirement → UseCase (satisfies) │
|
|
117
|
+
│ - Component → Requirement (implements) │
|
|
118
|
+
│ - Entity → Artifact (documents) │
|
|
119
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
120
|
+
↓ Reference ↓ Consistency check
|
|
121
|
+
┌────────────────────────────────┐ ┌────────────────────────────────┐
|
|
122
|
+
│ 3a) Generated artifacts (docs/)│ │ 3b) External SSOT │
|
|
123
|
+
│ - Markdown (updated by embedoc) │ │ - OpenAPI (YAML/JSON) │
|
|
124
|
+
│ - Mermaid diagrams │ │ - DDL / Prisma │
|
|
125
|
+
│ → Manual edits outside markers │ │ - CloudFormation / Terraform │
|
|
126
|
+
└────────────────────────────────┘ └────────────────────────────────┘
|
|
127
|
+
↓
|
|
128
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
129
|
+
│ 4) Implementation (src/) │
|
|
130
|
+
│ - Implement by referencing external SSOT (OpenAPI/DDL, etc.) │
|
|
131
|
+
│ - Link via TestRef which requirement/command corresponds to │
|
|
132
|
+
│ - Declare which requirement is implemented via relations │
|
|
133
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### 6.2 Phase-based Work
|
|
137
|
+
|
|
138
|
+
<!--@embedoc:model_data model="usecase" format="phase-workflow"-->
|
|
139
|
+
1. **REQ Phase**
|
|
140
|
+
- Write requirements in TypeScript
|
|
141
|
+
- Generate Markdown/Mermaid via `build` (review on PR by viewing docs/)
|
|
142
|
+
- Verify requirement consistency, required fields, reference integrity, and phase gate via `lint`
|
|
143
|
+
|
|
144
|
+
2. **HLD Phase**
|
|
145
|
+
- Write logical architecture (`design/architecture.ts`) in TypeScript
|
|
146
|
+
- Generate Markdown/Mermaid via `build` (review on PR by viewing docs/)
|
|
147
|
+
- Verify architecture consistency (layer violations, boundary crossings, etc.) via `lint`
|
|
148
|
+
- Write screen specifications (`design/screens.ts`) in TypeScript
|
|
149
|
+
- Verify screen consistency via `lint`
|
|
150
|
+
|
|
151
|
+
3. **LLD Phase**
|
|
152
|
+
- Write concept model (`design/concept-model.ts`) in TypeScript
|
|
153
|
+
- Generate Markdown/Mermaid via `build` (review on PR by viewing docs/)
|
|
154
|
+
- Write form details (`design/screens/forms/`) in TypeScript
|
|
155
|
+
|
|
156
|
+
4. **Implementation Phase**
|
|
157
|
+
- Verify requirement-external SSOT consistency via `check external-ssot`
|
|
158
|
+
- Check change impact scope via `impact`
|
|
159
|
+
|
|
160
|
+
5. **OPS Phase**
|
|
161
|
+
- Finalize runbook URLs, etc. and pass the final gate
|
|
162
|
+
|
|
163
|
+
6. **CI (Always)**
|
|
164
|
+
- Verify ID uniqueness, reference integrity, and layer dependency direction via `lint`
|
|
165
|
+
- Detect manual edits to artifacts via `drift`
|
|
166
|
+
- Verify implementation-contract consistency via `check contract`
|
|
167
|
+
<!--@embedoc:end-->
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## 7. Main Artifacts (Repository Artifacts)
|
|
172
|
+
|
|
173
|
+
### 7.1 Directory Structure
|
|
174
|
+
|
|
175
|
+
<!--@embedoc:model_data model="artifact" format="directory-tree"-->
|
|
176
|
+
```
|
|
177
|
+
design/ # TypeScript (source of truth) = upstream SSOT (requirement/design models)
|
|
178
|
+
├── _models/ # Model definitions (schemas, lint rules, exporters)
|
|
179
|
+
├── requirements.ts # Requirement definitions
|
|
180
|
+
├── usecases.ts # Use case and actor definitions
|
|
181
|
+
├── architecture.ts # Logical architecture (C4 System/Container)
|
|
182
|
+
├── concept-model.ts # Concept model (Entity/Relation)
|
|
183
|
+
├── glossary.ts # Glossary
|
|
184
|
+
├── artifacts.ts # Artifact and directory structure definitions
|
|
185
|
+
└── cli-commands.ts # CLI command specifications
|
|
186
|
+
|
|
187
|
+
docs/ # Human-readable documents (auto-updated via embedoc)
|
|
188
|
+
├── framework_requirements_spec.md # Framework requirements specification (sections auto-updated via embedoc)
|
|
189
|
+
├── model-design.md # Model design guide
|
|
190
|
+
├── model-guide.md # Model definition guide
|
|
191
|
+
├── model_entity_catalog.md # Model and entity catalog
|
|
192
|
+
└── framework_evaluation.md # Framework evaluation
|
|
193
|
+
|
|
194
|
+
specs/ # Machine-readable artifacts (JSON Schema for consistency checking)
|
|
195
|
+
├── schemas/ # JSON Schema
|
|
196
|
+
│ └── entities/ # Entity JSON Schema (E-001.json, etc.)
|
|
197
|
+
└── index.json # Aggregated data (reference graph for all models)
|
|
198
|
+
|
|
199
|
+
src/ # Application implementation code (not managed by speckeeper)
|
|
200
|
+
```
|
|
201
|
+
<!--@embedoc:end-->
|
|
202
|
+
|
|
203
|
+
> **Note**: See constraint requirement CR-003. speckeeper does not generate implementation code.
|
|
204
|
+
|
|
205
|
+
### 7.2 Artifact Classification
|
|
206
|
+
|
|
207
|
+
<!--@embedoc:model_data model="artifact" format="table"-->
|
|
208
|
+
| Category | Location | Purpose | Drift target |
|
|
209
|
+
| --- | --- | --- | --- |
|
|
210
|
+
| **SSOT** | `design/` | TypeScript models (source of truth) = requirement/design definitions | - |
|
|
211
|
+
| **Human-readable artifacts** | `docs/` | Markdown/Mermaid (for review) | Yes |
|
|
212
|
+
| **Machine-readable artifacts** | `specs/` | JSON/JSON Schema for consistency checking | Yes |
|
|
213
|
+
| **Implementation code** | `src/` | Application implementation (not managed by speckeeper) | - |
|
|
214
|
+
<!--@embedoc:end-->
|
|
215
|
+
|
|
216
|
+
> **Note**: speckeeper does not generate implementation code. Implementation code is generated from external SSOT by micro-contracts (API contracts) or ORM (DB connections).
|
|
217
|
+
|
|
218
|
+
### 7.3 CI Definition
|
|
219
|
+
|
|
220
|
+
<!--@embedoc:model_data model="cli-command" format="ci-list"-->
|
|
221
|
+
- Execute the following in GitHub Actions (or equivalent)
|
|
222
|
+
- `lint` (Design consistency)
|
|
223
|
+
- `build` (Generate docs/specs)
|
|
224
|
+
- `drift` (Detect manual edits to artifacts)
|
|
225
|
+
- `check external-ssot` (External SSOT consistency check)
|
|
226
|
+
- `check contract` (Contract consistency, can be omitted when using external SSOT)
|
|
227
|
+
<!--@embedoc:end-->
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## 8. Functional Requirements
|
|
232
|
+
|
|
233
|
+
This chapter defines the **common system functionality** that the speckeeper framework (`src/`) should implement.
|
|
234
|
+
|
|
235
|
+
> **Note**: For specific field definitions and usage examples of individual models (Requirement, Entity, Screen, etc.),
|
|
236
|
+
> see **[Model Definition Examples](model-guide.md)**.
|
|
237
|
+
|
|
238
|
+
<!--@embedoc:model_data model="requirement" format="spec-chapter"-->
|
|
239
|
+
### 8.1 Common Requirements (All Models)
|
|
240
|
+
|
|
241
|
+
Defines common requirements that apply to all models.
|
|
242
|
+
|
|
243
|
+
#### FR-101: ID Management
|
|
244
|
+
|
|
245
|
+
All model elements have a unique `id` and provide ID-based reference and consistency checking
|
|
246
|
+
|
|
247
|
+
- **FR-101-01**: All model elements have a unique id [test]
|
|
248
|
+
- **FR-101-02**: id follows conventions (e.g., REQ-OBS-001, ENT-ORDER, COMP-API) [test]
|
|
249
|
+
- **FR-101-03**: References are expressed by ID and reference integrity checking is provided [test]
|
|
250
|
+
- **FR-101-04**: ID changes detect all reference locations via reference integrity check (lint) [test]
|
|
251
|
+
|
|
252
|
+
**Impact of ID Changes**
|
|
253
|
+
- ID changes detect all reference locations via reference integrity check (lint)
|
|
254
|
+
- **Change Impact Analysis CLI**: `speckeeper impact {ID}` lists the impact scope
|
|
255
|
+
|
|
256
|
+
#### FR-102: Phase Management
|
|
257
|
+
|
|
258
|
+
Set phase (REQ/HLD/LLD/OPS) on models and verify phase gates
|
|
259
|
+
|
|
260
|
+
- **FR-102-01**: Phase can be handled as REQ | HLD | LLD | OPS [test]
|
|
261
|
+
- **FR-102-02**: Can set phase in model definition and verify phase gate [test]
|
|
262
|
+
- **FR-102-03**: TBD is allowed/prohibited at specified phase [test]
|
|
263
|
+
|
|
264
|
+
#### FR-104: Model Definition
|
|
265
|
+
|
|
266
|
+
Define and register project-specific models in TypeScript
|
|
267
|
+
|
|
268
|
+
- **FR-104-01**: Can define models by inheriting from Model base class [test]
|
|
269
|
+
- **FR-104-02**: Can define runtime validation with Zod schema [test]
|
|
270
|
+
- **FR-104-03**: Can define model-specific lint rules [test]
|
|
271
|
+
- **FR-104-04**: Can define model-specific renderers (text output functions) [test]
|
|
272
|
+
- **FR-104-05**: Can define external SSOT consistency checkers (optional) [test]
|
|
273
|
+
- **FR-104-06**: Can register as models: [...] in speckeeper.config.ts [demo]
|
|
274
|
+
- **FR-104-07**: Registered models become targets of lint/build/drift/check [test]
|
|
275
|
+
- **FR-104-08**: Can set modelLevel on models to enable relation constraint verification [test]
|
|
276
|
+
- **FR-104-09**: Can get model level (L0/L1/L2/L3) via Model.level property [test]
|
|
277
|
+
|
|
278
|
+
**Model Definition Components**
|
|
279
|
+
|
|
280
|
+
| Element | Required | Description |
|
|
281
|
+
|---------|----------|-------------|
|
|
282
|
+
| `id` | ✓ | Unique identifier for the model |
|
|
283
|
+
| `name` | ✓ | Model name (for display) |
|
|
284
|
+
| `idPrefix` | ✓ | ID prefix (e.g., `REQ-`, `ENT-`) |
|
|
285
|
+
| `schema` | ✓ | Zod schema |
|
|
286
|
+
| `modelLevel` | | Model level (L0/L1/L2/L3) - Used for relation constraint verification |
|
|
287
|
+
| `lintRules` | | Model-specific lint rules |
|
|
288
|
+
| `renderers` | | Renderers (text output functions) |
|
|
289
|
+
| `externalChecker` | | External SSOT consistency checker |
|
|
290
|
+
|
|
291
|
+
**Defined Models (design/_models/)**
|
|
292
|
+
|
|
293
|
+
The following models are defined in this project:
|
|
294
|
+
|
|
295
|
+
| Model | ID Prefix | Purpose |
|
|
296
|
+
|-------|-----------|---------|
|
|
297
|
+
| Requirement | `REQ-` | Requirement definition |
|
|
298
|
+
| UseCase | `UC-` | Use case |
|
|
299
|
+
| Term | `TERM-` | Term definition |
|
|
300
|
+
| Architecture | `COMP-`/`LAYER-` | Architecture |
|
|
301
|
+
| ConceptModel | `ENT-`/`REL-` | Concept model |
|
|
302
|
+
| Screen | `SCR-` | Screen definition |
|
|
303
|
+
| ProcessFlow | `FLOW-` | Process flow |
|
|
304
|
+
| APIRef | `API-` | API reference (external SSOT) |
|
|
305
|
+
| TableRef | `TBL-` | Table reference (external SSOT) |
|
|
306
|
+
| IaCRef | `IAC-` | IaC reference (external SSOT) |
|
|
307
|
+
| BatchRef | `BATCH-` | Batch reference (external SSOT) |
|
|
308
|
+
|
|
309
|
+
**Runbook model definition example**
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
// Model definition example
|
|
313
|
+
import { z } from 'zod';
|
|
314
|
+
import { Model } from 'speckeeper';
|
|
315
|
+
|
|
316
|
+
const RunbookSchema = z.object({
|
|
317
|
+
id: z.string(),
|
|
318
|
+
title: z.string(),
|
|
319
|
+
severity: z.enum(['critical', 'high', 'medium', 'low']),
|
|
320
|
+
symptoms: z.array(z.string()),
|
|
321
|
+
steps: z.array(z.object({
|
|
322
|
+
order: z.number(),
|
|
323
|
+
action: z.string(),
|
|
324
|
+
verification: z.string().optional(),
|
|
325
|
+
})),
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
class RunbookModel extends Model<typeof RunbookSchema> {
|
|
329
|
+
id = 'runbook';
|
|
330
|
+
name = 'Runbook';
|
|
331
|
+
idPrefix = 'RB';
|
|
332
|
+
schema = RunbookSchema;
|
|
333
|
+
|
|
334
|
+
lintRules = [
|
|
335
|
+
{
|
|
336
|
+
id: 'runbook-has-steps',
|
|
337
|
+
severity: 'error',
|
|
338
|
+
message: 'Runbook must have at least one step',
|
|
339
|
+
check: (spec) => spec.steps.length === 0,
|
|
340
|
+
},
|
|
341
|
+
];
|
|
342
|
+
|
|
343
|
+
renderers = [
|
|
344
|
+
{
|
|
345
|
+
format: 'markdown',
|
|
346
|
+
render: (specs, ctx) => specs.map(s => `# ${s.title}\n${s.symptoms.join('\n')}`).join('\n'),
|
|
347
|
+
},
|
|
348
|
+
];
|
|
349
|
+
}
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
> [Model definition examples](model-guide.md)
|
|
353
|
+
|
|
354
|
+
#### FR-105: Project Initialization
|
|
355
|
+
|
|
356
|
+
Initialize a new speckeeper project with starter templates and basic model definitions
|
|
357
|
+
|
|
358
|
+
- **FR-105-01**: speckeeper init creates design/ directory structure [test]
|
|
359
|
+
- **FR-105-02**: speckeeper init generates speckeeper.config.ts with default settings [test]
|
|
360
|
+
- **FR-105-03**: speckeeper init generates package.json with type: module and dependencies [test]
|
|
361
|
+
- **FR-105-04**: speckeeper init generates tsconfig.json for TypeScript support [test]
|
|
362
|
+
- **FR-105-05**: speckeeper init generates basic model definitions in design/_models/ [test]
|
|
363
|
+
- **FR-105-06**: speckeeper init generates sample specification files [test]
|
|
364
|
+
- **FR-105-07**: Generated project passes speckeeper lint without errors [test]
|
|
365
|
+
- **FR-105-08**: Generated project passes typecheck without errors [test]
|
|
366
|
+
- **FR-105-09**: speckeeper init --force overwrites existing files [test]
|
|
367
|
+
- **FR-105-10**: speckeeper init skips package.json if it already exists (without --force) [test]
|
|
368
|
+
|
|
369
|
+
**Generated Files**
|
|
370
|
+
|
|
371
|
+
| Path | Description |
|
|
372
|
+
|------|-------------|
|
|
373
|
+
| `design/` | Design directory root |
|
|
374
|
+
| `design/_models/` | Model definitions directory |
|
|
375
|
+
| `design/_models/requirement.ts` | Requirement model |
|
|
376
|
+
| `design/_models/usecase.ts` | UseCase and Actor models |
|
|
377
|
+
| `design/_models/entity.ts` | Entity model |
|
|
378
|
+
| `design/_models/component.ts` | Component model |
|
|
379
|
+
| `design/_models/term.ts` | Term model |
|
|
380
|
+
| `design/_models/index.ts` | Model exports |
|
|
381
|
+
| `design/index.ts` | Design entry point |
|
|
382
|
+
| `design/requirements.ts` | Sample requirements |
|
|
383
|
+
| `speckeeper.config.ts` | Configuration file |
|
|
384
|
+
| `package.json` | Package manifest (if not exists) |
|
|
385
|
+
| `tsconfig.json` | TypeScript configuration |
|
|
386
|
+
|
|
387
|
+
**Project initialization examples**
|
|
388
|
+
|
|
389
|
+
```bash
|
|
390
|
+
# Initialize a new project
|
|
391
|
+
npx speckeeper init
|
|
392
|
+
|
|
393
|
+
# Force overwrite existing files
|
|
394
|
+
npx speckeeper init --force
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
### 8.2 External SSOT Reference
|
|
398
|
+
|
|
399
|
+
Can define references to external SSOT (OpenAPI, DDL, IaC, etc.)
|
|
400
|
+
|
|
401
|
+
#### FR-201: External SSOT Path Configuration
|
|
402
|
+
|
|
403
|
+
External SSOT file paths (OpenAPI, DDL, test code, etc.) are configured in speckeeper.config.ts, not in mermaid flowcharts
|
|
404
|
+
|
|
405
|
+
- **FR-201-01**: External SSOT file paths are defined in speckeeper.config.ts via ExternalSsotPaths [test]
|
|
406
|
+
- **FR-201-02**: Mermaid flowchart is scaffold-only and does not contain runtime configuration such as file paths [review]
|
|
407
|
+
|
|
408
|
+
### 8.3 Generation (build)
|
|
409
|
+
|
|
410
|
+
Generate "human-readable artifacts (docs/)" and "machine-readable artifacts (specs/)" from TS models
|
|
411
|
+
|
|
412
|
+
#### FR-301: Rendering Feature for External Programs
|
|
413
|
+
|
|
414
|
+
Models provide text rendering functionality callable from external programs
|
|
415
|
+
|
|
416
|
+
- **FR-301-01**: Can define rendering functions in Model class via renderers property [test]
|
|
417
|
+
- **FR-301-02**: Rendering can be invoked via common interface from external programs [test]
|
|
418
|
+
- **FR-301-03**: Rendering results switch internally based on model class [test]
|
|
419
|
+
- **FR-301-04**: Output format can be specified via format parameter [test]
|
|
420
|
+
- **FR-301-05**: Regeneration produces identical content (idempotency) [test]
|
|
421
|
+
|
|
422
|
+
**Design Policy**
|
|
423
|
+
|
|
424
|
+
- speckeeper itself does not directly generate documents (docs/)
|
|
425
|
+
- External programs (template engines, etc.) invoke model rendering functionality to generate documents
|
|
426
|
+
- Model-specific rendering logic is consolidated in `design/_models/`
|
|
427
|
+
- Common rendering interface (`Renderer`) is provided
|
|
428
|
+
|
|
429
|
+
**Rendering Interface**
|
|
430
|
+
|
|
431
|
+
| Method | Description |
|
|
432
|
+
|--------|-------------|
|
|
433
|
+
| `model.render(format, specs, ctx)` | Render in specified format |
|
|
434
|
+
| `model.hasRenderer(format)` | Check if format is available |
|
|
435
|
+
| `model.getAvailableFormats()` | List available formats |
|
|
436
|
+
|
|
437
|
+
**RenderContext**
|
|
438
|
+
|
|
439
|
+
| Property | Description |
|
|
440
|
+
|----------|-------------|
|
|
441
|
+
| `params` | Parameters (filter conditions, etc.) |
|
|
442
|
+
| `markdown.table()` | Markdown table generation helper |
|
|
443
|
+
|
|
444
|
+
**Rendering functionality definition and invocation example**
|
|
445
|
+
|
|
446
|
+
```typescript
|
|
447
|
+
// Model renderers definition example
|
|
448
|
+
protected renderers: Renderer<MySpec>[] = [
|
|
449
|
+
{
|
|
450
|
+
format: 'table',
|
|
451
|
+
render: (specs, ctx) => ctx.markdown.table(
|
|
452
|
+
['ID', 'Name'],
|
|
453
|
+
specs.map(s => [s.id, s.name])
|
|
454
|
+
),
|
|
455
|
+
},
|
|
456
|
+
{
|
|
457
|
+
format: 'list',
|
|
458
|
+
render: (specs, _ctx) => specs.map(s => `- ${s.id}: ${s.name}`).join('\n'),
|
|
459
|
+
},
|
|
460
|
+
];
|
|
461
|
+
|
|
462
|
+
// Invocation example from external program
|
|
463
|
+
import { myModel } from '../design/_models/my-model.ts';
|
|
464
|
+
|
|
465
|
+
const table = myModel.render('table', specs, ctx);
|
|
466
|
+
const list = myModel.render('list', specs, ctx);
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
#### FR-302: Machine-readable Artifacts (specs/)
|
|
470
|
+
|
|
471
|
+
Generate JSON Schema and requirement definitions from concept model entities
|
|
472
|
+
|
|
473
|
+
- **FR-302-01**: Entity attributes are mapped to JSON Schema properties [test]
|
|
474
|
+
- **FR-302-02**: Can output reference resolution graph (specs/index.json) [test]
|
|
475
|
+
|
|
476
|
+
| Output | Content |
|
|
477
|
+
|--------|---------|
|
|
478
|
+
| `specs/schemas/entities/` | JSON Schema (concept Entity common vocabulary) |
|
|
479
|
+
| `specs/index.json` | Reference resolution graph (ID list and reference relations for all models) |
|
|
480
|
+
|
|
481
|
+
> **Note**: speckeeper **does not generate implementation code**.
|
|
482
|
+
> Implementation code is generated by external tools from external SSOT:
|
|
483
|
+
> - API contract → External tools (generated from OpenAPI)
|
|
484
|
+
> - DB connection → ORM/DDL tools (generated from DDL/Prisma)
|
|
485
|
+
|
|
486
|
+
### 8.4 Lint/Validation
|
|
487
|
+
|
|
488
|
+
Provides lint functionality to verify model consistency
|
|
489
|
+
|
|
490
|
+
#### FR-401: Common Lint Items
|
|
491
|
+
|
|
492
|
+
Verify common lint items that apply to all models
|
|
493
|
+
|
|
494
|
+
- **FR-401-01**: Verify IDs are not duplicated within the same type [test]
|
|
495
|
+
- **FR-401-02**: Verify IDs follow conventions [test]
|
|
496
|
+
- **FR-401-03**: Verify referenced targets exist [test]
|
|
497
|
+
- **FR-401-04**: Verify no circular references exist [test]
|
|
498
|
+
- **FR-401-05**: Verify no TBDs remain at specified phase [test]
|
|
499
|
+
- **FR-401-06**: Detect orphan elements (entities without relations, etc.) [test]
|
|
500
|
+
|
|
501
|
+
| Check Item | Description |
|
|
502
|
+
|------------|-------------|
|
|
503
|
+
| ID Uniqueness | IDs are not duplicated within the same type |
|
|
504
|
+
| ID Format | IDs follow conventions |
|
|
505
|
+
| Reference Integrity | Referenced targets exist |
|
|
506
|
+
| Circular Reference | No circular references |
|
|
507
|
+
| Phase Gate | No TBDs remain at specified phase |
|
|
508
|
+
| Orphan Elements | Detect entities without relations, etc. |
|
|
509
|
+
|
|
510
|
+
#### FR-402: Custom Lint Rules
|
|
511
|
+
|
|
512
|
+
Each model can define lintRules to verify model-specific constraints
|
|
513
|
+
|
|
514
|
+
- **FR-402-01**: Can set lintRules in Model definition [test]
|
|
515
|
+
- **FR-402-02**: Can set severity (error/warning/info) [test]
|
|
516
|
+
- **FR-402-03**: Lint results include rule ID, message, and target ID [test]
|
|
517
|
+
|
|
518
|
+
**Custom lint rule definition example**
|
|
519
|
+
|
|
520
|
+
```typescript
|
|
521
|
+
lintRules: LintRule<T>[] = [
|
|
522
|
+
{
|
|
523
|
+
id: 'rule-id',
|
|
524
|
+
severity: 'error' | 'warning' | 'info',
|
|
525
|
+
message: 'Error message',
|
|
526
|
+
check: (spec) => /* true if problem exists */,
|
|
527
|
+
},
|
|
528
|
+
];
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
### 8.5 Drift Check
|
|
532
|
+
|
|
533
|
+
Detect if artifacts (docs/, specs/) have been manually edited
|
|
534
|
+
|
|
535
|
+
- **FR-500-01**: After build execution, detect differences between generated docs//specs/ and committed files [test]
|
|
536
|
+
- **FR-500-02**: Fail CI when differences are found [test]
|
|
537
|
+
- **FR-500-03**: Output message prompting to "regenerate and commit" [test]
|
|
538
|
+
- **FR-500-04**: Manual editing of artifacts is prohibited (detected by drift) [review]
|
|
539
|
+
|
|
540
|
+
### 8.6 External SSOT Consistency Check
|
|
541
|
+
|
|
542
|
+
Verify consistency between TS models (external SSOT references) and external SSOT (OpenAPI, DDL, IaC, etc.)
|
|
543
|
+
|
|
544
|
+
#### FR-601: Three Categories of Consistency Check
|
|
545
|
+
|
|
546
|
+
All external SSOT consistency checks are uniformly composed of existence, type, and constraint categories
|
|
547
|
+
|
|
548
|
+
- **FR-601-01**: Existence: Referenced items exist in external artifacts [test]
|
|
549
|
+
- **FR-601-02**: Type: Expected type/class/category matches [test]
|
|
550
|
+
- **FR-601-03**: Constraints: Non-functional/guardrails are satisfied [test]
|
|
551
|
+
|
|
552
|
+
| Category | Content | Examples |
|
|
553
|
+
|----------|---------|----------|
|
|
554
|
+
| **Existence** | Referenced items exist in external artifacts | operationId existence, table existence |
|
|
555
|
+
| **Type** | Expected type/class/category matches | resourceType match, columnType match |
|
|
556
|
+
| **Constraints** | Non-functional/guardrails are satisfied | Encryption required, PII classification |
|
|
557
|
+
|
|
558
|
+
#### FR-602: Check Command
|
|
559
|
+
|
|
560
|
+
Provide CLI command to execute external SSOT consistency check
|
|
561
|
+
|
|
562
|
+
- **FR-602-01**: speckeeper check runs external SSOT consistency check for all models [test]
|
|
563
|
+
- **FR-602-02**: speckeeper check --model <model-name> checks only specific model [test]
|
|
564
|
+
- **FR-602-03**: Model name is the model ID defined in design/_models/ [review]
|
|
565
|
+
- **FR-602-04**: Only models with externalChecker are targeted [test]
|
|
566
|
+
|
|
567
|
+
**Check command examples**
|
|
568
|
+
|
|
569
|
+
```bash
|
|
570
|
+
# External SSOT consistency check for all models
|
|
571
|
+
speckeeper check
|
|
572
|
+
|
|
573
|
+
# Check specific model only
|
|
574
|
+
speckeeper check --model api-ref # APIRef consistency only
|
|
575
|
+
speckeeper check --model table-ref # TableRef consistency only
|
|
576
|
+
speckeeper check --model iac-ref # IaCRef consistency only
|
|
577
|
+
speckeeper check --model batch-ref # BatchRef consistency only
|
|
578
|
+
|
|
579
|
+
# Specify multiple models
|
|
580
|
+
speckeeper check --model api-ref --model table-ref
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
#### FR-603: External Checker
|
|
584
|
+
|
|
585
|
+
Each model can define externalChecker to implement consistency check with external SSOT
|
|
586
|
+
|
|
587
|
+
- **FR-603-01**: Can set externalChecker in Model definition [test]
|
|
588
|
+
- **FR-603-02**: externalChecker includes target file reading and check logic [test]
|
|
589
|
+
- **FR-603-03**: Check results include success, errors, warnings [test]
|
|
590
|
+
- **FR-603-04**: speckeeper check command auto-detects and runs models with externalChecker [test]
|
|
591
|
+
|
|
592
|
+
**External Checker Structure**
|
|
593
|
+
|
|
594
|
+
| Property | Description |
|
|
595
|
+
|----------|-------------|
|
|
596
|
+
| `sourcePath` | Function that returns the target file path |
|
|
597
|
+
| `check` | Check logic body |
|
|
598
|
+
|
|
599
|
+
**External checker definition example**
|
|
600
|
+
|
|
601
|
+
```typescript
|
|
602
|
+
// design/_models/api-ref.ts
|
|
603
|
+
externalChecker: ExternalChecker<APIRef> = {
|
|
604
|
+
sourcePath: (spec) => spec.source.path,
|
|
605
|
+
check: (spec, openApiDoc) => {
|
|
606
|
+
const errors: string[] = [];
|
|
607
|
+
const warnings: string[] = [];
|
|
608
|
+
|
|
609
|
+
// operationId existence check
|
|
610
|
+
if (!findOperationId(openApiDoc, spec.operationId)) {
|
|
611
|
+
errors.push(`operationId '${spec.operationId}' not found`);
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
return {
|
|
615
|
+
success: errors.length === 0,
|
|
616
|
+
errors,
|
|
617
|
+
warnings,
|
|
618
|
+
};
|
|
619
|
+
},
|
|
620
|
+
};
|
|
621
|
+
```
|
|
622
|
+
|
|
623
|
+
#### FR-604: Coverage Verification
|
|
624
|
+
|
|
625
|
+
Use Model class coverageChecker to verify cross-model coverage
|
|
626
|
+
|
|
627
|
+
- **FR-604-01**: Execute coverage verification with speckeeper check --coverage [test]
|
|
628
|
+
- **FR-604-02**: Define coverageChecker interface in Model class [test]
|
|
629
|
+
- **FR-604-03**: Auto-detect and execute models with coverageChecker [test]
|
|
630
|
+
- **FR-604-04**: Calculate and display coverage rate (%) [test]
|
|
631
|
+
- **FR-604-05**: List uncovered items [test]
|
|
632
|
+
|
|
633
|
+
**coverageChecker Design**
|
|
634
|
+
|
|
635
|
+
| Property | Description |
|
|
636
|
+
|----------|-------------|
|
|
637
|
+
| `targetModel` | Target model ID for coverage ('requirement', etc.) |
|
|
638
|
+
| `description` | Coverage check description |
|
|
639
|
+
| `check` | Coverage check function (receives registry of all models) |
|
|
640
|
+
|
|
641
|
+
**Example: TestRef model coverageChecker**
|
|
642
|
+
|
|
643
|
+
Verifies that acceptanceCriteria with `verificationMethod: 'test'` specific to design/
|
|
644
|
+
are covered by TestRef.testCasePatterns.
|
|
645
|
+
Coverage logic is defined in each project's design/.
|
|
646
|
+
|
|
647
|
+
**Coverage verification command execution example**
|
|
648
|
+
|
|
649
|
+
```bash
|
|
650
|
+
# Coverage verification
|
|
651
|
+
speckeeper check --coverage
|
|
652
|
+
|
|
653
|
+
# Output example
|
|
654
|
+
Test Coverage Report
|
|
655
|
+
─────────────────────────────────────
|
|
656
|
+
Total testable criteria: 70
|
|
657
|
+
Covered by TestRef: 70
|
|
658
|
+
Not covered: 0
|
|
659
|
+
|
|
660
|
+
Coverage: 100%
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
#### FR-605: Model-Integrated Check Architecture
|
|
664
|
+
|
|
665
|
+
External SSOT and test verification logic is integrated into _models/ definitions, eliminating the separate _checkers/ directory
|
|
666
|
+
|
|
667
|
+
- **FR-605-01**: Scaffold does not generate _checkers/ directory [test]
|
|
668
|
+
- **FR-605-02**: Verification logic is included in _models/ model definitions [test]
|
|
669
|
+
- **FR-605-03**: speckeeper check external-ssot uses verification logic from _models/ model definitions only [test]
|
|
670
|
+
- **FR-605-04**: speckeeper check external-ssot does not reference _checkers/ directory [test]
|
|
671
|
+
- **FR-605-05**: Checker template functions (src/scaffold/templates/checkers/) are removed; checker logic moves to core DSL (src/core/dsl/) [test]
|
|
672
|
+
|
|
673
|
+
Implement actual validation logic for externalOpenAPIChecker and externalSqlSchemaChecker, replacing stubs with real file parsing and verification
|
|
674
|
+
|
|
675
|
+
#### FR-1001: OpenAPI YAML/JSON Parsing
|
|
676
|
+
|
|
677
|
+
externalOpenAPIChecker MUST parse YAML and JSON format OpenAPI files
|
|
678
|
+
|
|
679
|
+
- **FR-1001-01**: YAML format OpenAPI files are parsed successfully [test]
|
|
680
|
+
- **FR-1001-02**: JSON format OpenAPI files are parsed successfully [test]
|
|
681
|
+
|
|
682
|
+
#### FR-1002: OpenAPI Spec ID Verification
|
|
683
|
+
|
|
684
|
+
externalOpenAPIChecker MUST verify spec IDs via operationId, path segments, schema names, and x-spec-id extensions
|
|
685
|
+
|
|
686
|
+
- **FR-1002-01**: Spec ID found via operationId [test]
|
|
687
|
+
- **FR-1002-02**: Spec ID found via exact path segment match [test]
|
|
688
|
+
- **FR-1002-03**: Spec ID found via schema name [test]
|
|
689
|
+
- **FR-1002-04**: Spec ID found via x-spec-id extension [test]
|
|
690
|
+
|
|
691
|
+
#### FR-1003: OpenAPI Missing Spec ID Warning
|
|
692
|
+
|
|
693
|
+
externalOpenAPIChecker MUST report a warning for each spec ID not found in the OpenAPI document
|
|
694
|
+
|
|
695
|
+
- **FR-1003-01**: Warning reported when spec ID is not found [test]
|
|
696
|
+
|
|
697
|
+
#### FR-1004: OpenAPI Method Check
|
|
698
|
+
|
|
699
|
+
externalOpenAPIChecker MAY optionally verify HTTP method exists for matched path (opt-in via config)
|
|
700
|
+
|
|
701
|
+
- **FR-1004-01**: Method check is opt-in via mapper config [test]
|
|
702
|
+
- **FR-1004-02**: Warning reported for method mismatch [test]
|
|
703
|
+
|
|
704
|
+
#### FR-1005: OpenAPI Parameter/Response Check
|
|
705
|
+
|
|
706
|
+
externalOpenAPIChecker MAY optionally verify parameter names, response property names and types (opt-in via config)
|
|
707
|
+
|
|
708
|
+
- **FR-1005-01**: Parameter check is opt-in via mapper config [test]
|
|
709
|
+
- **FR-1005-02**: Response property check is opt-in via mapper config [test]
|
|
710
|
+
- **FR-1005-03**: Type containment is used for type comparison [test]
|
|
711
|
+
|
|
712
|
+
#### FR-1006: OpenAPI Mismatch Warnings
|
|
713
|
+
|
|
714
|
+
externalOpenAPIChecker MUST report warnings for method/parameter/property/type mismatches
|
|
715
|
+
|
|
716
|
+
- **FR-1006-01**: Warning for missing/wrong HTTP method [test]
|
|
717
|
+
- **FR-1006-02**: Warning for missing request parameter [test]
|
|
718
|
+
- **FR-1006-03**: Warning for missing response property [test]
|
|
719
|
+
- **FR-1006-04**: Warning for type mismatch [test]
|
|
720
|
+
|
|
721
|
+
#### FR-1007: OpenAPI File Not Found Error
|
|
722
|
+
|
|
723
|
+
externalOpenAPIChecker MUST report an error when the OpenAPI file does not exist
|
|
724
|
+
|
|
725
|
+
- **FR-1007-01**: Error reported with missing file path [test]
|
|
726
|
+
|
|
727
|
+
#### FR-1008: OpenAPI Parse Failure Error
|
|
728
|
+
|
|
729
|
+
externalOpenAPIChecker MUST report an error when the OpenAPI file cannot be parsed
|
|
730
|
+
|
|
731
|
+
- **FR-1008-01**: Error reported for invalid YAML [test]
|
|
732
|
+
- **FR-1008-02**: Error reported for empty file [test]
|
|
733
|
+
|
|
734
|
+
#### FR-1009: SQL DDL Parsing
|
|
735
|
+
|
|
736
|
+
externalSqlSchemaChecker MUST parse SQL DDL files and extract table definitions
|
|
737
|
+
|
|
738
|
+
- **FR-1009-01**: DDL parsed with node-sql-parser [test]
|
|
739
|
+
- **FR-1009-02**: Table names, column names, and column types extracted [test]
|
|
740
|
+
|
|
741
|
+
#### FR-1010: SQL Table Existence Check
|
|
742
|
+
|
|
743
|
+
externalSqlSchemaChecker MUST verify spec-referenced table names exist in parsed DDL
|
|
744
|
+
|
|
745
|
+
- **FR-1010-01**: Warning when referenced table is missing [test]
|
|
746
|
+
|
|
747
|
+
#### FR-1011: SQL Column Existence Check
|
|
748
|
+
|
|
749
|
+
externalSqlSchemaChecker MUST verify spec-referenced columns exist in DDL table
|
|
750
|
+
|
|
751
|
+
- **FR-1011-01**: Warning when referenced column is missing [test]
|
|
752
|
+
- **FR-1011-02**: Column check skipped when table is missing [test]
|
|
753
|
+
|
|
754
|
+
#### FR-1012: SQL Type Consistency Check
|
|
755
|
+
|
|
756
|
+
externalSqlSchemaChecker MAY optionally verify column type containment (opt-in via checkTypes)
|
|
757
|
+
|
|
758
|
+
- **FR-1012-01**: Type check is opt-in via checkTypes config [test]
|
|
759
|
+
- **FR-1012-02**: Wider DDL type accepted (SMALLINT→INT OK) [test]
|
|
760
|
+
- **FR-1012-03**: Narrower DDL type produces warning (INT→SMALLINT NG) [test]
|
|
761
|
+
|
|
762
|
+
#### FR-1013: SQL Checker Warnings
|
|
763
|
+
|
|
764
|
+
externalSqlSchemaChecker MUST report warnings for missing table, column, and type mismatches
|
|
765
|
+
|
|
766
|
+
- **FR-1013-01**: Warning for missing table [test]
|
|
767
|
+
- **FR-1013-02**: Warning for missing column [test]
|
|
768
|
+
- **FR-1013-03**: Warning for type mismatch [test]
|
|
769
|
+
|
|
770
|
+
#### FR-1014: SQL File Not Found Error
|
|
771
|
+
|
|
772
|
+
externalSqlSchemaChecker MUST report an error when the DDL file does not exist
|
|
773
|
+
|
|
774
|
+
- **FR-1014-01**: Error reported with missing file path [test]
|
|
775
|
+
|
|
776
|
+
#### FR-1015: SQL Parse Failure Graceful Degradation
|
|
777
|
+
|
|
778
|
+
externalSqlSchemaChecker MUST handle DDL parse failures gracefully with regex fallback
|
|
779
|
+
|
|
780
|
+
- **FR-1015-01**: Regex fallback used when parser fails [test]
|
|
781
|
+
- **FR-1015-02**: Warning emitted for parse fallback [test]
|
|
782
|
+
|
|
783
|
+
#### FR-1016: Checker Pattern Consistency
|
|
784
|
+
|
|
785
|
+
Both checkers follow the testChecker pattern: file existence check → content parsing → spec ID verification
|
|
786
|
+
|
|
787
|
+
- **FR-1016-01**: OpenAPI checker follows file→parse→verify pattern [test]
|
|
788
|
+
- **FR-1016-02**: SQL checker follows file→parse→verify pattern [test]
|
|
789
|
+
|
|
790
|
+
#### FR-1017: Source Path Fallback
|
|
791
|
+
|
|
792
|
+
Both checkers use sourcePath from checker config, falling back to hardcoded defaults
|
|
793
|
+
|
|
794
|
+
- **FR-1017-01**: Config sourcePath used when provided [test]
|
|
795
|
+
- **FR-1017-02**: Default path used when no config [test]
|
|
796
|
+
|
|
797
|
+
#### FR-1018: Minimal New Dependencies
|
|
798
|
+
|
|
799
|
+
Only node-sql-parser added as new runtime dependency (>100K weekly downloads)
|
|
800
|
+
|
|
801
|
+
- **FR-1018-01**: Only node-sql-parser added as new dependency [review]
|
|
802
|
+
|
|
803
|
+
#### FR-1019: Checker Documentation Accuracy
|
|
804
|
+
|
|
805
|
+
README and scaffold-mermaid-spec.md accurately describe all three built-in checkers as fully implemented
|
|
806
|
+
|
|
807
|
+
- **FR-1019-01**: README checker table describes validation levels [review]
|
|
808
|
+
- **FR-1019-02**: scaffold-mermaid-spec.md Section 7 describes validation levels [review]
|
|
809
|
+
|
|
810
|
+
### 8.7 Change Impact Analysis
|
|
811
|
+
|
|
812
|
+
Analyze and list impact scope when IDs change
|
|
813
|
+
|
|
814
|
+
#### FR-701: Inter-model Relations
|
|
815
|
+
|
|
816
|
+
Define relations between models to enable impact scope tracking
|
|
817
|
+
|
|
818
|
+
- **FR-701-01**: Can define relations via relations property in model definition [test]
|
|
819
|
+
- **FR-701-02**: Provides standard relation types [review]
|
|
820
|
+
- **FR-701-03**: Relations are used as input for impact analysis [test]
|
|
821
|
+
- **FR-701-04**: Define source/target model level constraints per relation type [test]
|
|
822
|
+
- **FR-701-05**: Level violations and circular references can be detected by lint [test]
|
|
823
|
+
|
|
824
|
+
**Model Level Definition**
|
|
825
|
+
|
|
826
|
+
Models are classified into the following levels by abstraction (L0 is most abstract):
|
|
827
|
+
|
|
828
|
+
| Level | Perspective | Model Examples | Description |
|
|
829
|
+
|-------|-------------|----------------|-------------|
|
|
830
|
+
| L0 (Business+Domain) | Why / Problem space | UseCase, Actor, Term, Goal | Outcomes/values to achieve, business flows, terminology, business rules |
|
|
831
|
+
| L1 (Requirements) | What | Requirement, Constraint | Functional/non-functional requirements, constraints, acceptance criteria |
|
|
832
|
+
| L2 (Design) | How (Policy) | Component, Entity, ProcessFlow | Architecture, structure, domain model, policies |
|
|
833
|
+
| L3 (Detailed Design/Implementation) | How to build | Screen, APIRef, TableRef, IaCRef | Concrete screen/API/DB definitions, external SSOT references |
|
|
834
|
+
|
|
835
|
+
```
|
|
836
|
+
Abstract ◄───────────────────────────────────────────────────► Concrete
|
|
837
|
+
L0 L1 L2 L3
|
|
838
|
+
Business+Domain → Requirements → Design (Policy) → Detailed Design/Implementation
|
|
839
|
+
(Why) (What) (How) (How to build)
|
|
840
|
+
```
|
|
841
|
+
|
|
842
|
+
**Relation Types and Level Constraints**
|
|
843
|
+
|
|
844
|
+
| Type | Source(A) | Target(B) | Level Constraint | Description |
|
|
845
|
+
|------|-----------|-----------|------------------|-------------|
|
|
846
|
+
| `implements` | L2,L3 | L1 | A.level > B.level | Design/implementation implements requirements |
|
|
847
|
+
| `satisfies` | L1,L2,L3 | L0,L1 | A.level >= B.level | Design satisfies business/requirements |
|
|
848
|
+
| `refines` | L1,L2,L3 | L0,L1 | A.level > B.level | Requirements refine business, design refines requirements |
|
|
849
|
+
| `verifies` | any | L0,L1 | - | Tests verify business/requirements |
|
|
850
|
+
| `dependsOn` | any | any | A.level >= B.level | Same level or concrete→abstract |
|
|
851
|
+
| `uses` | any | any | - | Runtime reference (no level constraint) |
|
|
852
|
+
| `includes` | any | any | same level | Inclusion within same level |
|
|
853
|
+
| `traces` | any | any | - | Bidirectional tracking (no level constraint) |
|
|
854
|
+
| `relatedTo` | any | any | - | General relation (no level constraint) |
|
|
855
|
+
|
|
856
|
+
**Prohibited Relation Patterns (Lint Error)**
|
|
857
|
+
|
|
858
|
+
| Pattern | Reason | Example |
|
|
859
|
+
|---------|--------|---------|
|
|
860
|
+
| Abstract→Concrete `implements` | Wrong direction | Requirement → Screen ❌ |
|
|
861
|
+
| Abstract→Concrete `satisfies` | Wrong direction | UseCase → Component ❌ |
|
|
862
|
+
| Abstract→Concrete `refines` | Wrong direction | UseCase → Screen ❌ |
|
|
863
|
+
| Circular reference | Infinite loop | A→B→C→A ❌ |
|
|
864
|
+
| Self-reference | Meaningless | A→A ❌ |
|
|
865
|
+
|
|
866
|
+
**Circular Reference Detection Rules**
|
|
867
|
+
|
|
868
|
+
Circular references are detected under the following conditions:
|
|
869
|
+
|
|
870
|
+
1. **Direct cycle**: A implements B, B implements A
|
|
871
|
+
2. **Indirect cycle**: A→B→C→A (any combination of relation types)
|
|
872
|
+
3. **Level violation cycle**: Concrete→Abstract→Concrete (level returns)
|
|
873
|
+
|
|
874
|
+
```
|
|
875
|
+
Cycle patterns to detect:
|
|
876
|
+
┌─────────────────────────────────────────────────┐
|
|
877
|
+
│ Allowed: L0 ← L1 ← L2 ← L3 (one direction only)│
|
|
878
|
+
│ │
|
|
879
|
+
│ Prohibited: L0 ← L1 ← L2 → L1 (level returns) │
|
|
880
|
+
│ └───────────────────┘ │
|
|
881
|
+
│ cycle │
|
|
882
|
+
└─────────────────────────────────────────────────┘
|
|
883
|
+
```
|
|
884
|
+
|
|
885
|
+
**Impact Propagation Direction**
|
|
886
|
+
|
|
887
|
+
| Type | Direction | Description |
|
|
888
|
+
|------|-----------|-------------|
|
|
889
|
+
| `implements` | A change→Check B | Verify requirement satisfaction on implementation change |
|
|
890
|
+
| `satisfies` | B change→Update A | Update design on business/requirement change |
|
|
891
|
+
| `refines` | B change→Update A | Update detail on parent change |
|
|
892
|
+
| `verifies` | B change→Update A | Update tests on business/requirement change |
|
|
893
|
+
| `dependsOn` | B change→A impacted | Dependent impacted by dependency change |
|
|
894
|
+
| `uses` | B change→A impacted | User impacted by used change |
|
|
895
|
+
| `includes` | B change→A impacted | Whole impacted by part change |
|
|
896
|
+
| `traces` | Bidirectional | Detect tracked element changes |
|
|
897
|
+
| `relatedTo` | Bidirectional | Detect related element changes |
|
|
898
|
+
|
|
899
|
+
**Typical Relations Between Levels**
|
|
900
|
+
|
|
901
|
+
```
|
|
902
|
+
L0 (Business+Domain) L1 (Requirements) L2 (Design) L3 (Detailed Design/Impl)
|
|
903
|
+
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
904
|
+
│ UseCase │◄────────────│Requirement│◄───────│Component │◄───────│ Screen │
|
|
905
|
+
│ │ refines │ │implements │dependsOn│ │
|
|
906
|
+
└──────────┘ └──────────┘ └──────────┘ └──────────┘
|
|
907
|
+
▲ ▲ ▲ │
|
|
908
|
+
│traces │satisfies │uses │uses
|
|
909
|
+
│ │ │ ▼
|
|
910
|
+
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
911
|
+
│ Actor │ │Constraint │ │ Entity │ │ APIRef │
|
|
912
|
+
│ Term │ │ │ │ProcessFlow│ │ TableRef │
|
|
913
|
+
│ Goal │ │ │ │ │ │ │
|
|
914
|
+
└──────────┘ └──────────┘ └──────────┘ └──────────┘
|
|
915
|
+
Why / What How How to
|
|
916
|
+
Problem space (Policy) build
|
|
917
|
+
```
|
|
918
|
+
|
|
919
|
+
> [Relation implementation](../src/core/relation.ts)
|
|
920
|
+
|
|
921
|
+
### 8.8 Artifact Export
|
|
922
|
+
|
|
923
|
+
Output aggregated JSON for machine processing
|
|
924
|
+
|
|
925
|
+
- **FR-800-01**: Can output aggregated JSON for machine processing (specs/index.json) [test]
|
|
926
|
+
- **FR-800-02**: Can be used for future tool integration (dashboards, requirement lists, progress visualization) [review]
|
|
927
|
+
|
|
928
|
+
<!--@embedoc:end-->
|
|
929
|
+
|
|
930
|
+
---
|
|
931
|
+
|
|
932
|
+
## 9. Non-Functional Requirements
|
|
933
|
+
|
|
934
|
+
<!--@embedoc:model_data model="requirement" format="nfr-chapter"-->
|
|
935
|
+
### 9.1 Execution Time
|
|
936
|
+
|
|
937
|
+
**NFR-001: Command Execution Time**
|
|
938
|
+
|
|
939
|
+
lint/build/drift within 1 minute for typical requirement scale (~500 items), check within 2 minutes (depends on file count)
|
|
940
|
+
|
|
941
|
+
- lint/build/drift within 60 seconds for 500 requirements scale
|
|
942
|
+
- check within 120 seconds for 1000 files scale
|
|
943
|
+
- build within 5 seconds for 1000 requirements, 100 entities, 50 screens
|
|
944
|
+
|
|
945
|
+
### 9.2 Portability
|
|
946
|
+
|
|
947
|
+
**NFR-002: Node.js Compatibility**
|
|
948
|
+
|
|
949
|
+
Works on Node.js (LTS)
|
|
950
|
+
|
|
951
|
+
- Verified on Node.js 18 LTS
|
|
952
|
+
- Verified on Node.js 20 LTS
|
|
953
|
+
- Verified on Node.js 22 LTS
|
|
954
|
+
|
|
955
|
+
**NFR-003: Multi-OS Support**
|
|
956
|
+
|
|
957
|
+
Avoid OS dependencies and work on Linux/macOS/Windows
|
|
958
|
+
|
|
959
|
+
- Verified on Linux (Ubuntu)
|
|
960
|
+
- Verified on macOS
|
|
961
|
+
- Verified on Windows (PowerShell)
|
|
962
|
+
- Eliminate OS-dependent code such as path separators
|
|
963
|
+
|
|
964
|
+
### 9.3 Modifiability (Extensibility)
|
|
965
|
+
|
|
966
|
+
**NFR-004: User-defined Models**
|
|
967
|
+
|
|
968
|
+
Users can define custom models by inheriting from Model base class
|
|
969
|
+
|
|
970
|
+
- Can define new models by inheriting from Model base class
|
|
971
|
+
- Can define model-specific schema, lint rules, and renderers
|
|
972
|
+
- Models registered in speckeeper.config.ts become targets of lint/build/check
|
|
973
|
+
|
|
974
|
+
**NFR-005: Input Format Diversity**
|
|
975
|
+
|
|
976
|
+
Allow YAML/JSON input to lower participation barriers for non-developers
|
|
977
|
+
|
|
978
|
+
- Support TypeScript DSL input
|
|
979
|
+
- Support YAML format input
|
|
980
|
+
- Support JSON format input
|
|
981
|
+
|
|
982
|
+
**NFR-006: Rule Extensibility**
|
|
983
|
+
|
|
984
|
+
Allow adding lint and check rules via plugin mechanism
|
|
985
|
+
|
|
986
|
+
- Custom lint rules can be added
|
|
987
|
+
- Custom check rules (external SSOT verification) can be added
|
|
988
|
+
- Rules are defined under Model._models/
|
|
989
|
+
|
|
990
|
+
### 9.4 Transparency
|
|
991
|
+
|
|
992
|
+
**NFR-007: Error Message Clarity**
|
|
993
|
+
|
|
994
|
+
Output errors showing requirement ID, file, and field name, providing messages that clearly show "why it failed"
|
|
995
|
+
|
|
996
|
+
- Errors include requirement ID/specification ID
|
|
997
|
+
- Errors include file path and line number (when possible)
|
|
998
|
+
- Errors include problematic field name
|
|
999
|
+
- Provide hints for fixes
|
|
1000
|
+
|
|
1001
|
+
### 9.5 Compatibility
|
|
1002
|
+
|
|
1003
|
+
**NFR-008: TypeScript Compatibility**
|
|
1004
|
+
|
|
1005
|
+
Type checking passes on TypeScript 5.0+
|
|
1006
|
+
|
|
1007
|
+
- Compiles successfully on TypeScript 5.0
|
|
1008
|
+
- No type errors in strict mode
|
|
1009
|
+
|
|
1010
|
+
**NFR-009: ESM Support**
|
|
1011
|
+
|
|
1012
|
+
Provided in ES Modules format
|
|
1013
|
+
|
|
1014
|
+
- Can be imported via import statement
|
|
1015
|
+
- Tree-shaking works
|
|
1016
|
+
|
|
1017
|
+
### 9.6 Deployability
|
|
1018
|
+
|
|
1019
|
+
**NFR-010: npm Distribution**
|
|
1020
|
+
|
|
1021
|
+
Can be distributed as npm package
|
|
1022
|
+
|
|
1023
|
+
- Can publish package via npm publish
|
|
1024
|
+
- Can install via npm install speckeeper
|
|
1025
|
+
|
|
1026
|
+
<!--@embedoc:end-->
|
|
1027
|
+
|
|
1028
|
+
---
|
|
1029
|
+
|
|
1030
|
+
## 10. Security Requirements
|
|
1031
|
+
|
|
1032
|
+
- Secrets embedded in repository are prohibited
|
|
1033
|
+
- External links such as Runbook URLs are allowed, but must not include authentication information
|
|
1034
|
+
- Care must be taken to prevent sensitive information from appearing in CI logs (configure to avoid exposing template contents)
|
|
1035
|
+
|
|
1036
|
+
---
|
|
1037
|
+
|
|
1038
|
+
## 11. Acceptance Criteria
|
|
1039
|
+
|
|
1040
|
+
Refer to `acceptanceCriteria` defined in each requirement (FR-*, NFR-*, CR-*).
|
|
1041
|
+
|
|
1042
|
+
Verification of acceptance criteria is automated with `speckeeper check test --coverage`,
|
|
1043
|
+
which confirms that acceptance criteria with `verificationMethod: test` are covered by `TestRef`.
|
|
1044
|
+
|
|
1045
|
+
```bash
|
|
1046
|
+
# Check acceptance criteria coverage
|
|
1047
|
+
npx speckeeper check test --coverage
|
|
1048
|
+
```
|
|
1049
|
+
|
|
1050
|
+
---
|
|
1051
|
+
|
|
1052
|
+
End of Document
|