@specship/specship-win32-arm64 0.25.0 → 0.28.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/bin/specship.cmd +31 -1
- package/lib/dist/activation/cheatsheet.d.ts +17 -1
- package/lib/dist/activation/cheatsheet.d.ts.map +1 -1
- package/lib/dist/activation/cheatsheet.js +47 -3
- package/lib/dist/activation/cheatsheet.js.map +1 -1
- package/lib/dist/activation/hook-output.d.ts +80 -0
- package/lib/dist/activation/hook-output.d.ts.map +1 -0
- package/lib/dist/activation/hook-output.js +103 -0
- package/lib/dist/activation/hook-output.js.map +1 -0
- package/lib/dist/activation/search-intercept.d.ts +60 -29
- package/lib/dist/activation/search-intercept.d.ts.map +1 -1
- package/lib/dist/activation/search-intercept.js +159 -55
- package/lib/dist/activation/search-intercept.js.map +1 -1
- package/lib/dist/activation/steering.d.ts +8 -10
- package/lib/dist/activation/steering.d.ts.map +1 -1
- package/lib/dist/activation/steering.js +21 -6
- package/lib/dist/activation/steering.js.map +1 -1
- package/lib/dist/behaviour/behaviour-surface.d.ts +47 -0
- package/lib/dist/behaviour/behaviour-surface.d.ts.map +1 -1
- package/lib/dist/behaviour/behaviour-surface.js +108 -2
- package/lib/dist/behaviour/behaviour-surface.js.map +1 -1
- package/lib/dist/bin/node-version-check.d.ts +22 -7
- package/lib/dist/bin/node-version-check.d.ts.map +1 -1
- package/lib/dist/bin/node-version-check.js +39 -9
- package/lib/dist/bin/node-version-check.js.map +1 -1
- package/lib/dist/bin/specship.js +762 -81
- package/lib/dist/bin/specship.js.map +1 -1
- package/lib/dist/commands/specship/learn.md +22 -0
- package/lib/dist/commands/specship/spec.md +12 -0
- package/lib/dist/db/sqlite-adapter.d.ts +7 -5
- package/lib/dist/db/sqlite-adapter.d.ts.map +1 -1
- package/lib/dist/db/sqlite-adapter.js +11 -9
- package/lib/dist/db/sqlite-adapter.js.map +1 -1
- package/lib/dist/enforce/changed-files.d.ts +11 -0
- package/lib/dist/enforce/changed-files.d.ts.map +1 -1
- package/lib/dist/enforce/changed-files.js +42 -0
- package/lib/dist/enforce/changed-files.js.map +1 -1
- package/lib/dist/enforce/enforce.d.ts +25 -1
- package/lib/dist/enforce/enforce.d.ts.map +1 -1
- package/lib/dist/enforce/enforce.js +58 -3
- package/lib/dist/enforce/enforce.js.map +1 -1
- package/lib/dist/enforce/mutation.d.ts +46 -0
- package/lib/dist/enforce/mutation.d.ts.map +1 -0
- package/lib/dist/enforce/mutation.js +104 -0
- package/lib/dist/enforce/mutation.js.map +1 -0
- package/lib/dist/enforce/suppressions.d.ts +33 -0
- package/lib/dist/enforce/suppressions.d.ts.map +1 -0
- package/lib/dist/enforce/suppressions.js +159 -0
- package/lib/dist/enforce/suppressions.js.map +1 -0
- package/lib/dist/extraction/specs/markdown-spec-extractor.d.ts.map +1 -1
- package/lib/dist/extraction/specs/markdown-spec-extractor.js +16 -2
- package/lib/dist/extraction/specs/markdown-spec-extractor.js.map +1 -1
- package/lib/dist/graph/spec-coverage.d.ts +57 -1
- package/lib/dist/graph/spec-coverage.d.ts.map +1 -1
- package/lib/dist/graph/spec-coverage.js +129 -5
- package/lib/dist/graph/spec-coverage.js.map +1 -1
- package/lib/dist/health/smoke-check.js +2 -2
- package/lib/dist/health/smoke-check.js.map +1 -1
- package/lib/dist/index.d.ts +8 -3
- package/lib/dist/index.d.ts.map +1 -1
- package/lib/dist/index.js +65 -9
- package/lib/dist/index.js.map +1 -1
- package/lib/dist/installer/gemini-commands.d.ts +107 -0
- package/lib/dist/installer/gemini-commands.d.ts.map +1 -0
- package/lib/dist/installer/gemini-commands.js +264 -0
- package/lib/dist/installer/gemini-commands.js.map +1 -0
- package/lib/dist/installer/index.d.ts +23 -1
- package/lib/dist/installer/index.d.ts.map +1 -1
- package/lib/dist/installer/index.js +22 -3
- package/lib/dist/installer/index.js.map +1 -1
- package/lib/dist/installer/install-defaults.d.ts +19 -0
- package/lib/dist/installer/install-defaults.d.ts.map +1 -1
- package/lib/dist/installer/install-defaults.js +28 -0
- package/lib/dist/installer/install-defaults.js.map +1 -1
- package/lib/dist/installer/instructions-template.d.ts +22 -0
- package/lib/dist/installer/instructions-template.d.ts.map +1 -1
- package/lib/dist/installer/instructions-template.js +37 -1
- package/lib/dist/installer/instructions-template.js.map +1 -1
- package/lib/dist/installer/targets/claude.d.ts +4 -0
- package/lib/dist/installer/targets/claude.d.ts.map +1 -1
- package/lib/dist/installer/targets/claude.js +8 -25
- package/lib/dist/installer/targets/claude.js.map +1 -1
- package/lib/dist/installer/targets/gemini.d.ts +85 -12
- package/lib/dist/installer/targets/gemini.d.ts.map +1 -1
- package/lib/dist/installer/targets/gemini.js +527 -30
- package/lib/dist/installer/targets/gemini.js.map +1 -1
- package/lib/dist/installer/targets/shared.d.ts +13 -0
- package/lib/dist/installer/targets/shared.d.ts.map +1 -1
- package/lib/dist/installer/targets/shared.js +18 -0
- package/lib/dist/installer/targets/shared.js.map +1 -1
- package/lib/dist/installer/targets/types.d.ts +12 -0
- package/lib/dist/installer/targets/types.d.ts.map +1 -1
- package/lib/dist/jira/auto-publish.d.ts +71 -4
- package/lib/dist/jira/auto-publish.d.ts.map +1 -1
- package/lib/dist/jira/auto-publish.js +186 -17
- package/lib/dist/jira/auto-publish.js.map +1 -1
- package/lib/dist/jira/reconcile.d.ts +24 -1
- package/lib/dist/jira/reconcile.d.ts.map +1 -1
- package/lib/dist/jira/reconcile.js +46 -2
- package/lib/dist/jira/reconcile.js.map +1 -1
- package/lib/dist/jira/repo-config.d.ts +9 -0
- package/lib/dist/jira/repo-config.d.ts.map +1 -1
- package/lib/dist/jira/repo-config.js +11 -0
- package/lib/dist/jira/repo-config.js.map +1 -1
- package/lib/dist/jira/types.d.ts +7 -0
- package/lib/dist/jira/types.d.ts.map +1 -1
- package/lib/dist/jira/types.js.map +1 -1
- package/lib/dist/knowledge/enforce.d.ts +75 -0
- package/lib/dist/knowledge/enforce.d.ts.map +1 -0
- package/lib/dist/knowledge/enforce.js +250 -0
- package/lib/dist/knowledge/enforce.js.map +1 -0
- package/lib/dist/knowledge/facts.d.ts +33 -0
- package/lib/dist/knowledge/facts.d.ts.map +1 -0
- package/lib/dist/knowledge/facts.js +117 -0
- package/lib/dist/knowledge/facts.js.map +1 -0
- package/lib/dist/knowledge/proposals.d.ts +88 -0
- package/lib/dist/knowledge/proposals.d.ts.map +1 -0
- package/lib/dist/knowledge/proposals.js +360 -0
- package/lib/dist/knowledge/proposals.js.map +1 -0
- package/lib/dist/knowledge/stale.d.ts +64 -0
- package/lib/dist/knowledge/stale.d.ts.map +1 -0
- package/lib/dist/knowledge/stale.js +174 -0
- package/lib/dist/knowledge/stale.js.map +1 -0
- package/lib/dist/mcp/gemini-session.d.ts +50 -0
- package/lib/dist/mcp/gemini-session.d.ts.map +1 -0
- package/lib/dist/mcp/gemini-session.js +159 -0
- package/lib/dist/mcp/gemini-session.js.map +1 -0
- package/lib/dist/mcp/jira-tools.d.ts.map +1 -1
- package/lib/dist/mcp/jira-tools.js +25 -0
- package/lib/dist/mcp/jira-tools.js.map +1 -1
- package/lib/dist/mcp/model-context.d.ts +22 -9
- package/lib/dist/mcp/model-context.d.ts.map +1 -1
- package/lib/dist/mcp/model-context.js +35 -13
- package/lib/dist/mcp/model-context.js.map +1 -1
- package/lib/dist/mcp/proxy.js +1 -1
- package/lib/dist/mcp/proxy.js.map +1 -1
- package/lib/dist/mcp/server-instructions.d.ts +16 -15
- package/lib/dist/mcp/server-instructions.d.ts.map +1 -1
- package/lib/dist/mcp/server-instructions.js +67 -1
- package/lib/dist/mcp/server-instructions.js.map +1 -1
- package/lib/dist/mcp/session.js +1 -1
- package/lib/dist/mcp/session.js.map +1 -1
- package/lib/dist/mcp/spec-tools.d.ts +9 -1
- package/lib/dist/mcp/spec-tools.d.ts.map +1 -1
- package/lib/dist/mcp/spec-tools.js +69 -21
- package/lib/dist/mcp/spec-tools.js.map +1 -1
- package/lib/dist/mcp/tools.d.ts +37 -1
- package/lib/dist/mcp/tools.d.ts.map +1 -1
- package/lib/dist/mcp/tools.js +120 -9
- package/lib/dist/mcp/tools.js.map +1 -1
- package/lib/dist/pulse/pulse.d.ts +93 -0
- package/lib/dist/pulse/pulse.d.ts.map +1 -0
- package/lib/dist/pulse/pulse.js +401 -0
- package/lib/dist/pulse/pulse.js.map +1 -0
- package/lib/dist/reflect/apply.d.ts.map +1 -1
- package/lib/dist/reflect/apply.js +38 -3
- package/lib/dist/reflect/apply.js.map +1 -1
- package/lib/dist/reflect/auto-sweep.d.ts +26 -0
- package/lib/dist/reflect/auto-sweep.d.ts.map +1 -0
- package/lib/dist/reflect/auto-sweep.js +90 -0
- package/lib/dist/reflect/auto-sweep.js.map +1 -0
- package/lib/dist/reflect/cli.d.ts +62 -0
- package/lib/dist/reflect/cli.d.ts.map +1 -0
- package/lib/dist/reflect/cli.js +163 -0
- package/lib/dist/reflect/cli.js.map +1 -0
- package/lib/dist/reflect/miner.d.ts.map +1 -1
- package/lib/dist/reflect/miner.js +119 -0
- package/lib/dist/reflect/miner.js.map +1 -1
- package/lib/dist/reflect/sweep.d.ts +1 -0
- package/lib/dist/reflect/sweep.d.ts.map +1 -1
- package/lib/dist/reflect/sweep.js +62 -13
- package/lib/dist/reflect/sweep.js.map +1 -1
- package/lib/dist/reflect/targets.d.ts +2 -0
- package/lib/dist/reflect/targets.d.ts.map +1 -1
- package/lib/dist/reflect/targets.js +33 -0
- package/lib/dist/reflect/targets.js.map +1 -1
- package/lib/dist/reflect/types.d.ts +19 -2
- package/lib/dist/reflect/types.d.ts.map +1 -1
- package/lib/dist/resolution/test-title-links.d.ts.map +1 -1
- package/lib/dist/resolution/test-title-links.js +3 -14
- package/lib/dist/resolution/test-title-links.js.map +1 -1
- package/lib/dist/server/routes/claude.js +15 -7
- package/lib/dist/server/routes/knowledge.js +118 -0
- package/lib/dist/server/server.js +2 -0
- package/lib/dist/spec-lint/lint.d.ts +1 -1
- package/lib/dist/spec-lint/lint.d.ts.map +1 -1
- package/lib/dist/spec-lint/lint.js +63 -2
- package/lib/dist/spec-lint/lint.js.map +1 -1
- package/lib/dist/spec-quality/criterion-ids.d.ts +13 -0
- package/lib/dist/spec-quality/criterion-ids.d.ts.map +1 -0
- package/lib/dist/spec-quality/criterion-ids.js +38 -0
- package/lib/dist/spec-quality/criterion-ids.js.map +1 -0
- package/lib/dist/spec-quality/evidence-kind.d.ts +54 -0
- package/lib/dist/spec-quality/evidence-kind.d.ts.map +1 -0
- package/lib/dist/spec-quality/evidence-kind.js +183 -0
- package/lib/dist/spec-quality/evidence-kind.js.map +1 -0
- package/lib/dist/spec-quality/link-persist.d.ts +65 -0
- package/lib/dist/spec-quality/link-persist.d.ts.map +1 -0
- package/lib/dist/spec-quality/link-persist.js +249 -0
- package/lib/dist/spec-quality/link-persist.js.map +1 -0
- package/lib/dist/spec-quality/plan-scope.d.ts +38 -0
- package/lib/dist/spec-quality/plan-scope.d.ts.map +1 -0
- package/lib/dist/spec-quality/plan-scope.js +129 -0
- package/lib/dist/spec-quality/plan-scope.js.map +1 -0
- package/lib/dist/spec-quality/postcheck.d.ts +85 -0
- package/lib/dist/spec-quality/postcheck.d.ts.map +1 -0
- package/lib/dist/spec-quality/postcheck.js +390 -0
- package/lib/dist/spec-quality/postcheck.js.map +1 -0
- package/lib/dist/spec-quality/readiness.d.ts +72 -0
- package/lib/dist/spec-quality/readiness.d.ts.map +1 -0
- package/lib/dist/spec-quality/readiness.js +226 -0
- package/lib/dist/spec-quality/readiness.js.map +1 -0
- package/lib/dist/workflows/agents/claude.d.ts +16 -0
- package/lib/dist/workflows/agents/claude.d.ts.map +1 -0
- package/lib/dist/workflows/agents/claude.js +82 -0
- package/lib/dist/workflows/agents/claude.js.map +1 -0
- package/lib/dist/workflows/agents/gemini.d.ts +21 -0
- package/lib/dist/workflows/agents/gemini.d.ts.map +1 -0
- package/lib/dist/workflows/agents/gemini.js +124 -0
- package/lib/dist/workflows/agents/gemini.js.map +1 -0
- package/lib/dist/workflows/agents/index.d.ts +28 -0
- package/lib/dist/workflows/agents/index.d.ts.map +1 -0
- package/lib/dist/workflows/agents/index.js +104 -0
- package/lib/dist/workflows/agents/index.js.map +1 -0
- package/lib/dist/workflows/agents/types.d.ts +55 -0
- package/lib/dist/workflows/agents/types.d.ts.map +1 -0
- package/lib/dist/workflows/agents/types.js +46 -0
- package/lib/dist/workflows/agents/types.js.map +1 -0
- package/lib/dist/workflows/batch.d.ts +63 -0
- package/lib/dist/workflows/batch.d.ts.map +1 -0
- package/lib/dist/workflows/batch.js +151 -0
- package/lib/dist/workflows/batch.js.map +1 -0
- package/lib/dist/workflows/defaults/claude-design-implement.yaml +3 -4
- package/lib/dist/workflows/defaults/spec-author.yaml +11 -9
- package/lib/dist/workflows/defaults/spec-implement-mixed.yaml +21 -436
- package/lib/dist/workflows/defaults/spec-implement.yaml +465 -46
- package/lib/dist/workflows/discovery.d.ts +13 -0
- package/lib/dist/workflows/discovery.d.ts.map +1 -1
- package/lib/dist/workflows/discovery.js +79 -17
- package/lib/dist/workflows/discovery.js.map +1 -1
- package/lib/dist/workflows/executor.d.ts +18 -0
- package/lib/dist/workflows/executor.d.ts.map +1 -1
- package/lib/dist/workflows/executor.js +130 -33
- package/lib/dist/workflows/executor.js.map +1 -1
- package/lib/dist/workflows/gc.d.ts +50 -0
- package/lib/dist/workflows/gc.d.ts.map +1 -0
- package/lib/dist/workflows/gc.js +120 -0
- package/lib/dist/workflows/gc.js.map +1 -0
- package/lib/dist/workflows/merge-queue.d.ts +64 -0
- package/lib/dist/workflows/merge-queue.d.ts.map +1 -0
- package/lib/dist/workflows/merge-queue.js +162 -0
- package/lib/dist/workflows/merge-queue.js.map +1 -0
- package/lib/dist/workflows/runners/approval.d.ts +1 -1
- package/lib/dist/workflows/runners/approval.d.ts.map +1 -1
- package/lib/dist/workflows/runners/approval.js +11 -2
- package/lib/dist/workflows/runners/approval.js.map +1 -1
- package/lib/dist/workflows/runners/bash.d.ts +15 -0
- package/lib/dist/workflows/runners/bash.d.ts.map +1 -1
- package/lib/dist/workflows/runners/bash.js +50 -1
- package/lib/dist/workflows/runners/bash.js.map +1 -1
- package/lib/dist/workflows/runners/prompt.d.ts +16 -41
- package/lib/dist/workflows/runners/prompt.d.ts.map +1 -1
- package/lib/dist/workflows/runners/prompt.js +55 -120
- package/lib/dist/workflows/runners/prompt.js.map +1 -1
- package/lib/dist/workflows/runners/types.d.ts +12 -0
- package/lib/dist/workflows/runners/types.d.ts.map +1 -1
- package/lib/dist/workflows/schemas/workflow.d.ts +17 -0
- package/lib/dist/workflows/schemas/workflow.d.ts.map +1 -1
- package/lib/dist/workflows/schemas/workflow.js +27 -0
- package/lib/dist/workflows/schemas/workflow.js.map +1 -1
- package/lib/node_modules/.package-lock.json +1 -1
- package/lib/package.json +2 -2
- package/package.json +5 -3
- package/node.exe +0 -4
|
@@ -32,6 +32,28 @@ applies it.
|
|
|
32
32
|
ROUTINE
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
+
### Lanes (ALEARN-DOC)
|
|
36
|
+
|
|
37
|
+
The capture has three lanes — pick by what the lesson IS:
|
|
38
|
+
|
|
39
|
+
- **skill** (default, above) — a reusable multi-step routine.
|
|
40
|
+
- **style** — a code-style convention the user stated or corrected ("always
|
|
41
|
+
use named exports", "use our logger, not console.log"). Capture with
|
|
42
|
+
`--lane style`; title = short rule name, stdin = the rule in one or two
|
|
43
|
+
sentences. On apply it lands in `.specship/conventions.md` and is injected
|
|
44
|
+
into every future session's cheatsheet.
|
|
45
|
+
- **domain** — business/product knowledge the user explained (what a term
|
|
46
|
+
means, a rule of the domain, a product decision). Capture with
|
|
47
|
+
`--lane domain`; title = the term/concept, stdin = the fact in plain
|
|
48
|
+
sentences. On apply it lands as a draft fact under `specs/domain/`
|
|
49
|
+
(the apply IS the human confirmation — DOM-SPECSHIP-003).
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
specship reflect --capture --lane style --title "<rule name>" <<'RULE'
|
|
53
|
+
<the convention>
|
|
54
|
+
RULE
|
|
55
|
+
```
|
|
56
|
+
|
|
35
57
|
4. **Tell the user** the proposal id from the output and that they can review
|
|
36
58
|
the open proposals with `specship reflect` (add `--json` for the full
|
|
37
59
|
bodies). Nothing lands until they apply it. The CLI is the only review
|
|
@@ -432,6 +432,18 @@ Pull the requirement's acceptance criteria and its behaviour surface
|
|
|
432
432
|
(`specship_spec` with `spec_id` + `behaviour_surface: true` → UI tier / backend
|
|
433
433
|
tier). For **each** acceptance criterion, author a Playwright test when a UI
|
|
434
434
|
exists and/or a backend test, mirroring the repo's existing test conventions.
|
|
435
|
+
**Honour the surface's test-shape classification (REQ-QGATE-001):** a criterion
|
|
436
|
+
marked `[invariant]` is authored as a **property-based test** with the framework
|
|
437
|
+
the surface names — Hypothesis (`@given` + strategies) on a Python backend,
|
|
438
|
+
fast-check on TypeScript/JavaScript — generating inputs and asserting the
|
|
439
|
+
stated property, never a single hard-coded example. Criteria marked
|
|
440
|
+
`[example]` stay concrete example tests.
|
|
441
|
+
**Contract-fuzz leg (REQ-QGATE-003):** when the surface marks the spec
|
|
442
|
+
route-backed, it emits a Schemathesis command scoped to the linked routes.
|
|
443
|
+
Fill in the OpenAPI schema ref, show the command for review (staging only —
|
|
444
|
+
never run it silently), and record the outcome via `specship_link_verify`
|
|
445
|
+
(fail → result "fail" with the failing case as reason). The fuzz run never
|
|
446
|
+
mints `tests`-kind links.
|
|
435
447
|
**Preview the files → confirm → write**, then `specship_link_assert … kind:tests`
|
|
436
448
|
at the `.A<N>`, run the suite, and `specship_link_verify` each (pass→verified,
|
|
437
449
|
fail→broken; a suite that can't run is reported unrun, never marked broken).
|
|
@@ -9,13 +9,15 @@
|
|
|
9
9
|
* 1. `better-sqlite3` — present only when the host has installed it (a
|
|
10
10
|
* devDependency in this repo, optional in user installs). Ships its
|
|
11
11
|
* own SQLite compiled with FTS5, so it's the only path that works on
|
|
12
|
-
* dev machines whose system Node was built without FTS5.
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
12
|
+
* dev machines whose system Node was built without FTS5.
|
|
13
|
+
* 2. `node:sqlite` — Node's built-in module (Node 22.5+, the supported
|
|
14
|
+
* floor). Published packages bundle no runtime — they run on the
|
|
15
|
+
* user's installed Node (>=22.5 <25) — and `node:sqlite` only ships
|
|
16
|
+
* FTS5 on Node 24, so Node 22/23 users without better-sqlite3 lack FTS5.
|
|
16
17
|
*
|
|
17
18
|
* Tests, dev runs from source, and contributors get FTS5 via better-sqlite3.
|
|
18
|
-
* End users
|
|
19
|
+
* End users get FTS5 via better-sqlite3 (optional dependency) or Node 24's
|
|
20
|
+
* `node:sqlite`.
|
|
19
21
|
*/
|
|
20
22
|
export interface SqliteStatement {
|
|
21
23
|
run(...params: any[]): {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite-adapter.d.ts","sourceRoot":"","sources":["../../src/db/sqlite-adapter.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"sqlite-adapter.d.ts","sourceRoot":"","sources":["../../src/db/sqlite-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,GAAG;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IAC7E,GAAG,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;IAC3B,GAAG,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,CAAC;IAC7B;;;;;OAKG;IACH,OAAO,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;CAClD;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAAC;IACtC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,GAAG,CAAC;IACzD,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;IACjE,KAAK,IAAI,IAAI,CAAC;IACd,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB;AAED;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG,gBAAgB,CAAC;AAqK7D;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,EAAE,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE,aAAa,CAAA;CAAE,CAkC7F"}
|
|
@@ -10,13 +10,15 @@
|
|
|
10
10
|
* 1. `better-sqlite3` — present only when the host has installed it (a
|
|
11
11
|
* devDependency in this repo, optional in user installs). Ships its
|
|
12
12
|
* own SQLite compiled with FTS5, so it's the only path that works on
|
|
13
|
-
* dev machines whose system Node was built without FTS5.
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
13
|
+
* dev machines whose system Node was built without FTS5.
|
|
14
|
+
* 2. `node:sqlite` — Node's built-in module (Node 22.5+, the supported
|
|
15
|
+
* floor). Published packages bundle no runtime — they run on the
|
|
16
|
+
* user's installed Node (>=22.5 <25) — and `node:sqlite` only ships
|
|
17
|
+
* FTS5 on Node 24, so Node 22/23 users without better-sqlite3 lack FTS5.
|
|
17
18
|
*
|
|
18
19
|
* Tests, dev runs from source, and contributors get FTS5 via better-sqlite3.
|
|
19
|
-
* End users
|
|
20
|
+
* End users get FTS5 via better-sqlite3 (optional dependency) or Node 24's
|
|
21
|
+
* `node:sqlite`.
|
|
20
22
|
*/
|
|
21
23
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
24
|
exports.createDatabase = createDatabase;
|
|
@@ -204,10 +206,10 @@ function createDatabase(dbPath) {
|
|
|
204
206
|
errors.push(`node:sqlite: ${error instanceof Error ? error.message : String(error)}`);
|
|
205
207
|
throw new Error('Failed to open SQLite.\n' +
|
|
206
208
|
'SpecShip tries better-sqlite3 first (when installed), then falls back to\n' +
|
|
207
|
-
"Node's built-in node:sqlite (Node 22.5
|
|
208
|
-
'
|
|
209
|
-
'
|
|
210
|
-
'
|
|
209
|
+
"Node's built-in node:sqlite (Node 22.5+; FTS5 ships in node:sqlite only on\n" +
|
|
210
|
+
'Node 24). Run on Node 24, or install better-sqlite3\n' +
|
|
211
|
+
'(`npm install --save-dev better-sqlite3`) so FTS5 works on hosts whose\n' +
|
|
212
|
+
'Node was built without it.\n' +
|
|
211
213
|
`Backend errors:\n${errors.map((e) => ` - ${e}`).join('\n')}`);
|
|
212
214
|
}
|
|
213
215
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite-adapter.js","sourceRoot":"","sources":["../../src/db/sqlite-adapter.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"sqlite-adapter.js","sourceRoot":"","sources":["../../src/db/sqlite-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -25,4 +25,15 @@ export declare class InvalidRefError extends Error {
|
|
|
25
25
|
* the directory is not a git repository.
|
|
26
26
|
*/
|
|
27
27
|
export declare function changedFilesSince(projectRoot: string, ref: string): string[];
|
|
28
|
+
/**
|
|
29
|
+
* Unified diff text of the change under review (REQ-QGATE-004): tracked
|
|
30
|
+
* changes since `ref` (default HEAD), plus every untracked file rendered as a
|
|
31
|
+
* pseudo-diff of all-added lines — a brand-new file's suppressions are exactly
|
|
32
|
+
* as introduced as an edit's. Feed the result to `scanDisableComments`.
|
|
33
|
+
*
|
|
34
|
+
* Throws when the directory is not a git repository (callers decide whether
|
|
35
|
+
* an unavailable scan is skipped or fatal); binary/unreadable untracked files
|
|
36
|
+
* are silently omitted.
|
|
37
|
+
*/
|
|
38
|
+
export declare function workingTreeDiffText(projectRoot: string, ref?: string): string;
|
|
28
39
|
//# sourceMappingURL=changed-files.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"changed-files.d.ts","sourceRoot":"","sources":["../../src/enforce/changed-files.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;
|
|
1
|
+
{"version":3,"file":"changed-files.d.ts","sourceRoot":"","sources":["../../src/enforce/changed-files.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAOH,qEAAqE;AACrE,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;CAQzC;AAWD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAwB5E;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,SAAS,GAAG,MAAM,CA2B7E"}
|
|
@@ -15,7 +15,10 @@
|
|
|
15
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
16
|
exports.InvalidRefError = void 0;
|
|
17
17
|
exports.changedFilesSince = changedFilesSince;
|
|
18
|
+
exports.workingTreeDiffText = workingTreeDiffText;
|
|
18
19
|
const child_process_1 = require("child_process");
|
|
20
|
+
const fs_1 = require("fs");
|
|
21
|
+
const path_1 = require("path");
|
|
19
22
|
const enforce_1 = require("./enforce");
|
|
20
23
|
/** Thrown when `<ref>` is not a commit-ish this repository knows. */
|
|
21
24
|
class InvalidRefError extends Error {
|
|
@@ -69,4 +72,43 @@ function changedFilesSince(projectRoot, ref) {
|
|
|
69
72
|
collect(git(projectRoot, ['ls-files', '--others', '--exclude-standard']));
|
|
70
73
|
return [...out].sort();
|
|
71
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* Unified diff text of the change under review (REQ-QGATE-004): tracked
|
|
77
|
+
* changes since `ref` (default HEAD), plus every untracked file rendered as a
|
|
78
|
+
* pseudo-diff of all-added lines — a brand-new file's suppressions are exactly
|
|
79
|
+
* as introduced as an edit's. Feed the result to `scanDisableComments`.
|
|
80
|
+
*
|
|
81
|
+
* Throws when the directory is not a git repository (callers decide whether
|
|
82
|
+
* an unavailable scan is skipped or fatal); binary/unreadable untracked files
|
|
83
|
+
* are silently omitted.
|
|
84
|
+
*/
|
|
85
|
+
function workingTreeDiffText(projectRoot, ref = 'HEAD') {
|
|
86
|
+
const parts = [git(projectRoot, ['diff', '--no-color', ref, '--'])];
|
|
87
|
+
const untracked = git(projectRoot, ['ls-files', '--others', '--exclude-standard'])
|
|
88
|
+
.split('\n')
|
|
89
|
+
.map((l) => l.trim())
|
|
90
|
+
.filter(Boolean);
|
|
91
|
+
for (const file of untracked) {
|
|
92
|
+
try {
|
|
93
|
+
const content = (0, fs_1.readFileSync)((0, path_1.join)(projectRoot, file), 'utf-8');
|
|
94
|
+
if (content.includes('\u0000'))
|
|
95
|
+
continue; // binary
|
|
96
|
+
const lines = content.split('\n');
|
|
97
|
+
if (lines[lines.length - 1] === '')
|
|
98
|
+
lines.pop();
|
|
99
|
+
parts.push([
|
|
100
|
+
`diff --git a/${file} b/${file}`,
|
|
101
|
+
'--- /dev/null',
|
|
102
|
+
`+++ b/${file}`,
|
|
103
|
+
`@@ -0,0 +1,${lines.length} @@`,
|
|
104
|
+
...lines.map((l) => `+${l}`),
|
|
105
|
+
'',
|
|
106
|
+
].join('\n'));
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
// unreadable → skip
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return parts.join('\n');
|
|
113
|
+
}
|
|
72
114
|
//# sourceMappingURL=changed-files.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"changed-files.js","sourceRoot":"","sources":["../../src/enforce/changed-files.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;;;
|
|
1
|
+
{"version":3,"file":"changed-files.js","sourceRoot":"","sources":["../../src/enforce/changed-files.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,7 +17,9 @@
|
|
|
17
17
|
import { SpecLink } from './../types';
|
|
18
18
|
import { FitnessReport } from '../fitness/fitness';
|
|
19
19
|
import { MaintainabilityReport } from '../graph/maintainability';
|
|
20
|
-
|
|
20
|
+
import { SuppressionFinding } from './suppressions';
|
|
21
|
+
import { MutationConfig, MutationDeps } from './mutation';
|
|
22
|
+
export type CheckName = 'drift' | 'fitness' | 'maintainability' | 'behaviour' | 'suppressions' | 'mutation';
|
|
21
23
|
/**
|
|
22
24
|
* Project-relative, forward-slashed, no `./` prefix. Link target paths, spec
|
|
23
25
|
* source paths and git's output all have to compare in one shape before
|
|
@@ -30,6 +32,8 @@ export interface GateConfig {
|
|
|
30
32
|
fitness?: boolean;
|
|
31
33
|
maintainability?: boolean;
|
|
32
34
|
behaviour?: boolean;
|
|
35
|
+
suppressions?: boolean;
|
|
36
|
+
mutation?: boolean;
|
|
33
37
|
}
|
|
34
38
|
export interface EnforceConfig {
|
|
35
39
|
gate?: GateConfig;
|
|
@@ -37,6 +41,12 @@ export interface EnforceConfig {
|
|
|
37
41
|
behaviour?: {
|
|
38
42
|
exclude?: string[];
|
|
39
43
|
};
|
|
44
|
+
/**
|
|
45
|
+
* Mutation-score gate config (REQ-QGATE-002) — the check exists only when
|
|
46
|
+
* this key (or `gate.mutation`) is present; the default gate output is
|
|
47
|
+
* byte-identical without it (A1).
|
|
48
|
+
*/
|
|
49
|
+
mutation?: MutationConfig;
|
|
40
50
|
}
|
|
41
51
|
/** Tests-link summary for one requirement (its own + its acceptance criteria's). */
|
|
42
52
|
export interface RequirementVerification {
|
|
@@ -55,6 +65,14 @@ export interface EnforceDeps {
|
|
|
55
65
|
fitness: FitnessReport;
|
|
56
66
|
maintainability: MaintainabilityReport;
|
|
57
67
|
requirements: RequirementVerification[];
|
|
68
|
+
/**
|
|
69
|
+
* Suppression markers introduced by the change under review
|
|
70
|
+
* (REQ-QGATE-004). Absent/undefined → the diff scan did not run (no git,
|
|
71
|
+
* no diff) and the check is omitted entirely — never reported as passed.
|
|
72
|
+
*/
|
|
73
|
+
suppressions?: SuppressionFinding[];
|
|
74
|
+
/** Mutation-score snapshot (REQ-QGATE-002); absent → check omitted (A1). */
|
|
75
|
+
mutation?: MutationDeps;
|
|
58
76
|
}
|
|
59
77
|
/**
|
|
60
78
|
* Change-scoped evaluation (REQ-AUTHG-006): restrict the link-scoped checks to
|
|
@@ -78,6 +96,12 @@ export interface CheckOutcome {
|
|
|
78
96
|
* repo-global analyses and always run unscoped (REQ-AUTHG-006).
|
|
79
97
|
*/
|
|
80
98
|
scoped?: boolean;
|
|
99
|
+
/**
|
|
100
|
+
* True when the check's input was unavailable (e.g. no mutation report):
|
|
101
|
+
* presented as skipped, never as pass or fail, and never gates
|
|
102
|
+
* (REQ-QGATE-002.A3).
|
|
103
|
+
*/
|
|
104
|
+
skipped?: boolean;
|
|
81
105
|
}
|
|
82
106
|
export interface EnforceReport {
|
|
83
107
|
checks: CheckOutcome[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enforce.d.ts","sourceRoot":"","sources":["../../src/enforce/enforce.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAsB,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"enforce.d.ts","sourceRoot":"","sources":["../../src/enforce/enforce.ts"],"names":[],"mappings":"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"}
|
|
@@ -58,6 +58,7 @@ exports.enableGateChecks = enableGateChecks;
|
|
|
58
58
|
const fs = __importStar(require("fs"));
|
|
59
59
|
const path = __importStar(require("path"));
|
|
60
60
|
const maintainability_1 = require("../graph/maintainability");
|
|
61
|
+
const suppressions_1 = require("./suppressions");
|
|
61
62
|
/**
|
|
62
63
|
* Project-relative, forward-slashed, no `./` prefix. Link target paths, spec
|
|
63
64
|
* source paths and git's output all have to compare in one shape before
|
|
@@ -135,7 +136,61 @@ function evaluateEnforcement(deps, config = {}, scope) {
|
|
|
135
136
|
...(changed ? { scoped: true } : {}),
|
|
136
137
|
});
|
|
137
138
|
}
|
|
138
|
-
|
|
139
|
+
// --- suppressions (REQ-QGATE-004) ---
|
|
140
|
+
// Only when a diff scan actually ran: an absent scan is unknown, and an
|
|
141
|
+
// unknown result is never rendered as a pass (same doctrine as
|
|
142
|
+
// VERIFY_RESULT=skipped).
|
|
143
|
+
if (deps.suppressions !== undefined) {
|
|
144
|
+
const findings = deps.suppressions.map(suppressions_1.formatSuppressionFinding);
|
|
145
|
+
checks.push({
|
|
146
|
+
check: 'suppressions',
|
|
147
|
+
gating: gate.suppressions === true,
|
|
148
|
+
passed: findings.length === 0,
|
|
149
|
+
findings,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
// --- mutation score (REQ-QGATE-002) ---
|
|
153
|
+
// Present only when configured (A1). Per spec: aggregate mutant kill rates
|
|
154
|
+
// over the requirement's linked files that appear in the report; below the
|
|
155
|
+
// threshold → the spec's test evidence is weak. Report unavailable →
|
|
156
|
+
// skipped, which never fails and is never rendered as pass (A3).
|
|
157
|
+
if (deps.mutation !== undefined) {
|
|
158
|
+
const mu = deps.mutation;
|
|
159
|
+
if (mu.stats === null) {
|
|
160
|
+
checks.push({
|
|
161
|
+
check: 'mutation',
|
|
162
|
+
gating: gate.mutation === true,
|
|
163
|
+
passed: false,
|
|
164
|
+
skipped: true,
|
|
165
|
+
findings: [`mutation gate: skipped — ${mu.reason ?? 'no report'}`],
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
const findings = [];
|
|
170
|
+
const pct = (n) => `${Math.round(n * 100)}%`;
|
|
171
|
+
for (const req of deps.requirements) {
|
|
172
|
+
if (changed && !touches(req.sourcePath) && !(req.linkedFiles ?? []).some(touches))
|
|
173
|
+
continue;
|
|
174
|
+
for (const file of new Set((req.linkedFiles ?? []).map(normalizePath))) {
|
|
175
|
+
const s = mu.stats.get(file);
|
|
176
|
+
if (!s || s.total === 0)
|
|
177
|
+
continue;
|
|
178
|
+
const rate = s.killed / s.total;
|
|
179
|
+
if (rate < mu.threshold) {
|
|
180
|
+
findings.push(`${req.id}: weak test evidence — ${file} mutant kill rate ${pct(rate)} < ${pct(mu.threshold)} threshold (${s.killed}/${s.total} killed)`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
checks.push({
|
|
185
|
+
check: 'mutation',
|
|
186
|
+
gating: gate.mutation === true,
|
|
187
|
+
passed: findings.length === 0,
|
|
188
|
+
findings,
|
|
189
|
+
...(changed ? { scoped: true } : {}),
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
const gatedFailures = checks.filter((c) => c.gating && !c.passed && !c.skipped).map((c) => c.check);
|
|
139
194
|
return { checks, gatedFailures, passed: gatedFailures.length === 0 };
|
|
140
195
|
}
|
|
141
196
|
/** Default name of the checked-in project config file at the project root. */
|
|
@@ -157,13 +212,13 @@ function loadEnforceConfig(projectRoot) {
|
|
|
157
212
|
return {};
|
|
158
213
|
}
|
|
159
214
|
/** All check names, for `--strict` / `--enable-gate` validation. */
|
|
160
|
-
exports.ALL_CHECKS = ['drift', 'fitness', 'maintainability', 'behaviour'];
|
|
215
|
+
exports.ALL_CHECKS = ['drift', 'fitness', 'maintainability', 'behaviour', 'suppressions', 'mutation'];
|
|
161
216
|
/**
|
|
162
217
|
* The `--strict` override (REQ-ENFORCE-004.A2): every check gates for this
|
|
163
218
|
* run only. Nothing is read from or written to the project config.
|
|
164
219
|
*/
|
|
165
220
|
function strictEnforceConfig() {
|
|
166
|
-
return { gate: { drift: true, fitness: true, maintainability: true, behaviour: true } };
|
|
221
|
+
return { gate: { drift: true, fitness: true, maintainability: true, behaviour: true, suppressions: true, mutation: true } };
|
|
167
222
|
}
|
|
168
223
|
/**
|
|
169
224
|
* Persist gating for the named checks into `specship.config.json`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enforce.js","sourceRoot":"","sources":["../../src/enforce/enforce.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"enforce.js","sourceRoot":"","sources":["../../src/enforce/enforce.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mutation-score gate (REQ-QGATE-002).
|
|
3
|
+
*
|
|
4
|
+
* A `tests` link proves a test exists and passed — not that it would notice
|
|
5
|
+
* the implementation breaking (agent-written suites average high coverage but
|
|
6
|
+
* low mutant kill rates). This gate closes that: per spec, the kill rate of
|
|
7
|
+
* mutants in its linked implementation files must clear a threshold for the
|
|
8
|
+
* test evidence to count as strong.
|
|
9
|
+
*
|
|
10
|
+
* SpecShip does NOT run the mutation tool. It consumes a checked-in/CI-produced
|
|
11
|
+
* report in the cross-tool mutation-testing-report-schema JSON (StrykerJS and
|
|
12
|
+
* friends emit it natively; mutmut ecosystems convert). That keeps
|
|
13
|
+
* `specship check` deterministic and fast, and keeps the tool choice with the
|
|
14
|
+
* project. Opt-in via `specship.config.json` → `enforce.mutation`; with no
|
|
15
|
+
* config the check does not exist and the gate's output is unchanged (A1).
|
|
16
|
+
*/
|
|
17
|
+
export declare const DEFAULT_MUTATION_THRESHOLD = 0.8;
|
|
18
|
+
export declare const DEFAULT_MUTATION_REPORT = "reports/mutation/mutation.json";
|
|
19
|
+
/** Per-file mutant stats: killed includes Timeout (the mutant didn't survive). */
|
|
20
|
+
export interface MutationFileStats {
|
|
21
|
+
killed: number;
|
|
22
|
+
total: number;
|
|
23
|
+
}
|
|
24
|
+
export interface MutationConfig {
|
|
25
|
+
/** Project-relative path of the mutation-testing-report-schema JSON. */
|
|
26
|
+
report?: string;
|
|
27
|
+
/** Minimum kill rate (0–1) for a spec's implementation files. */
|
|
28
|
+
threshold?: number;
|
|
29
|
+
}
|
|
30
|
+
/** Deps snapshot the enforcement evaluation consumes. */
|
|
31
|
+
export interface MutationDeps {
|
|
32
|
+
/** Null when the report could not be read — the check reports skipped (A3). */
|
|
33
|
+
stats: Map<string, MutationFileStats> | null;
|
|
34
|
+
reason?: string;
|
|
35
|
+
threshold: number;
|
|
36
|
+
reportPath: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Parse a mutation-testing-report-schema JSON into per-file kill stats.
|
|
40
|
+
* File keys are normalized to project-relative forward-slash paths so they
|
|
41
|
+
* compare against link target paths.
|
|
42
|
+
*/
|
|
43
|
+
export declare function parseMutationReport(json: string): Map<string, MutationFileStats>;
|
|
44
|
+
/** Assemble the deps snapshot from disk — missing/unreadable report → skipped. */
|
|
45
|
+
export declare function loadMutationDeps(projectRoot: string, cfg?: MutationConfig): MutationDeps;
|
|
46
|
+
//# sourceMappingURL=mutation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mutation.d.ts","sourceRoot":"","sources":["../../src/enforce/mutation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,eAAO,MAAM,0BAA0B,MAAM,CAAC;AAC9C,eAAO,MAAM,uBAAuB,mCAAmC,CAAC;AAExE,kFAAkF;AAClF,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,wEAAwE;IACxE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,yDAAyD;AACzD,MAAM,WAAW,YAAY;IAC3B,+EAA+E;IAC/E,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,GAAG,IAAI,CAAC;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAOD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAehF;AAED,kFAAkF;AAClF,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,GAAE,cAAmB,GAAG,YAAY,CAc5F"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Mutation-score gate (REQ-QGATE-002).
|
|
4
|
+
*
|
|
5
|
+
* A `tests` link proves a test exists and passed — not that it would notice
|
|
6
|
+
* the implementation breaking (agent-written suites average high coverage but
|
|
7
|
+
* low mutant kill rates). This gate closes that: per spec, the kill rate of
|
|
8
|
+
* mutants in its linked implementation files must clear a threshold for the
|
|
9
|
+
* test evidence to count as strong.
|
|
10
|
+
*
|
|
11
|
+
* SpecShip does NOT run the mutation tool. It consumes a checked-in/CI-produced
|
|
12
|
+
* report in the cross-tool mutation-testing-report-schema JSON (StrykerJS and
|
|
13
|
+
* friends emit it natively; mutmut ecosystems convert). That keeps
|
|
14
|
+
* `specship check` deterministic and fast, and keeps the tool choice with the
|
|
15
|
+
* project. Opt-in via `specship.config.json` → `enforce.mutation`; with no
|
|
16
|
+
* config the check does not exist and the gate's output is unchanged (A1).
|
|
17
|
+
*/
|
|
18
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
19
|
+
if (k2 === undefined) k2 = k;
|
|
20
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
21
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
22
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
23
|
+
}
|
|
24
|
+
Object.defineProperty(o, k2, desc);
|
|
25
|
+
}) : (function(o, m, k, k2) {
|
|
26
|
+
if (k2 === undefined) k2 = k;
|
|
27
|
+
o[k2] = m[k];
|
|
28
|
+
}));
|
|
29
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
30
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
31
|
+
}) : function(o, v) {
|
|
32
|
+
o["default"] = v;
|
|
33
|
+
});
|
|
34
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
35
|
+
var ownKeys = function(o) {
|
|
36
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
37
|
+
var ar = [];
|
|
38
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
39
|
+
return ar;
|
|
40
|
+
};
|
|
41
|
+
return ownKeys(o);
|
|
42
|
+
};
|
|
43
|
+
return function (mod) {
|
|
44
|
+
if (mod && mod.__esModule) return mod;
|
|
45
|
+
var result = {};
|
|
46
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
47
|
+
__setModuleDefault(result, mod);
|
|
48
|
+
return result;
|
|
49
|
+
};
|
|
50
|
+
})();
|
|
51
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
52
|
+
exports.DEFAULT_MUTATION_REPORT = exports.DEFAULT_MUTATION_THRESHOLD = void 0;
|
|
53
|
+
exports.parseMutationReport = parseMutationReport;
|
|
54
|
+
exports.loadMutationDeps = loadMutationDeps;
|
|
55
|
+
const fs = __importStar(require("fs"));
|
|
56
|
+
const path = __importStar(require("path"));
|
|
57
|
+
const enforce_1 = require("./enforce");
|
|
58
|
+
exports.DEFAULT_MUTATION_THRESHOLD = 0.8;
|
|
59
|
+
exports.DEFAULT_MUTATION_REPORT = 'reports/mutation/mutation.json';
|
|
60
|
+
/** Mutant statuses that count as caught by the suite. */
|
|
61
|
+
const CAUGHT = new Set(['Killed', 'Timeout']);
|
|
62
|
+
/** Statuses that count toward the denominator (detectable-in-principle). */
|
|
63
|
+
const COUNTED = new Set(['Killed', 'Timeout', 'Survived', 'NoCoverage']);
|
|
64
|
+
/**
|
|
65
|
+
* Parse a mutation-testing-report-schema JSON into per-file kill stats.
|
|
66
|
+
* File keys are normalized to project-relative forward-slash paths so they
|
|
67
|
+
* compare against link target paths.
|
|
68
|
+
*/
|
|
69
|
+
function parseMutationReport(json) {
|
|
70
|
+
const parsed = JSON.parse(json);
|
|
71
|
+
const out = new Map();
|
|
72
|
+
for (const [file, data] of Object.entries(parsed.files ?? {})) {
|
|
73
|
+
let killed = 0;
|
|
74
|
+
let total = 0;
|
|
75
|
+
for (const m of data.mutants ?? []) {
|
|
76
|
+
const status = m.status ?? '';
|
|
77
|
+
if (!COUNTED.has(status))
|
|
78
|
+
continue;
|
|
79
|
+
total++;
|
|
80
|
+
if (CAUGHT.has(status))
|
|
81
|
+
killed++;
|
|
82
|
+
}
|
|
83
|
+
out.set((0, enforce_1.normalizePath)(file), { killed, total });
|
|
84
|
+
}
|
|
85
|
+
return out;
|
|
86
|
+
}
|
|
87
|
+
/** Assemble the deps snapshot from disk — missing/unreadable report → skipped. */
|
|
88
|
+
function loadMutationDeps(projectRoot, cfg = {}) {
|
|
89
|
+
const reportPath = cfg.report ?? exports.DEFAULT_MUTATION_REPORT;
|
|
90
|
+
const threshold = cfg.threshold ?? exports.DEFAULT_MUTATION_THRESHOLD;
|
|
91
|
+
try {
|
|
92
|
+
const json = fs.readFileSync(path.join(projectRoot, reportPath), 'utf-8');
|
|
93
|
+
return { stats: parseMutationReport(json), threshold, reportPath };
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
return {
|
|
97
|
+
stats: null,
|
|
98
|
+
reason: `mutation report not readable: ${reportPath} (${err instanceof Error ? err.message.split('\n')[0] : String(err)})`,
|
|
99
|
+
threshold,
|
|
100
|
+
reportPath,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=mutation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mutation.js","sourceRoot":"","sources":["../../src/enforce/mutation.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyCH,kDAeC;AAGD,4CAcC;AAvED,uCAAyB;AACzB,2CAA6B;AAC7B,uCAA0C;AAE7B,QAAA,0BAA0B,GAAG,GAAG,CAAC;AACjC,QAAA,uBAAuB,GAAG,gCAAgC,CAAC;AAwBxE,yDAAyD;AACzD,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC;AAC9C,4EAA4E;AAC5E,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC;AAEzE;;;;GAIG;AACH,SAAgB,mBAAmB,CAAC,IAAY;IAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAyE,CAAC;IACxG,MAAM,GAAG,GAAG,IAAI,GAAG,EAA6B,CAAC;IACjD,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC;QAC9D,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;YACnC,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC;YAC9B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC;gBAAE,SAAS;YACnC,KAAK,EAAE,CAAC;YACR,IAAI,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC;gBAAE,MAAM,EAAE,CAAC;QACnC,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,IAAA,uBAAa,EAAC,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IAClD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,kFAAkF;AAClF,SAAgB,gBAAgB,CAAC,WAAmB,EAAE,MAAsB,EAAE;IAC5E,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,IAAI,+BAAuB,CAAC;IACzD,MAAM,SAAS,GAAG,GAAG,CAAC,SAAS,IAAI,kCAA0B,CAAC;IAC9D,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,EAAE,OAAO,CAAC,CAAC;QAC1E,OAAO,EAAE,KAAK,EAAE,mBAAmB,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;IACrE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,KAAK,EAAE,IAAI;YACX,MAAM,EAAE,iCAAiC,UAAU,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG;YAC1H,SAAS;YACT,UAAU;SACX,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Suppression-comment scan (REQ-QGATE-004).
|
|
3
|
+
*
|
|
4
|
+
* Agents under pressure silence lint/type rules instead of fixing code — the
|
|
5
|
+
* implement workflows forbid it in prose, but prose isn't enforcement. This
|
|
6
|
+
* module detects suppression markers INTRODUCED by a change: a pure function
|
|
7
|
+
* over unified diff text (A2), so the workflows' gate, `specship check`, and
|
|
8
|
+
* tests all share one implementation.
|
|
9
|
+
*
|
|
10
|
+
* Ratchet semantics (A1): only added lines count, and an added line whose
|
|
11
|
+
* exact content also appears among the diff's removed lines is a move, not an
|
|
12
|
+
* introduction. Pre-existing suppressions are out of scope.
|
|
13
|
+
*/
|
|
14
|
+
export interface SuppressionFinding {
|
|
15
|
+
/** Project-relative path of the file the suppression was added to. */
|
|
16
|
+
file: string;
|
|
17
|
+
/** 1-indexed line number in the new file. */
|
|
18
|
+
line: number;
|
|
19
|
+
/** Which marker family matched (e.g. `noqa`, `eslint-disable`). */
|
|
20
|
+
marker: string;
|
|
21
|
+
/** True when the suppression carries an inline justification. */
|
|
22
|
+
justified: boolean;
|
|
23
|
+
/** The added line, trimmed. */
|
|
24
|
+
text: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Scan unified diff text for suppression markers on added lines (A1, A2).
|
|
28
|
+
* Pure: input diff text, output findings — no git, no filesystem.
|
|
29
|
+
*/
|
|
30
|
+
export declare function scanDisableComments(diffText: string): SuppressionFinding[];
|
|
31
|
+
/** Render a finding as one gate-report line. */
|
|
32
|
+
export declare function formatSuppressionFinding(f: SuppressionFinding): string;
|
|
33
|
+
//# sourceMappingURL=suppressions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suppressions.d.ts","sourceRoot":"","sources":["../../src/enforce/suppressions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,WAAW,kBAAkB;IACjC,sEAAsE;IACtE,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,mEAAmE;IACnE,MAAM,EAAE,MAAM,CAAC;IACf,iEAAiE;IACjE,SAAS,EAAE,OAAO,CAAC;IACnB,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;CACd;AAsFD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,EAAE,CA4C1E;AAED,gDAAgD;AAChD,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,kBAAkB,GAAG,MAAM,CAEtE"}
|