speckeeper 0.4.2 → 0.7.0

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 CHANGED
@@ -11,7 +11,7 @@
11
11
  Requirements and design documents often drift from implementation. **speckeeper** treats specifications as **code** — type-safe, version-controlled, and continuously validated against your actual artifacts (tests, OpenAPI, DDL, IaC).
12
12
 
13
13
  ```
14
- Mermaid flowchart ──► speckeeper scaffold ──► design/_models/ & _checkers/
14
+ Mermaid flowchart ──► speckeeper scaffold ──► design/_models/
15
15
  │
16
16
  design/*.ts ─────────────────────────────► Validation & Consistency Checks
17
17
  │
@@ -26,7 +26,7 @@ design/*.ts ──────────────────────
26
26
  - **Design validation** — Lint rules for ID uniqueness, reference integrity, circular dependencies, and phase gates
27
27
  - **External SSOT validation** — Check consistency with test files, and custom checkers for OpenAPI, DDL, etc.
28
28
  - **Traceability** — Track relationships across model levels (L0-L3) with impact analysis
29
- - **Scaffold from Mermaid** — Generate `_models/` and `_checkers/` skeletons from a mermaid flowchart
29
+ - **Scaffold from Mermaid** — Generate `_models/` skeletons from a mermaid flowchart with class-based artifact resolution
30
30
  - **Custom models** — Extend with domain-specific models (Runbooks, Policies, etc.)
31
31
  - **CI-ready** — Built-in lint, drift detection, and coverage checks
32
32
 
@@ -47,33 +47,55 @@ Create a Markdown file (e.g. `requirements.md`) containing a mermaid flowchart t
47
47
 
48
48
  ```mermaid
49
49
  flowchart TB
50
- TERM[Term] <-->|relatedTo| SR[System Requirement]
51
- SR -->|refines| FR[Functional Requirement]
52
- SR -->|refines| NFR[Non-Functional Requirement]
53
- FR -->|refines| UC[Use Case]
54
- FR -->|includes| AT[Acceptance Test]
55
- UC -->|implements| API[API Spec]
56
- AT -->|implements| E2ET[E2E Test]
57
-
58
- classDef speckeeper fill:#2563EB,stroke:#1D4ED8,color:#fff,stroke-width:2px
59
- class TERM,SR,FR,NFR,UC,AT speckeeper
50
+ subgraph L0[Business]
51
+ UC[Use Cases]
52
+ TERM[Glossary]
53
+ end
54
+ subgraph L1[Requirements]
55
+ FR[Functional Requirements]
56
+ NFR[Non-Functional Requirements]
57
+ end
58
+ subgraph External[External Artifacts]
59
+ API[OpenAPI Spec]
60
+ DDL[Database Schema]
61
+ UT[Unit Tests]
62
+ end
63
+
64
+ FR -->|refines| UC
65
+ FR -->|implements| API
66
+ FR -->|verifiedBy| UT
67
+ FR -->|implements| DDL
68
+
69
+ class UC,TERM,FR,NFR speckeeper
70
+ class FR,NFR requirement
71
+ class UC usecase
72
+ class TERM term
73
+ class API openapi
74
+ class DDL sqlschema
75
+ class UT test
60
76
  ```
61
77
 
62
- Nodes marked with `class ... speckeeper` become managed models. Edges define lint rules (reference integrity) and checkers (external validation) automatically.
78
+ Key concepts:
79
+ - `class ... speckeeper` marks nodes as managed by speckeeper
80
+ - Additional `class` lines assign **artifact classes** (determines model name/file and node grouping)
81
+ - External node classes (`openapi`, `sqlschema`, `test`) determine checker bindings
82
+ - `subgraph` determines model level (L0–L3)
83
+ - `implements` edges trigger external SSOT validation
84
+ - `verifiedBy` edges trigger test verification
63
85
 
64
- ### 2. Scaffold models and checkers
86
+ ### 2. Scaffold models
65
87
 
66
88
  ```bash
67
89
  npx speckeeper scaffold --source requirements.md
