speckeeper 0.8.0 → 0.9.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,20 +11,28 @@
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/
15
- │
16
- design/*.ts ─────────────────────────────► Validation & Consistency Checks
14
+ speckeeper.config.ts (sources)
17
15
  │
18
- ├─► speckeeper lint → Design integrity (IDs, references, phase gates)
19
- ├─► speckeeper check → External SSOT validation (test coverage, etc.)
20
- └─► speckeeper impact → Change impact analysis with traceability
16
+ ├─► Global Source Scan → Find spec IDs in OpenAPI / DDL / annotations
17
+ │ │
18
+ │ ▼
19
+ │ MatchMap (specId → matches)
20
+ │ │
21
+ │ ▼
22
+ ├─► Deep Validation → Model-level structural checks (optional)
23
+ │
24
+ design/*.ts
25
+ │
26
+ ├─► speckeeper lint → Design integrity (IDs, references, phase gates)
27
+ ├─► speckeeper check → External SSOT validation (global scan + deep validation)
28
+ └─► speckeeper impact → Change impact analysis with traceability
21
29
  ```
22
30
 
23
31
  ## Features
24
32
 
25
33
  - **TypeScript as SSOT** — Define requirements, architecture, and design in type-safe TypeScript
26
34
  - **Design validation** — Lint rules for ID uniqueness, reference integrity, circular dependencies, and phase gates
27
- - **External SSOT validation** — Check consistency with test files, and custom checkers for OpenAPI, DDL, etc.
35
+ - **External SSOT validation** — Global scan across OpenAPI, DDL, annotations; optional deep validation per model
28
36
  - **Traceability** — Track relationships across model levels (L0-L3) with impact analysis
29
37
  - **Scaffold from Mermaid** — Generate `_models/` skeletons from a mermaid flowchart with class-based artifact resolution
30
38
  - **Custom models** — Extend with domain-specific models (Runbooks, Policies, etc.)
@@ -78,10 +86,9 @@ flowchart TB
78
86
  Key concepts:
79
87
  - `class ... speckeeper` marks nodes as managed by speckeeper
80
88
  - Additional `class` lines assign **artifact classes** (determines model name/file and node grouping)
81
- - External node classes (`openapi`, `sqlschema`, `test`) determine checker bindings
89
+ - External node classes (`openapi`, `sqlschema`, `test`) describe the artifact type
82
90
  - `subgraph` determines model level (L0–L3)
83
- - `implements` edges trigger external SSOT validation
84
- - `verifiedBy` edges trigger test verification
91
+ - `implements`/`verifiedBy` edges define the relationship semantics
85
92
 
86
93
  ### 2. Scaffold models
87
94
 
@@ -90,10 +97,9 @@ npx speckeeper scaffold --source requirements.md
90
97
  ```
91
98
 
92
99
  This generates:
93
- - `design/_models/` — Model classes with base schema (id, name, description, relations) and core factory imports. Customise after generation.
100
+ - `design/_models/` — Model classes with base schema and lint rules
94
101
  - `design/*.ts` — Spec data files using `defineSpecs()`
95
102
  - `design/index.ts` — Entry point via `mergeSpecs()`
96
- - Checker bindings from `implements`/`verifiedBy` edges are added as guidance comments
97
103
 
98
104
  See [Scaffold Mermaid Specification](./docs/scaffold-mermaid-spec.md) for the full input format.
99
105
 
@@ -152,7 +158,7 @@ npx speckeeper impact FR-001
152
158
  | `speckeeper check` | Verify consistency with external SSOT |
153
159
  | `speckeeper check test --coverage` | Verify test coverage for requirements |
154
160
  | `speckeeper scaffold` | Generate model skeletons from a mermaid flowchart |
155
- | `speckeeper drift` | Detect manual edits to generated `specs/` files |
161
+ | `speckeeper drift` | Detect manual edits to generated `docs/` files |
156
162
  | `speckeeper impact <id>` | Analyze change impact for a specific element |
157
163
 
158
164
  **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.
@@ -184,44 +190,142 @@ Checks include:
184
190
 
185
191
  ### External SSOT Validation (check)
186
192
 
187
- Validate your specifications against actual implementation artifacts. speckeeper provides built-in checker factories via `speckeeper/dsl`:
193
+ Validate your specifications against actual implementation artifacts. speckeeper performs a **global source scan** across all configured sources, then optionally runs **deep validation** using model-specific rules.
194
+
195
+ The check flow has three levels:
196
+
197
+ 1. **Existence check** (automatic) — Is the spec ID found in any configured source?
198
+ 2. **Structural check** (via `deepValidation`) — Does the matched object's structure match? (e.g. HTTP method, table columns)
199
+ 3. **Type check** (via `deepValidation`) — Do types match? (e.g. parameter types, column types)
188
200
 
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 |
201
+ #### Source configuration
195
202
 
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.
203
+ Define global scan sources in `speckeeper.config.ts`:
204
+
205
+ ```typescript
206
+ // speckeeper.config.ts
207
+ import { defineConfig } from 'speckeeper';
208
+
209
+ export default defineConfig({
210
+ // ...
211
+ sources: [
212
+ {
213
+ type: 'openapi',
214
+ paths: ['api/openapi.yaml'],
215
+ relation: 'implements',
216
+ },
217
+ {
218
+ type: 'ddl',
219
+ paths: ['db/schema.sql'],
220
+ relation: 'implements',
221
+ },
222
+ {
223
+ type: 'annotation',
224
+ paths: ['test/**/*.test.ts', 'tests/**/*.test.ts'],
225
+ relation: 'verifiedBy',
226
+ },
227
+ {
228
+ type: 'annotation',
229
+ paths: ['src/**/*.ts'],
230
+ exclude: ['src/**/*.test.ts'],
231
+ relation: 'implements',
232
+ },
233
+ ],
234
+ });
235
+ ```
236
+
237
+ Each source defines:
238
+ - **`type`** — Built-in (`'openapi'`, `'ddl'`, `'annotation'`) or custom with a `scanner` plugin
239
+ - **`paths`** — Glob patterns for files to scan
240
+ - **`relation`** — Whether matches represent `'implements'` or `'verifiedBy'`
241
+
242
+ #### Built-in scanners
243
+
244
+ | Scanner | Finds spec IDs via | Deep validation |
245
+ |---------|-------------------|-----------------|
246
+ | `openapi` | operationId, path segment, schema name, `x-spec-id` | HTTP method, parameter names/types, response property names/types |
247
+ | `ddl` | Table name (case-insensitive, schema-prefix stripped) | Column names, column types (containment-based) |
248
+ | `annotation` | `@verifies`, `@implements`, `@traces` annotations | — |
249
+
250
+ Annotations work in any comment style (`//`, `#`, `--`, `/* */`, `<!-- -->`). Multiple IDs can be comma- or space-separated.
251
+
252
+ ```typescript
253
+ // tests/unit/auth.test.ts
254
+ // @verifies FR-001, FR-001-01
255
+ describe('User Authentication', () => { ... });
256
+ ```
197
257
 
