@specship/specship-win32-arm64 0.24.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 +11 -13
- package/lib/dist/activation/steering.d.ts.map +1 -1
- package/lib/dist/activation/steering.js +25 -10
- 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 +989 -116
- package/lib/dist/bin/specship.js.map +1 -1
- package/lib/dist/commands/specship/learn.md +27 -3
- package/lib/dist/commands/specship/spec.md +85 -15
- package/lib/dist/db/spec-queries.d.ts +73 -3
- package/lib/dist/db/spec-queries.d.ts.map +1 -1
- package/lib/dist/db/spec-queries.js +139 -5
- package/lib/dist/db/spec-queries.js.map +1 -1
- 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 +39 -0
- package/lib/dist/enforce/changed-files.d.ts.map +1 -0
- package/lib/dist/enforce/changed-files.js +114 -0
- package/lib/dist/enforce/changed-files.js.map +1 -0
- package/lib/dist/enforce/enforce.d.ts +53 -2
- package/lib/dist/enforce/enforce.d.ts.map +1 -1
- package/lib/dist/enforce/enforce.js +95 -8
- 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/grammars.d.ts +10 -0
- package/lib/dist/extraction/grammars.d.ts.map +1 -1
- package/lib/dist/extraction/grammars.js +32 -3
- package/lib/dist/extraction/grammars.js.map +1 -1
- package/lib/dist/extraction/index.d.ts +7 -0
- package/lib/dist/extraction/index.d.ts.map +1 -1
- package/lib/dist/extraction/index.js.map +1 -1
- package/lib/dist/extraction/specs/markdown-spec-extractor.d.ts +7 -0
- package/lib/dist/extraction/specs/markdown-spec-extractor.d.ts.map +1 -1
- package/lib/dist/extraction/specs/markdown-spec-extractor.js +97 -10
- package/lib/dist/extraction/specs/markdown-spec-extractor.js.map +1 -1
- package/lib/dist/extraction/wasm/tree-sitter-pascal.wasm.gz +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-scala.wasm.gz +0 -0
- package/lib/dist/graph/spec-coverage.d.ts +142 -0
- package/lib/dist/graph/spec-coverage.d.ts.map +1 -0
- package/lib/dist/graph/spec-coverage.js +276 -0
- package/lib/dist/graph/spec-coverage.js.map +1 -0
- 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 +75 -7
- package/lib/dist/index.d.ts.map +1 -1
- package/lib/dist/index.js +191 -23
- 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 +55 -8
- package/lib/dist/installer/index.d.ts.map +1 -1
- package/lib/dist/installer/index.js +72 -53
- package/lib/dist/installer/index.js.map +1 -1
- package/lib/dist/installer/init-offer.d.ts +14 -9
- package/lib/dist/installer/init-offer.d.ts.map +1 -1
- package/lib/dist/installer/init-offer.js +13 -9
- package/lib/dist/installer/init-offer.js.map +1 -1
- package/lib/dist/installer/install-defaults.d.ts +81 -0
- package/lib/dist/installer/install-defaults.d.ts.map +1 -0
- package/lib/dist/installer/install-defaults.js +95 -0
- package/lib/dist/installer/install-defaults.js.map +1 -0
- 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 +18 -0
- package/lib/dist/installer/targets/claude.d.ts.map +1 -1
- package/lib/dist/installer/targets/claude.js +70 -23
- 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 +22 -4
- 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/fitness-tool.d.ts +5 -6
- package/lib/dist/mcp/fitness-tool.d.ts.map +1 -1
- package/lib/dist/mcp/fitness-tool.js +0 -16
- package/lib/dist/mcp/fitness-tool.js.map +1 -1
- 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/health-tool.d.ts +26 -0
- package/lib/dist/mcp/health-tool.d.ts.map +1 -0
- package/lib/dist/mcp/health-tool.js +50 -0
- package/lib/dist/mcp/health-tool.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/maintainability-tool.d.ts +5 -7
- package/lib/dist/mcp/maintainability-tool.d.ts.map +1 -1
- package/lib/dist/mcp/maintainability-tool.js +0 -16
- package/lib/dist/mcp/maintainability-tool.js.map +1 -1
- package/lib/dist/mcp/model-context.d.ts +31 -7
- package/lib/dist/mcp/model-context.d.ts.map +1 -1
- package/lib/dist/mcp/model-context.js +70 -21
- package/lib/dist/mcp/model-context.js.map +1 -1
- package/lib/dist/mcp/proxy.d.ts.map +1 -1
- package/lib/dist/mcp/proxy.js +5 -2
- 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 +72 -5
- 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 +282 -49
- package/lib/dist/mcp/spec-tools.js.map +1 -1
- package/lib/dist/mcp/tools.d.ts +49 -9
- package/lib/dist/mcp/tools.d.ts.map +1 -1
- package/lib/dist/mcp/tools.js +210 -58
- 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/spec-link-resolver.d.ts +44 -2
- package/lib/dist/resolution/spec-link-resolver.d.ts.map +1 -1
- package/lib/dist/resolution/spec-link-resolver.js +132 -0
- package/lib/dist/resolution/spec-link-resolver.js.map +1 -1
- package/lib/dist/resolution/test-title-links.d.ts +62 -0
- package/lib/dist/resolution/test-title-links.d.ts.map +1 -0
- package/lib/dist/resolution/test-title-links.js +97 -0
- package/lib/dist/resolution/test-title-links.js.map +1 -0
- package/lib/dist/search/query-parser.d.ts.map +1 -1
- package/lib/dist/search/query-parser.js +6 -1
- package/lib/dist/search/query-parser.js.map +1 -1
- package/lib/dist/server/project-registry.js +1 -1
- package/lib/dist/server/routes/claude.js +24 -43
- package/lib/dist/server/routes/graph.js +53 -7
- package/lib/dist/server/routes/knowledge.js +118 -0
- package/lib/dist/server/routes/mcp.js +4 -3
- package/lib/dist/server/routes/projects.js +4 -4
- package/lib/dist/server/routes/spec.js +49 -7
- package/lib/dist/server/server.js +31 -17
- package/lib/dist/skills/spec-author/SKILL.md +164 -0
- package/lib/dist/skills/spec-author/references/format.md +210 -0
- package/lib/dist/skills/spec-author/references/gap-questions.md +152 -0
- package/lib/dist/skills/spec-author/references/quality-rubric.md +125 -0
- package/lib/dist/skills/spec-author/references/review-checklist.md +175 -0
- package/lib/dist/spec-lint/lint.d.ts +82 -0
- package/lib/dist/spec-lint/lint.d.ts.map +1 -0
- package/lib/dist/spec-lint/lint.js +491 -0
- package/lib/dist/spec-lint/lint.js.map +1 -0
- 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/statusline/index.js.map +1 -1
- package/lib/dist/statusline/render.d.ts +1 -1
- package/lib/dist/statusline/render.d.ts.map +1 -1
- package/lib/dist/statusline/render.js +3 -1
- package/lib/dist/statusline/render.js.map +1 -1
- package/lib/dist/ui/assets/index-BzuUWUAE.js +50 -0
- package/lib/dist/ui/index.html +1 -1
- package/lib/dist/verify/report-ingest.d.ts +88 -0
- package/lib/dist/verify/report-ingest.d.ts.map +1 -0
- package/lib/dist/verify/report-ingest.js +269 -0
- package/lib/dist/verify/report-ingest.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-fix.yaml +103 -12
- package/lib/dist/workflows/defaults/spec-implement-mixed.yaml +21 -193
- package/lib/dist/workflows/defaults/spec-implement.yaml +701 -41
- package/lib/dist/workflows/defaults/spec-verify.yaml +60 -9
- 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 +8 -4
- package/package.json +5 -3
- package/lib/dist/extraction/wasm/tree-sitter-pascal.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-scala.wasm +0 -0
- package/lib/dist/server/ingest/impact-query.js +0 -343
- package/lib/dist/server/routes/events.js +0 -152
- package/lib/dist/ui/assets/index-CjjaftDw.js +0 -50
- package/node.exe +0 -4
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spec coverage rollup (REQ-VSTATE-006).
|
|
3
|
+
*
|
|
4
|
+
* Answers the one question nothing could answer before: which requirements and
|
|
5
|
+
* which individual acceptance criteria have PASSING TEST EVIDENCE.
|
|
6
|
+
*
|
|
7
|
+
* The rule that makes the number honest: a verdict derives ONLY from `tests`
|
|
8
|
+
* links. An `implements` link says code claims to satisfy the spec — it is not
|
|
9
|
+
* proof, so a criterion with implementation and no test reads `untested`
|
|
10
|
+
* (REQ-VSTATE-006.A3). This is the conflation the dashboard's
|
|
11
|
+
* implemented-counted-as-met display was built on.
|
|
12
|
+
*/
|
|
13
|
+
import type { Spec, SpecLink, SpecLinkState } from '../types';
|
|
14
|
+
import type { SpecQueries } from '../db/spec-queries';
|
|
15
|
+
import { type EvidenceKind } from '../spec-quality/evidence-kind';
|
|
16
|
+
/**
|
|
17
|
+
* Coverage verdict for one spec node.
|
|
18
|
+
*
|
|
19
|
+
* - `untested` no `tests` link at all (implementation alone lands here)
|
|
20
|
+
* - `tested` tests are linked but none has a passing verification yet
|
|
21
|
+
* - `verified` every linked test is `verified`
|
|
22
|
+
* - `broken` at least one linked test is `broken` (worst state wins)
|
|
23
|
+
*/
|
|
24
|
+
export type CoverageVerdict = 'untested' | 'tested' | 'verified' | 'broken';
|
|
25
|
+
/** Link counts by state for one link kind. */
|
|
26
|
+
export interface LinkRollup {
|
|
27
|
+
count: number;
|
|
28
|
+
/** Per-state counts, e.g. `{ verified: 2, drifted: 1 }`. Only non-zero keys. */
|
|
29
|
+
states: Partial<Record<SpecLinkState, number>>;
|
|
30
|
+
}
|
|
31
|
+
/** Coverage for one acceptance criterion (or any leaf spec). */
|
|
32
|
+
export interface CriterionCoverage {
|
|
33
|
+
specId: string;
|
|
34
|
+
title: string;
|
|
35
|
+
kind: Spec['kind'];
|
|
36
|
+
implementsLinks: LinkRollup;
|
|
37
|
+
testsLinks: LinkRollup;
|
|
38
|
+
verdict: CoverageVerdict;
|
|
39
|
+
/**
|
|
40
|
+
* The evidence kind this criterion requires (REQ-PIPETRUST-001) — declared
|
|
41
|
+
* inline or derived. Advisory alongside the verdict; never changes it.
|
|
42
|
+
*/
|
|
43
|
+
requiredKind: EvidenceKind;
|
|
44
|
+
/** Kinds actually provided by the criterion's usable `tests` links (REQ-PIPETRUST-003). */
|
|
45
|
+
presentKinds: EvidenceKind[];
|
|
46
|
+
/** True when `presentKinds` includes `requiredKind`. */
|
|
47
|
+
kindSatisfied: boolean;
|
|
48
|
+
}
|
|
49
|
+
/** Per-criterion evidence-kind result (REQ-PIPETRUST-003). */
|
|
50
|
+
export interface EvidenceKindResult {
|
|
51
|
+
requiredKind: EvidenceKind;
|
|
52
|
+
presentKinds: EvidenceKind[];
|
|
53
|
+
kindSatisfied: boolean;
|
|
54
|
+
}
|
|
55
|
+
export interface EvidenceKindOptions {
|
|
56
|
+
/** Implements links whose targets decide `linksUi` / `linksRoute`. */
|
|
57
|
+
implementsLinks?: SpecLink[];
|
|
58
|
+
/** Root that relative link target paths resolve against (default: cwd). */
|
|
59
|
+
projectRoot?: string;
|
|
60
|
+
/** Test-file classifier; defaults to reading the file. Injectable for caching. */
|
|
61
|
+
classify?: (absPath: string, relPath: string) => EvidenceKind;
|
|
62
|
+
}
|
|
63
|
+
export interface SpecCoverageOptions {
|
|
64
|
+
/** Project root for reading linked test files when classifying evidence kind. */
|
|
65
|
+
projectRoot?: string;
|
|
66
|
+
}
|
|
67
|
+
/** Coverage for one requirement plus each of its criteria. */
|
|
68
|
+
export interface RequirementCoverage extends CriterionCoverage {
|
|
69
|
+
criteria: CriterionCoverage[];
|
|
70
|
+
/** Criteria whose verdict is `verified` / `tested` / `broken` / `untested`. */
|
|
71
|
+
criteriaTotals: Record<CoverageVerdict, number>;
|
|
72
|
+
/** Criteria carrying at least one `tests` link — the "N of M" numerator. */
|
|
73
|
+
criteriaWithTests: number;
|
|
74
|
+
/** Criteria counted, or 1 when the requirement has none (itself). */
|
|
75
|
+
criteriaCount: number;
|
|
76
|
+
}
|
|
77
|
+
export interface SpecCoverageReport {
|
|
78
|
+
/** The spec the report was scoped to, or null for the whole project. */
|
|
79
|
+
specId: string | null;
|
|
80
|
+
requirements: RequirementCoverage[];
|
|
81
|
+
totals: {
|
|
82
|
+
requirements: number;
|
|
83
|
+
criteria: number;
|
|
84
|
+
criteriaWithTests: number;
|
|
85
|
+
criteriaVerified: number;
|
|
86
|
+
criteriaBroken: number;
|
|
87
|
+
};
|
|
88
|
+
/** Evidence-kind rollup (REQ-PIPETRUST-003) — kept out of `totals` so its shape is unchanged. */
|
|
89
|
+
evidence: {
|
|
90
|
+
/** Criteria (requirements with none count as one) lacking their required kind. */
|
|
91
|
+
criteriaMissingKind: number;
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Verdict from `tests` links alone (REQ-VSTATE-006.A1 / .A3). Links flagged as
|
|
96
|
+
* non-test evidence (a `verifies:` bullet aimed at a fixture — REQ-VSTATE-002.A4)
|
|
97
|
+
* are not counted: they cannot prove anything, so a criterion "covered" only by
|
|
98
|
+
* one stays `untested`.
|
|
99
|
+
*/
|
|
100
|
+
export declare function verdictFor(testsLinks: SpecLink[]): CoverageVerdict;
|
|
101
|
+
/**
|
|
102
|
+
* Required vs present evidence kind for one criterion (REQ-PIPETRUST-003.A1).
|
|
103
|
+
*
|
|
104
|
+
* Required: {@link requiredEvidenceKind} over the criterion text, with
|
|
105
|
+
* `linksUi` / `linksRoute` read from the given implements links (a UI file
|
|
106
|
+
* extension, or a target node of kind `route`). Present: the kind of each
|
|
107
|
+
* usable `tests` link's target file — links flagged as non-test evidence are
|
|
108
|
+
* ignored, exactly as the verdict ignores them. Link state does not matter
|
|
109
|
+
* here: the verdict already says whether the tests pass.
|
|
110
|
+
*/
|
|
111
|
+
export declare function evidenceKindCoverage(criterionText: string, testsLinks: SpecLink[], opts?: EvidenceKindOptions): EvidenceKindResult;
|
|
112
|
+
/**
|
|
113
|
+
* Compute the coverage rollup for one spec, or for every requirement in the
|
|
114
|
+
* project when `specId` is omitted.
|
|
115
|
+
*
|
|
116
|
+
* Scoping: a `document` id expands to its requirement children; a `requirement`
|
|
117
|
+
* id is itself; anything else (an acceptance criterion, a domain fact, a brief)
|
|
118
|
+
* is reported as a single entry with no children. An unknown id — or a spec with
|
|
119
|
+
* no children and no links — returns an empty-but-valid report, never an error
|
|
120
|
+
* (REQ-VSTATE-006.A4).
|
|
121
|
+
*/
|
|
122
|
+
export declare function computeSpecCoverage(sq: SpecQueries, specId?: string, options?: SpecCoverageOptions): SpecCoverageReport;
|
|
123
|
+
/**
|
|
124
|
+
* Every in-scope criterion lacking its required evidence kind — the list
|
|
125
|
+
* `specship coverage` flags, as `{ specId, requiredKind, presentKinds }`. A
|
|
126
|
+
* requirement with no criteria stands in as its own single criterion.
|
|
127
|
+
*/
|
|
128
|
+
export declare function criteriaMissingKind(report: SpecCoverageReport): CriterionCoverage[];
|
|
129
|
+
/**
|
|
130
|
+
* Exit code for `specship coverage --require-kinds` (REQ-PIPETRUST-003.A2):
|
|
131
|
+
* non-zero when any in-scope criterion lacks its required kind, else zero.
|
|
132
|
+
* Without the flag the command never fails on kinds.
|
|
133
|
+
*/
|
|
134
|
+
export declare function requireKindsExitCode(report: SpecCoverageReport, requireKinds: boolean): number;
|
|
135
|
+
/**
|
|
136
|
+
* The single coverage line the implement workflow's human gate rests on
|
|
137
|
+
* (REQ-VSTATE-005.A2). Rendered here, from the same report `getSpecCoverage`
|
|
138
|
+
* returns, so the workflow's number and the API's number cannot disagree —
|
|
139
|
+
* previously an LLM counted it by eye.
|
|
140
|
+
*/
|
|
141
|
+
export declare function formatCoverageLine(report: SpecCoverageReport): string;
|
|
142
|
+
//# sourceMappingURL=spec-coverage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec-coverage.d.ts","sourceRoot":"","sources":["../../src/graph/spec-coverage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Spec coverage rollup (REQ-VSTATE-006).
|
|
4
|
+
*
|
|
5
|
+
* Answers the one question nothing could answer before: which requirements and
|
|
6
|
+
* which individual acceptance criteria have PASSING TEST EVIDENCE.
|
|
7
|
+
*
|
|
8
|
+
* The rule that makes the number honest: a verdict derives ONLY from `tests`
|
|
9
|
+
* links. An `implements` link says code claims to satisfy the spec — it is not
|
|
10
|
+
* proof, so a criterion with implementation and no test reads `untested`
|
|
11
|
+
* (REQ-VSTATE-006.A3). This is the conflation the dashboard's
|
|
12
|
+
* implemented-counted-as-met display was built on.
|
|
13
|
+
*/
|
|
14
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
17
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
18
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
19
|
+
}
|
|
20
|
+
Object.defineProperty(o, k2, desc);
|
|
21
|
+
}) : (function(o, m, k, k2) {
|
|
22
|
+
if (k2 === undefined) k2 = k;
|
|
23
|
+
o[k2] = m[k];
|
|
24
|
+
}));
|
|
25
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
26
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
27
|
+
}) : function(o, v) {
|
|
28
|
+
o["default"] = v;
|
|
29
|
+
});
|
|
30
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
31
|
+
var ownKeys = function(o) {
|
|
32
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
33
|
+
var ar = [];
|
|
34
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
35
|
+
return ar;
|
|
36
|
+
};
|
|
37
|
+
return ownKeys(o);
|
|
38
|
+
};
|
|
39
|
+
return function (mod) {
|
|
40
|
+
if (mod && mod.__esModule) return mod;
|
|
41
|
+
var result = {};
|
|
42
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
43
|
+
__setModuleDefault(result, mod);
|
|
44
|
+
return result;
|
|
45
|
+
};
|
|
46
|
+
})();
|
|
47
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
+
exports.verdictFor = verdictFor;
|
|
49
|
+
exports.evidenceKindCoverage = evidenceKindCoverage;
|
|
50
|
+
exports.computeSpecCoverage = computeSpecCoverage;
|
|
51
|
+
exports.criteriaMissingKind = criteriaMissingKind;
|
|
52
|
+
exports.requireKindsExitCode = requireKindsExitCode;
|
|
53
|
+
exports.formatCoverageLine = formatCoverageLine;
|
|
54
|
+
const test_title_links_1 = require("../resolution/test-title-links");
|
|
55
|
+
const path = __importStar(require("path"));
|
|
56
|
+
const evidence_kind_1 = require("../spec-quality/evidence-kind");
|
|
57
|
+
/** Matches behaviour-surface's `UI_FILE`: a direct link to one of these is UI code. */
|
|
58
|
+
const UI_FILE = /\.(tsx|jsx|vue|svelte|astro)$/i;
|
|
59
|
+
function rollup(links) {
|
|
60
|
+
const states = {};
|
|
61
|
+
for (const l of links)
|
|
62
|
+
states[l.state] = (states[l.state] ?? 0) + 1;
|
|
63
|
+
return { count: links.length, states };
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Verdict from `tests` links alone (REQ-VSTATE-006.A1 / .A3). Links flagged as
|
|
67
|
+
* non-test evidence (a `verifies:` bullet aimed at a fixture — REQ-VSTATE-002.A4)
|
|
68
|
+
* are not counted: they cannot prove anything, so a criterion "covered" only by
|
|
69
|
+
* one stays `untested`.
|
|
70
|
+
*/
|
|
71
|
+
function verdictFor(testsLinks) {
|
|
72
|
+
const usable = testsLinks.filter((l) => !(0, test_title_links_1.isNonTestEvidence)(l));
|
|
73
|
+
if (usable.length === 0)
|
|
74
|
+
return 'untested';
|
|
75
|
+
if (usable.some((l) => l.state === 'broken'))
|
|
76
|
+
return 'broken';
|
|
77
|
+
if (usable.every((l) => l.state === 'verified'))
|
|
78
|
+
return 'verified';
|
|
79
|
+
return 'tested';
|
|
80
|
+
}
|
|
81
|
+
/** Worst-wins merge, so a rollup never reads better than its worst part. */
|
|
82
|
+
function mergeVerdicts(verdicts) {
|
|
83
|
+
if (verdicts.length === 0)
|
|
84
|
+
return 'untested';
|
|
85
|
+
if (verdicts.includes('broken'))
|
|
86
|
+
return 'broken';
|
|
87
|
+
if (verdicts.includes('untested'))
|
|
88
|
+
return 'untested';
|
|
89
|
+
if (verdicts.every((v) => v === 'verified'))
|
|
90
|
+
return 'verified';
|
|
91
|
+
return 'tested';
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Required vs present evidence kind for one criterion (REQ-PIPETRUST-003.A1).
|
|
95
|
+
*
|
|
96
|
+
* Required: {@link requiredEvidenceKind} over the criterion text, with
|
|
97
|
+
* `linksUi` / `linksRoute` read from the given implements links (a UI file
|
|
98
|
+
* extension, or a target node of kind `route`). Present: the kind of each
|
|
99
|
+
* usable `tests` link's target file — links flagged as non-test evidence are
|
|
100
|
+
* ignored, exactly as the verdict ignores them. Link state does not matter
|
|
101
|
+
* here: the verdict already says whether the tests pass.
|
|
102
|
+
*/
|
|
103
|
+
function evidenceKindCoverage(criterionText, testsLinks, opts = {}) {
|
|
104
|
+
const impl = opts.implementsLinks ?? [];
|
|
105
|
+
const requiredKind = (0, evidence_kind_1.requiredEvidenceKind)(criterionText, {
|
|
106
|
+
linksUi: impl.some((l) => UI_FILE.test(l.targetFilePath ?? '')),
|
|
107
|
+
linksRoute: impl.some((l) => l.targetNodeKind === 'route'),
|
|
108
|
+
});
|
|
109
|
+
const classify = opts.classify ?? ((abs) => (0, evidence_kind_1.classifyTestEvidence)(abs));
|
|
110
|
+
const present = new Set();
|
|
111
|
+
for (const l of testsLinks) {
|
|
112
|
+
if (l.kind !== 'tests' || (0, test_title_links_1.isNonTestEvidence)(l) || !l.targetFilePath)
|
|
113
|
+
continue;
|
|
114
|
+
const rel = l.targetFilePath;
|
|
115
|
+
const abs = path.isAbsolute(rel) || !opts.projectRoot ? rel : path.join(opts.projectRoot, rel);
|
|
116
|
+
present.add(classify(abs, rel));
|
|
117
|
+
}
|
|
118
|
+
const presentKinds = evidence_kind_1.EVIDENCE_KINDS.filter((k) => present.has(k));
|
|
119
|
+
return { requiredKind, presentKinds, kindSatisfied: present.has(requiredKind) };
|
|
120
|
+
}
|
|
121
|
+
/** Classify each test file once per report, keyed by absolute path. */
|
|
122
|
+
function cachedClassifier() {
|
|
123
|
+
const cache = new Map();
|
|
124
|
+
return (abs) => {
|
|
125
|
+
let k = cache.get(abs);
|
|
126
|
+
if (!k) {
|
|
127
|
+
k = (0, evidence_kind_1.classifyTestEvidence)(abs);
|
|
128
|
+
cache.set(abs, k);
|
|
129
|
+
}
|
|
130
|
+
return k;
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
function coverageOf(sq, spec, kindOpts) {
|
|
134
|
+
const links = sq.getLinksBySpec(spec.id);
|
|
135
|
+
const testsLinks = links.filter((l) => l.kind === 'tests');
|
|
136
|
+
const implementsLinks = links.filter((l) => l.kind === 'implements');
|
|
137
|
+
const kinds = evidenceKindCoverage(spec.body ?? spec.title, testsLinks, {
|
|
138
|
+
...kindOpts,
|
|
139
|
+
implementsLinks: [...(kindOpts.extraImplements ?? []), ...implementsLinks],
|
|
140
|
+
});
|
|
141
|
+
return {
|
|
142
|
+
specId: spec.id,
|
|
143
|
+
title: spec.title,
|
|
144
|
+
kind: spec.kind,
|
|
145
|
+
implementsLinks: rollup(implementsLinks),
|
|
146
|
+
testsLinks: rollup(testsLinks),
|
|
147
|
+
verdict: verdictFor(testsLinks),
|
|
148
|
+
...kinds,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Compute the coverage rollup for one spec, or for every requirement in the
|
|
153
|
+
* project when `specId` is omitted.
|
|
154
|
+
*
|
|
155
|
+
* Scoping: a `document` id expands to its requirement children; a `requirement`
|
|
156
|
+
* id is itself; anything else (an acceptance criterion, a domain fact, a brief)
|
|
157
|
+
* is reported as a single entry with no children. An unknown id — or a spec with
|
|
158
|
+
* no children and no links — returns an empty-but-valid report, never an error
|
|
159
|
+
* (REQ-VSTATE-006.A4).
|
|
160
|
+
*/
|
|
161
|
+
function computeSpecCoverage(sq, specId, options = {}) {
|
|
162
|
+
const kindOpts = {
|
|
163
|
+
projectRoot: options.projectRoot,
|
|
164
|
+
classify: cachedClassifier(),
|
|
165
|
+
};
|
|
166
|
+
let roots;
|
|
167
|
+
if (specId) {
|
|
168
|
+
const spec = sq.getSpecById(specId);
|
|
169
|
+
if (!spec) {
|
|
170
|
+
return {
|
|
171
|
+
specId,
|
|
172
|
+
requirements: [],
|
|
173
|
+
totals: { requirements: 0, criteria: 0, criteriaWithTests: 0, criteriaVerified: 0, criteriaBroken: 0 },
|
|
174
|
+
evidence: { criteriaMissingKind: 0 },
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
roots =
|
|
178
|
+
spec.kind === 'document'
|
|
179
|
+
? sq.getSpecsByParent(spec.id).filter((s) => s.kind === 'requirement')
|
|
180
|
+
: [spec];
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
roots = sq.getAllSpecs().filter((s) => s.kind === 'requirement');
|
|
184
|
+
}
|
|
185
|
+
const requirements = roots.map((req) => {
|
|
186
|
+
const own = coverageOf(sq, req, kindOpts);
|
|
187
|
+
// A criterion inherits the requirement's direct implements links when
|
|
188
|
+
// deciding UI / route (REQ-PIPETRUST-001.A2 — "a requirement linked to…").
|
|
189
|
+
const reqImplements = sq.getLinksBySpec(req.id).filter((l) => l.kind === 'implements');
|
|
190
|
+
const criteria = sq
|
|
191
|
+
.getSpecsByParent(req.id)
|
|
192
|
+
.filter((c) => c.kind === 'acceptance')
|
|
193
|
+
.map((c) => coverageOf(sq, c, { ...kindOpts, extraImplements: reqImplements }));
|
|
194
|
+
const criteriaTotals = {
|
|
195
|
+
untested: 0,
|
|
196
|
+
tested: 0,
|
|
197
|
+
verified: 0,
|
|
198
|
+
broken: 0,
|
|
199
|
+
};
|
|
200
|
+
for (const c of criteria)
|
|
201
|
+
criteriaTotals[c.verdict]++;
|
|
202
|
+
// A requirement with no acceptance children IS its own single criterion —
|
|
203
|
+
// the same convention the workflow coverage line has always used.
|
|
204
|
+
const criteriaCount = criteria.length > 0 ? criteria.length : 1;
|
|
205
|
+
// "has linked tests" means USABLE test evidence — `untested` is exactly the
|
|
206
|
+
// verdict for "no tests link that could ever prove this".
|
|
207
|
+
const criteriaWithTests = criteria.length > 0
|
|
208
|
+
? criteria.filter((c) => c.verdict !== 'untested').length
|
|
209
|
+
: own.verdict === 'untested'
|
|
210
|
+
? 0
|
|
211
|
+
: 1;
|
|
212
|
+
if (criteria.length === 0)
|
|
213
|
+
criteriaTotals[own.verdict]++;
|
|
214
|
+
return {
|
|
215
|
+
...own,
|
|
216
|
+
verdict: mergeVerdicts(criteria.length > 0 ? criteria.map((c) => c.verdict) : [own.verdict]),
|
|
217
|
+
// A requirement's kind is satisfied only when every criterion's is; with
|
|
218
|
+
// no criteria it is its own single criterion.
|
|
219
|
+
kindSatisfied: criteria.length > 0 ? criteria.every((c) => c.kindSatisfied) : own.kindSatisfied,
|
|
220
|
+
criteria,
|
|
221
|
+
criteriaTotals,
|
|
222
|
+
criteriaWithTests,
|
|
223
|
+
criteriaCount,
|
|
224
|
+
};
|
|
225
|
+
});
|
|
226
|
+
const criteriaMissingKind = requirements.reduce((n, r) => n + (r.criteria.length > 0 ? r.criteria.filter((c) => !c.kindSatisfied).length : r.kindSatisfied ? 0 : 1), 0);
|
|
227
|
+
return {
|
|
228
|
+
specId: specId ?? null,
|
|
229
|
+
requirements,
|
|
230
|
+
totals: {
|
|
231
|
+
requirements: requirements.length,
|
|
232
|
+
criteria: requirements.reduce((n, r) => n + r.criteriaCount, 0),
|
|
233
|
+
criteriaWithTests: requirements.reduce((n, r) => n + r.criteriaWithTests, 0),
|
|
234
|
+
criteriaVerified: requirements.reduce((n, r) => n + r.criteriaTotals.verified, 0),
|
|
235
|
+
criteriaBroken: requirements.reduce((n, r) => n + r.criteriaTotals.broken, 0),
|
|
236
|
+
},
|
|
237
|
+
evidence: { criteriaMissingKind },
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Every in-scope criterion lacking its required evidence kind — the list
|
|
242
|
+
* `specship coverage` flags, as `{ specId, requiredKind, presentKinds }`. A
|
|
243
|
+
* requirement with no criteria stands in as its own single criterion.
|
|
244
|
+
*/
|
|
245
|
+
function criteriaMissingKind(report) {
|
|
246
|
+
const out = [];
|
|
247
|
+
for (const r of report.requirements) {
|
|
248
|
+
if (r.criteria.length > 0)
|
|
249
|
+
out.push(...r.criteria.filter((c) => !c.kindSatisfied));
|
|
250
|
+
else if (!r.kindSatisfied)
|
|
251
|
+
out.push(r);
|
|
252
|
+
}
|
|
253
|
+
return out;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Exit code for `specship coverage --require-kinds` (REQ-PIPETRUST-003.A2):
|
|
257
|
+
* non-zero when any in-scope criterion lacks its required kind, else zero.
|
|
258
|
+
* Without the flag the command never fails on kinds.
|
|
259
|
+
*/
|
|
260
|
+
function requireKindsExitCode(report, requireKinds) {
|
|
261
|
+
if (!requireKinds)
|
|
262
|
+
return 0;
|
|
263
|
+
return criteriaMissingKind(report).length > 0 ? 1 : 0;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* The single coverage line the implement workflow's human gate rests on
|
|
267
|
+
* (REQ-VSTATE-005.A2). Rendered here, from the same report `getSpecCoverage`
|
|
268
|
+
* returns, so the workflow's number and the API's number cannot disagree —
|
|
269
|
+
* previously an LLM counted it by eye.
|
|
270
|
+
*/
|
|
271
|
+
function formatCoverageLine(report) {
|
|
272
|
+
const subject = report.specId ?? 'the project';
|
|
273
|
+
const { criteriaWithTests, criteria } = report.totals;
|
|
274
|
+
return `${criteriaWithTests} of ${criteria} acceptance criteria for ${subject} have linked tests.`;
|
|
275
|
+
}
|
|
276
|
+
//# sourceMappingURL=spec-coverage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec-coverage.js","sourceRoot":"","sources":["../../src/graph/spec-coverage.ts"],"names":[],"mappings":"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"}
|
|
@@ -57,8 +57,8 @@ const path = __importStar(require("path"));
|
|
|
57
57
|
const child_process_1 = require("child_process");
|
|
58
58
|
const sqlite_adapter_1 = require("../db/sqlite-adapter");
|
|
59
59
|
const directory_1 = require("../directory");
|
|
60
|
-
const FTS5_REMEDIATION = '
|
|
61
|
-
'`npm install --save-dev better-sqlite3` so FTS5 works on a host Node built without it.';
|
|
60
|
+
const FTS5_REMEDIATION = 'Run on Node 24 (its built-in node:sqlite ships FTS5) or install better-sqlite3 ' +
|
|
61
|
+
'(`npm install --save-dev better-sqlite3`) so FTS5 works on a host Node built without it.';
|
|
62
62
|
/** Open a throwaway SQLite db, hand it to `fn`, then clean up the file + WAL/SHM. */
|
|
63
63
|
function withTempDb(fn) {
|
|
64
64
|
const tmp = path.join(os.tmpdir(), `specship-smoke-${process.pid}-${process.hrtime.bigint()}.db`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"smoke-check.js","sourceRoot":"","sources":["../../src/health/smoke-check.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkEH,oCAMC;AAGD,8BAUC;AAOD,oCA8CC;AAGD,kDAkBC;AAeD,sCAmDC;AAGD,wCAEC;AApOD,uCAAyB;AACzB,uCAAyB;AACzB,2CAA6B;AAC7B,iDAAsC;AACtC,yDAAsD;AACtD,4CAA6C;AA+B7C,MAAM,gBAAgB,GACpB,
|
|
1
|
+
{"version":3,"file":"smoke-check.js","sourceRoot":"","sources":["../../src/health/smoke-check.ts"],"names":[],"mappings":"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"}
|
package/lib/dist/index.d.ts
CHANGED
|
@@ -10,13 +10,15 @@ import { ResolutionResult } from './resolution';
|
|
|
10
10
|
import { SpecLinkResolver, SpecLinkResolverStats } from './resolution/spec-link-resolver';
|
|
11
11
|
import { SpecFunnel } from './resolution/brief-link-resolver';
|
|
12
12
|
import { DomainGapSeed } from './resolution/domain-gap-seed';
|
|
13
|
+
import { SpecCoverageReport } from './graph/spec-coverage';
|
|
14
|
+
import { VerifyReportResult } from './verify/report-ingest';
|
|
13
15
|
import { SpecQueries } from './db/spec-queries';
|
|
14
16
|
import { AnalyzeResult, SweepResult, Proposal, ProposalState, PreviewResult, ApplyOutcome, UndoOutcome } from './reflect';
|
|
15
17
|
import { RunEta } from './workflows/eta';
|
|
16
18
|
export type { RunEta, RunEtaAvailable, RunEtaUnavailable } from './workflows/eta';
|
|
17
19
|
import { MaintainabilityReport, MaintainabilityThresholds } from './graph/maintainability';
|
|
18
20
|
import { FitnessReport, FitnessRule } from './fitness/fitness';
|
|
19
|
-
import { EnforceConfig, EnforceReport } from './enforce/enforce';
|
|
21
|
+
import { EnforceConfig, EnforceReport, EnforceScope } from './enforce/enforce';
|
|
20
22
|
import { BehaviourSurface } from './behaviour/behaviour-surface';
|
|
21
23
|
import { FlowDiagramOptions, FlowDiagramResult } from './diagram/flow-diagram';
|
|
22
24
|
import { WatchOptions, PendingFile } from './sync';
|
|
@@ -30,6 +32,11 @@ export { ResolutionResult } from './resolution';
|
|
|
30
32
|
export { computeSpecFunnel, resolveBriefLink, summarizeBriefFunnel, findBriefsForSpec, } from './resolution/brief-link-resolver';
|
|
31
33
|
export type { SpecFunnel, SpecFunnelSummary, SpecFunnelDoc, BriefLink, BriefLinkState, BriefRollup, BriefFunnelEntry, } from './resolution/brief-link-resolver';
|
|
32
34
|
export { computeDomainGapSeed } from './resolution/domain-gap-seed';
|
|
35
|
+
export { computeSpecCoverage, formatCoverageLine, verdictFor, evidenceKindCoverage, criteriaMissingKind, requireKindsExitCode, } from './graph/spec-coverage';
|
|
36
|
+
export type { SpecCoverageReport, RequirementCoverage, CriterionCoverage, CoverageVerdict, LinkRollup, } from './graph/spec-coverage';
|
|
37
|
+
export { ingestTestReport, parseVitestJsonReport, caseMatchesLink, TestReportParseError, } from './verify/report-ingest';
|
|
38
|
+
export type { VerifyReportResult, ReportedTestCase, LinkOutcome } from './verify/report-ingest';
|
|
39
|
+
export { isRecognizedTestFile, isNonTestEvidence, scanTestTitleRefs } from './resolution/test-title-links';
|
|
33
40
|
export type { DomainGapSeed, GapSeedEntity, GapSeedSpec, DomainCoverage, } from './resolution/domain-gap-seed';
|
|
34
41
|
export { analyze as reflectAnalyze, sweep as reflectSweep, ReflectStore, previewProposal, applyProposal, undoProposal, } from './reflect';
|
|
35
42
|
export type { Proposal, ProposalType, ProposalSeverity, ProposalState, TargetKind, ProposalEvidence, ProposalPayload, PreviewResult, ApplyOutcome, UndoOutcome, ReflectContext, AnalyzeResult, SweepResult, } from './reflect';
|
|
@@ -37,10 +44,15 @@ export { computeMaintainability, resolveThresholds, resolveExclude, DEFAULT_THRE
|
|
|
37
44
|
export { collectFlows, renderMermaidFlowchart, writeFlowDiagramIfChanged, shouldAutoRefreshDiagram, resolveDiagramConfig, DEFAULT_DIAGRAM_OPTIONS } from './diagram/flow-diagram';
|
|
38
45
|
export type { FlowDiagramOptions, FlowDiagramConfig, FlowDiagramResult, FlowGraph } from './diagram/flow-diagram';
|
|
39
46
|
export { evaluateFitness, loadFitnessRules, FITNESS_CONFIG_FILE } from './fitness/fitness';
|
|
40
|
-
export { evaluateEnforcement, loadEnforceConfig, ENFORCE_CONFIG_FILE } from './enforce/enforce';
|
|
41
|
-
export {
|
|
47
|
+
export { evaluateEnforcement, loadEnforceConfig, ENFORCE_CONFIG_FILE, normalizePath } from './enforce/enforce';
|
|
48
|
+
export { changedFilesSince, InvalidRefError, workingTreeDiffText } from './enforce/changed-files';
|
|
49
|
+
export { scanDisableComments, formatSuppressionFinding } from './enforce/suppressions';
|
|
50
|
+
export type { SuppressionFinding } from './enforce/suppressions';
|
|
51
|
+
export { parseMutationReport, loadMutationDeps, DEFAULT_MUTATION_THRESHOLD, DEFAULT_MUTATION_REPORT } from './enforce/mutation';
|
|
52
|
+
export type { MutationConfig, MutationDeps, MutationFileStats } from './enforce/mutation';
|
|
53
|
+
export { computeBehaviourSurface, renderBehaviourSurface, isUiNode, classifyCriterionShape, propertyFramework } from './behaviour/behaviour-surface';
|
|
42
54
|
export type { BehaviourSurface, BehaviourFlowElement, BehaviourSurfaceDeps } from './behaviour/behaviour-surface';
|
|
43
|
-
export type { EnforceConfig, GateConfig, EnforceReport, EnforceDeps, CheckOutcome, CheckName, RequirementVerification, } from './enforce/enforce';
|
|
55
|
+
export type { EnforceConfig, GateConfig, EnforceReport, EnforceDeps, EnforceScope, CheckOutcome, CheckName, RequirementVerification, } from './enforce/enforce';
|
|
44
56
|
export type { FitnessRule, ForbiddenRule, LayersRule, IsolationRule, FitnessReport, FitnessViolation, FitnessConfigError, Selector, } from './fitness/fitness';
|
|
45
57
|
export type { MaintainabilityReport, MaintainabilityThresholds, CouplingFinding, OversizedFinding, GodFileFinding, CycleFinding, DeadCodeFinding, } from './graph/maintainability';
|
|
46
58
|
export { SpecShipError, FileError, ParseError, DatabaseError, SearchError, VectorError, ConfigError, Logger, setLogger, getLogger, silentLogger, defaultLogger, } from './errors';
|
|
@@ -107,6 +119,26 @@ export declare class SpecShip {
|
|
|
107
119
|
* package (it calls this on the dynamically-loaded SpecShip).
|
|
108
120
|
*/
|
|
109
121
|
getSpecFunnel(): SpecFunnel;
|
|
122
|
+
/**
|
|
123
|
+
* The spec coverage rollup (REQ-VSTATE-006): per requirement AND per
|
|
124
|
+
* acceptance criterion, the implements/tests link counts and states plus a
|
|
125
|
+
* verdict derived from `tests` links alone. Scoped to one spec id (a document
|
|
126
|
+
* expands to its requirements) or the whole project when omitted.
|
|
127
|
+
*
|
|
128
|
+
* Exposed on the instance so the MCP tool, the CLI and the desktop server all
|
|
129
|
+
* read the SAME numbers — the coverage line a human approves in the implement
|
|
130
|
+
* workflow is this function's output, not an LLM's count (REQ-VSTATE-005.A2).
|
|
131
|
+
*/
|
|
132
|
+
getSpecCoverage(specId?: string): SpecCoverageReport;
|
|
133
|
+
/**
|
|
134
|
+
* Ingest a test report (vitest JSON) and move `tests` links accordingly
|
|
135
|
+
* (REQ-VSTATE-004): a case that passed promotes its link to `verified` with
|
|
136
|
+
* the run recorded as evidence; a failure demotes it to `broken`. A malformed
|
|
137
|
+
* report throws {@link TestReportParseError} having changed nothing.
|
|
138
|
+
*/
|
|
139
|
+
verifyFromReport(reportPath: string, options?: {
|
|
140
|
+
runId?: string;
|
|
141
|
+
}): VerifyReportResult;
|
|
110
142
|
/**
|
|
111
143
|
* The domain gap-seed (REQ-DOMAIN-003): the structural code entities and
|
|
112
144
|
* non-domain specs that no domain fact yet covers, plus a coverage tally.
|
|
@@ -147,8 +179,12 @@ export declare class SpecShip {
|
|
|
147
179
|
* explicit override); with no config every check is advisory and the run
|
|
148
180
|
* passes. The behaviour chain reads `tests`-kind spec-links on each requirement
|
|
149
181
|
* and its acceptance criteria (verified = passing, broken = ran-and-failed).
|
|
182
|
+
*
|
|
183
|
+
* `scope` narrows the link-scoped checks to a set of changed files
|
|
184
|
+
* (REQ-AUTHG-006) — `specship check --since <ref>` supplies it. Omitted, the
|
|
185
|
+
* gate evaluates the whole repository exactly as before.
|
|
150
186
|
*/
|
|
151
|
-
getEnforce(config?: EnforceConfig): EnforceReport;
|
|
187
|
+
getEnforce(config?: EnforceConfig, scope?: EnforceScope): EnforceReport;
|
|
152
188
|
/**
|
|
153
189
|
* The behaviour surface for a requirement (REQ-BEHAVIOUR-001): its linked code
|
|
154
190
|
* plus the 1-hop route / component / handler neighbourhood, grouped UI vs
|
|
@@ -183,6 +219,7 @@ export declare class SpecShip {
|
|
|
183
219
|
reflectCapture(input: {
|
|
184
220
|
title: string;
|
|
185
221
|
content: string;
|
|
222
|
+
lane?: 'skill' | 'style' | 'domain';
|
|
186
223
|
}): Proposal;
|
|
187
224
|
/**
|
|
188
225
|
* Explicitly capture a lesson / anti-pattern as a human-gated `memory_rule`
|
|
@@ -263,11 +300,40 @@ export declare class SpecShip {
|
|
|
263
300
|
* errors and this wrapper guards the data-gathering too.
|
|
264
301
|
*/
|
|
265
302
|
private refreshStatuslineCache;
|
|
303
|
+
/**
|
|
304
|
+
* Re-extract ONE spec file without ever deleting the specs it still declares
|
|
305
|
+
* (REQ-VSTATE-001).
|
|
306
|
+
*
|
|
307
|
+
* `spec_links.spec_id` is `ON DELETE CASCADE`, so the delete-then-reinsert
|
|
308
|
+
* shape that spec indexing used to have destroyed every link the file did not
|
|
309
|
+
* re-declare — every agent-asserted `tests` link, every verification record —
|
|
310
|
+
* on any edit to any part of the file. Which also meant the sticky-state and
|
|
311
|
+
* spec-axis-drift machinery never ran on the real edit path: there was
|
|
312
|
+
* nothing left to transition.
|
|
313
|
+
*
|
|
314
|
+
* The fix is to make the destructive window not exist rather than to repair
|
|
315
|
+
* it afterwards: `insertSpec` upserts, so a surviving spec's row (and every
|
|
316
|
+
* link hanging off it) is never deleted, and `sweepRemovedSpecs` deletes only
|
|
317
|
+
* the ids the author actually removed (A3). Nothing is snapshotted, so
|
|
318
|
+
* nothing can be lost in a round-trip.
|
|
319
|
+
*
|
|
320
|
+
* Surviving specs keep their links, which makes the file's OWN declarations
|
|
321
|
+
* the other half of the contract: a `verifies:` / `implementations:` bullet
|
|
322
|
+
* the author deleted must take its link with it, or removing a declaration
|
|
323
|
+
* would silently mean nothing. `reconcileDeclaredLinks` drops exactly those —
|
|
324
|
+
* `spec-declaration` provenance only, never a link the file cannot re-create.
|
|
325
|
+
*
|
|
326
|
+
* The caller then applies the file's own declarations and runs the spec-axis
|
|
327
|
+
* drift rule over the surviving rows.
|
|
328
|
+
*/
|
|
329
|
+
private replaceSpecsForFile;
|
|
266
330
|
/**
|
|
267
331
|
* Internal spec indexing — does NOT take the indexMutex (caller already holds it)
|
|
268
332
|
* and does NOT take the fileLock. Used by indexAll and sync, which manage locks
|
|
269
333
|
* themselves. Returns the links that transitioned into `drifted` during the
|
|
270
|
-
* pass (spec-side and code-side) so sync can push them (REQ-DRIFT-PUSH-001)
|
|
334
|
+
* pass (spec-side and code-side) so sync can push them (REQ-DRIFT-PUSH-001),
|
|
335
|
+
* plus the extraction error/warning counts over the files it reparsed so the
|
|
336
|
+
* caller can surface them the way `indexSpecs` does (REQ-REVINT-002.A2).
|
|
271
337
|
*
|
|
272
338
|
* The per-file content-hash guard makes re-runs cheap; the comment-link scan
|
|
273
339
|
* + full link re-resolution at the end runs only when a spec file actually
|
|
@@ -284,7 +350,9 @@ export declare class SpecShip {
|
|
|
284
350
|
*
|
|
285
351
|
* Pipeline per file:
|
|
286
352
|
* 1. Hash file content; skip if `spec_files.content_hash` matches.
|
|
287
|
-
* 2.
|
|
353
|
+
* 2. Replace prior specs for this file, restoring their links afterwards
|
|
354
|
+
* (REQ-VSTATE-001) — only links of spec ids the file no longer declares
|
|
355
|
+
* are swept.
|
|
288
356
|
* 3. Run MarkdownSpecExtractor → insert specs + virtual node projections.
|
|
289
357
|
* 4. Apply `spec-declaration` link candidates from `implementations:`.
|
|
290
358
|
* 5. Mark previously-linked specs as drifted (drift_axis='spec') when
|