68
90
  ```
69
91
 
70
92
  This generates:
71
- - `design/_models/` — Model classes with Zod schemas, lint rules, and exporters derived from your flowchart
72
- - `design/*.ts` — Spec data files using `defineSpecs()` for each model
73
- - `design/index.ts` — Entry point that aggregates all spec modules via `mergeSpecs()`
74
- - `design/_checkers/` — External checker skeletons for `implements` edges (e.g. OpenAPI, DDL)
93
+ - `design/_models/` — Model classes with base schema (id, name, description, relations) and core factory imports. Customise after generation.
94
+ - `design/*.ts` — Spec data files using `defineSpecs()`
95
+ - `design/index.ts` — Entry point via `mergeSpecs()`
96
+ - Checker bindings from `implements`/`verifiedBy` edges are added as guidance comments
75
97
 
76
- See [Scaffold Mermaid Specification](./docs/scaffold-mermaid-spec.md) for the full input format and built-in node mappings.
98
+ See [Scaffold Mermaid Specification](./docs/scaffold-mermaid-spec.md) for the full input format.
77
99
 
78
100
  ### 3. Fill in your specifications
79
101
 
@@ -129,8 +151,8 @@ npx speckeeper impact FR-001
129
151
  | `speckeeper lint` | Validate design integrity (ID uniqueness, references, phase gates) |
130
152
  | `speckeeper check` | Verify consistency with external SSOT |
131
153
  | `speckeeper check test --coverage` | Verify test coverage for requirements |
132
- | `speckeeper scaffold` | Generate model/checker skeletons from a mermaid flowchart |
133
- | `speckeeper drift` | Detect manual edits to generated `specs/` files |
154
+ | `speckeeper scaffold` | Generate model skeletons from a mermaid flowchart |
155
+ | `speckeeper drift` | Detect manual edits to generated `docs/` files |
134
156
  | `speckeeper impact <id>` | Analyze change impact for a specific element |
135
157
 
136
158
  **Note**: `speckeeper build` generates machine-readable `specs/` output. For human-readable docs (`docs/`), use [embedoc](https://www.npmjs.com/package/embedoc) or similar tools with the model rendering API.
@@ -162,28 +184,26 @@ Checks include:
162
184
 
163
185
  ### External SSOT Validation (check)
164
186
 
165
- Validate your specifications against actual implementation artifacts.
187
+ Validate your specifications against actual implementation artifacts. speckeeper provides built-in checker factories via `speckeeper/dsl`:
166
188
 
167
- **Built-in: Test Coverage Check**
189
+ | Factory | Target | Validates |
190
+ |---------|--------|-----------|
191
+ | `testChecker()` | Test code | Test file existence + spec ID references in describe/it/test blocks |
192
+ | `externalOpenAPIChecker()` | OpenAPI spec | Spec ID existence (operationId, path, schema, x-spec-id), HTTP method, parameter/response property names and types |
193
+ | `externalSqlSchemaChecker()` | SQL schema | Table existence, column existence, type containment (DDL type must be equal or wider than spec type) |
194
+ | `relationCoverage()` | Cross-model | Coverage of a target model via relations |
168
195
 
169
- Define test references that link to your requirements:
196
+ Assign a checker to a model's `externalChecker` property. Scaffold emits guidance comments showing which factory to use based on your `implements` / `verifiedBy` edges.
170
197
 
171
198
  ```typescript
172
- // design/test-refs.ts
173
- import type { TestRef } from 'speckeeper';
199
+ // design/_models/requirement.ts
200
+ import { testChecker } from 'speckeeper/dsl';
174
201
 
175
- export const testRefs: TestRef[] = [
176
- {
177
- id: 'TEST-001',
178
- description: 'Authentication tests',
179
- source: { path: 'test/auth.test.ts', framework: 'vitest' },
180
- verifiesRequirements: ['FR-001'],
181
- testCasePatterns: [
182
- { acceptanceCriteriaId: 'FR-001-01', pattern: 'valid credentials' },
183
- { acceptanceCriteriaId: 'FR-001-02', pattern: 'invalid credentials' },
184
- ],
185
- },
186
- ];
202
+ class RequirementModel extends Model<typeof RequirementSchema> {
203
+ // ... schema, lintRules, etc.
204
+
205
+ protected externalChecker = testChecker<Requirement>();
206
+ }
187
207
  ```
188
208
 
189
209
  ```bash
@@ -196,13 +216,11 @@ speckeeper check
196
216
 
197
217
  ✓ All checks passed
198
218
 
199
- Coverage: TestRef → Requirement
200
- Coverage: 100% (34/34 acceptance criteria covered)
219
+ Coverage: Requirement → UseCase
220
+ Coverage: 100% (7/7 use cases covered)
201
221
  ```
202
222
 
203
- **Custom Checkers**
204
-
205
- Implement `externalChecker` in model definitions to validate against any external source (OpenAPI, DDL, IaC, etc.). See [Model Definition Guide](./docs/model-guide.md) for details.
223
+ You can also implement custom checkers for any external source by defining an `ExternalChecker<T>` directly. See [Model Definition Guide](./docs/model-guide.md) for details.
206
224
 
207
225
  ## Model Levels & Traceability
208
226
 
@@ -223,46 +241,66 @@ $ npx speckeeper impact FR-001
223
241
  FR-001 (Requirement)
224
242
  ├── implements: COMP-AUTH (Component)
225
243
  ├── satisfies: UC-001 (UseCase)
226
- └── verifies: TEST-001 (TestRef)
244
+ └── verifiedBy: TEST-001 (TestRef)
227
245
  ```
228
246
 
229
- See [Model Entity Catalog](./docs/model_entity_catalog.md) for relation types and level constraints.
247
+ ### Relation Types
248
+
249
+ | Relation | Direction | Description |
250
+ |----------|-----------|-------------|
251
+ | `implements` | spec→external | Spec is implemented as external artifact (OpenAPI, DDL) |
252
+ | `verifiedBy` | spec→test | Spec is verified by external test code |
253
+ | `satisfies` | L1→L0 | Satisfies a use case |
254
+ | `refines` | Same level or lower | Refinement |
255
+ | `verifies` | test→implementation | Test verifies implementation code (external, no checker) |
256
+ | `dependsOn` | None | Dependency |
257
+ | `relatedTo` | None | Association |
258
+
259
+ See [Model Entity Catalog](./docs/model_entity_catalog.md) for full details on relation types and level constraints.
230
260
 
231
261
  ## Customizing Models
232
262
 
233
- The starter templates provide basic models. You can customize them or add new domain-specific models:
263
+ Scaffolded models provide a base schema (id, name, description, relations). You can customize them or add new domain-specific models using core factory functions from `speckeeper/dsl`:
234
264
 
235
265
  ```typescript
236
266
  import { z } from 'zod';
237
- import { Model } from 'speckeeper';
267
+ import { Model, RelationSchema } from 'speckeeper';
268
+ import type { LintRule, Exporter, ModelLevel } from 'speckeeper';
269
+ import { requireField, arrayMinLength } from 'speckeeper/dsl';
238
270
 
239
271
  const RunbookSchema = z.object({
240
272
  id: z.string(),
241
- title: z.string(),
273
+ name: z.string().min(1),
274
+ description: z.string(),
242
275
  severity: z.enum(['critical', 'high', 'medium', 'low']),
243
276
  steps: z.array(z.object({
244
277
  action: z.string(),
245
278
  verification: z.string().optional(),
246
- })),
279
+ })).min(1),
280
+ relations: z.array(RelationSchema).optional(),
247
281
  });
248
282
 
283
+ type Runbook = z.input<typeof RunbookSchema>;
284
+
249
285
  class RunbookModel extends Model<typeof RunbookSchema> {
250
- id = 'runbook';
251
- name = 'Runbook';
252
- idPrefix = 'RB';
253
- schema = RunbookSchema;
254
-
255
- lintRules = [
256
- {
257
- id: 'runbook-has-steps',
258
- severity: 'error',
259
- message: 'Runbook must have at least one step',
260
- check: (spec) => spec.steps.length === 0,
261
- },
286
+ readonly id = 'runbook';
287
+ readonly name = 'Runbook';
288
+ readonly idPrefix = 'RB';
289
+ readonly schema = RunbookSchema;
290
+ readonly description = 'Incident runbooks';
291
+ protected modelLevel: ModelLevel = 'L3';
292
+
293
+ protected lintRules: LintRule<Runbook>[] = [
294
+ requireField<Runbook>('description', 'error'),
295
+ arrayMinLength<Runbook>('steps', 1),
262
296
  ];
297
+
298
+ protected exporters: Exporter<Runbook>[] = [];
263
299
  }
264
300
  ```
265
301
 
302
+ Core DSL factories (`speckeeper/dsl`) include `requireField`, `arrayMinLength`, `idFormat`, `childIdFormat`, `markdownExporter`, `testChecker`, `externalOpenAPIChecker`, `externalSqlSchemaChecker`, `relationCoverage`, and `baseSpecSchema`.
303
+
266
304
  ## Documentation
267
305
 
268
306
  - **[Model Definition Guide](./docs/model-guide.md)** — Start here for model customization and API reference