198
258
  ```typescript
199
- // design/_models/requirement.ts
200
- import { testChecker } from 'speckeeper/dsl';
259
+ // src/auth/handler.ts
260
+ // @implements FR-001
261
+ export class AuthHandler { ... }
262
+ ```
263
+
264
+ #### Deep validation (optional)
201
265
 
202
- class RequirementModel extends Model<typeof RequirementSchema> {
266
+ Models can define `deepValidation` to enable Level 2/3 structural checks on matched source objects:
267
+
268
+ ```typescript
269
+ class EntityModel extends Model<typeof EntitySchema> {
203
270
  // ... schema, lintRules, etc.
204
271
 
205
- protected externalChecker = testChecker<Requirement>();
272
+ protected deepValidation: DeepValidationConfig<Entity> = {
273
+ ddl: {
274
+ mapper: (spec) => ({
275
+ tableName: spec.tableName,
276
+ columns: spec.columns.map(c => ({ name: c.name, type: c.type })),
277
+ checkTypes: true,
278
+ }),
279
+ },
280
+ openapi: {
281
+ mapper: (spec) => ({
282
+ path: spec.apiPath,
283
+ method: spec.httpMethod,
284
+ responseProperties: spec.fields.map(f => ({ name: f.name, type: f.type })),
285
+ }),
286
+ },
287
+ };
206
288
  }
207
289
  ```
208
290
 
291
+ Without `deepValidation`, speckeeper still performs existence checks for all spec IDs across all configured sources.
292
+
293
+ #### Custom scanners
294
+
295
+ For file formats not covered by the built-in scanners, provide a custom `SourceScanner` plugin:
296
+
297
+ ```typescript
298
+ // speckeeper.config.ts
299
+ import { defineConfig } from 'speckeeper';
300
+ import type { SourceScanner } from 'speckeeper';
301
+
302
+ const protoScanner: SourceScanner = {
303
+ findSpecIds(content, specIds, filePath) {
304
+ // Parse protobuf content, find spec IDs in service/message names
305
+ // Return SourceMatch[] with specId, location, and optional context
306
+ return [];
307
+ },
308
+ };
309
+
310
+ export default defineConfig({
311
+ sources: [
312
+ { type: 'proto', paths: ['proto/**/*.proto'], relation: 'implements', scanner: protoScanner },
313
+ // ... other sources
314
+ ],
315
+ });
316
+ ```
317
+
209
318
  ```bash
210
- $ npx speckeeper check test --coverage
319
+ $ npx speckeeper check --verbose
211
320
 
212
321
  speckeeper check
213
322
 
214
323
  Design: design/
215
- Type: test
324
+ Type: all
216
325
 
217
326
  ✓ All checks passed
218
-
219
- Coverage: Requirement → UseCase
220
- Coverage: 100% (7/7 use cases covered)
221
327
  ```
222
328
 
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.
224
-
225
329
  ## Model Levels & Traceability
226
330
 
227
331
  speckeeper organizes models by abstraction level:
@@ -299,7 +403,7 @@ class RunbookModel extends Model<typeof RunbookSchema> {
299
403
  }
300
404
  ```
301
405
 
302
- Core DSL factories (`speckeeper/dsl`) include `requireField`, `arrayMinLength`, `idFormat`, `childIdFormat`, `markdownExporter`, `testChecker`, `externalOpenAPIChecker`, `externalSqlSchemaChecker`, `relationCoverage`, and `baseSpecSchema`.
406
+ Core DSL factories (`speckeeper/dsl`) include `requireField`, `arrayMinLength`, `idFormat`, `childIdFormat`, `markdownExporter`, `annotationCoverage`, `relationCoverage`, and `baseSpecSchema`. Global scanner utilities (`openapiScanner`, `ddlScanner`, `annotationScanner`, `createAnnotationScanner`) are also re-exported for advanced use.
303
407
 
304
408
  ## Documentation
305
409