@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,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Small-plan auto-approval (THROUGHPUT-DOC, REQ-THRU-003).
|
|
4
|
+
*
|
|
5
|
+
* A plan may skip the human plan gate ONLY when the project opted in
|
|
6
|
+
* (`workflow.autoApproveSmallPlans: true` in specship.config.json), every
|
|
7
|
+
* source file it names is already one of the requirement's
|
|
8
|
+
* `implementations:` files, and the requirement has at most
|
|
9
|
+
* `workflow.smallPlanMaxCriteria` (default 3) acceptance criteria. Test files,
|
|
10
|
+
* the requirement's own spec file and CHANGELOG.md never count against the
|
|
11
|
+
* scope — a good plan always names them. The final review is never skipped.
|
|
12
|
+
*
|
|
13
|
+
* Deterministic and file-based, so it runs inside a workflow worktree. The
|
|
14
|
+
* AUTO_APPROVE=yes|no marker is the contract the approval step reads.
|
|
15
|
+
*/
|
|
16
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
19
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
20
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
21
|
+
}
|
|
22
|
+
Object.defineProperty(o, k2, desc);
|
|
23
|
+
}) : (function(o, m, k, k2) {
|
|
24
|
+
if (k2 === undefined) k2 = k;
|
|
25
|
+
o[k2] = m[k];
|
|
26
|
+
}));
|
|
27
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
28
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
29
|
+
}) : function(o, v) {
|
|
30
|
+
o["default"] = v;
|
|
31
|
+
});
|
|
32
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
33
|
+
var ownKeys = function(o) {
|
|
34
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
35
|
+
var ar = [];
|
|
36
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
37
|
+
return ar;
|
|
38
|
+
};
|
|
39
|
+
return ownKeys(o);
|
|
40
|
+
};
|
|
41
|
+
return function (mod) {
|
|
42
|
+
if (mod && mod.__esModule) return mod;
|
|
43
|
+
var result = {};
|
|
44
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
45
|
+
__setModuleDefault(result, mod);
|
|
46
|
+
return result;
|
|
47
|
+
};
|
|
48
|
+
})();
|
|
49
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
+
exports.DEFAULT_SMALL_PLAN_MAX_CRITERIA = void 0;
|
|
51
|
+
exports.filesNamedInPlan = filesNamedInPlan;
|
|
52
|
+
exports.assessPlanScope = assessPlanScope;
|
|
53
|
+
exports.assessPlanScopeFromFile = assessPlanScopeFromFile;
|
|
54
|
+
exports.formatPlanScope = formatPlanScope;
|
|
55
|
+
const fs = __importStar(require("fs"));
|
|
56
|
+
const path = __importStar(require("path"));
|
|
57
|
+
const postcheck_1 = require("./postcheck");
|
|
58
|
+
exports.DEFAULT_SMALL_PLAN_MAX_CRITERIA = 3;
|
|
59
|
+
// A trailing full stop/!/? ends a sentence, not the path — a plan naming an
|
|
60
|
+
// out-of-scope file at the end of a sentence must still be caught.
|
|
61
|
+
const PATH_TOKEN = /(?:^|[\s`'"(\[])((?:\.{0,2}\/)?[A-Za-z0-9_@.-]+(?:\/[A-Za-z0-9_@.-]+)*\.[A-Za-z0-9]{1,6})(?=[\s`'")\]:,;.!?]|$)/g;
|
|
62
|
+
const TEST_FILE = /(^|\/)(__tests__|tests?|e2e|spec)\/|\.(test|spec)\.[A-Za-z0-9]+$/;
|
|
63
|
+
/** Project-relative file paths a plan names (deduplicated, in order). */
|
|
64
|
+
function filesNamedInPlan(planText) {
|
|
65
|
+
const out = [];
|
|
66
|
+
for (const m of planText.matchAll(PATH_TOKEN)) {
|
|
67
|
+
const p = m[1].replace(/^\.\//, '');
|
|
68
|
+
if (!p.includes('/') && !/^[A-Z][A-Za-z]+\.md$/.test(p))
|
|
69
|
+
continue; // bare words like "e.g." are not files
|
|
70
|
+
if (/^\d+(\.\d+)+$/.test(p) || /^https?:/.test(p))
|
|
71
|
+
continue;
|
|
72
|
+
if (!out.includes(p))
|
|
73
|
+
out.push(p);
|
|
74
|
+
}
|
|
75
|
+
return out;
|
|
76
|
+
}
|
|
77
|
+
function assessPlanScope(input) {
|
|
78
|
+
const maxCriteria = input.maxCriteria ?? exports.DEFAULT_SMALL_PLAN_MAX_CRITERIA;
|
|
79
|
+
const reasons = [];
|
|
80
|
+
if (!input.optIn) {
|
|
81
|
+
return { autoApprove: false, reasons: ['workflow.autoApproveSmallPlans is not enabled'], outOfScope: [] };
|
|
82
|
+
}
|
|
83
|
+
if (input.criteriaCount > maxCriteria) {
|
|
84
|
+
reasons.push(`requirement has ${input.criteriaCount} criteria (limit ${maxCriteria})`);
|
|
85
|
+
}
|
|
86
|
+
const allowed = new Set(input.implementationFiles);
|
|
87
|
+
const named = filesNamedInPlan(input.planText);
|
|
88
|
+
const outOfScope = named.filter((f) => !allowed.has(f) && !TEST_FILE.test(f) && f !== 'CHANGELOG.md' && f !== input.specFile);
|
|
89
|
+
if (outOfScope.length > 0)
|
|
90
|
+
reasons.push(`plan names files outside implementations: ${outOfScope.join(', ')}`);
|
|
91
|
+
if (named.filter((f) => allowed.has(f)).length === 0) {
|
|
92
|
+
reasons.push('plan names none of the requirement\'s implementation files');
|
|
93
|
+
}
|
|
94
|
+
return { autoApprove: reasons.length === 0, reasons, outOfScope };
|
|
95
|
+
}
|
|
96
|
+
function readWorkflowConfig(projectRoot) {
|
|
97
|
+
try {
|
|
98
|
+
const cfg = JSON.parse(fs.readFileSync(path.join(projectRoot, 'specship.config.json'), 'utf8'));
|
|
99
|
+
return (cfg && typeof cfg.workflow === 'object' && cfg.workflow) || {};
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
return {};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/** File-based loader: reads the requirement block and the project's opt-in. */
|
|
106
|
+
function assessPlanScopeFromFile(projectRoot, requirementId, planText) {
|
|
107
|
+
const cfg = readWorkflowConfig(projectRoot);
|
|
108
|
+
const specFile = (0, postcheck_1.findSpecFile)(projectRoot, requirementId);
|
|
109
|
+
const block = specFile ? (0, postcheck_1.requirementBlock)(fs.readFileSync(specFile, 'utf8'), requirementId) : null;
|
|
110
|
+
if (!specFile || !block) {
|
|
111
|
+
return { autoApprove: false, reasons: [`no spec block for ${requirementId}`], outOfScope: [] };
|
|
112
|
+
}
|
|
113
|
+
const implementationFiles = (0, postcheck_1.linkBullets)(block, 'implementations').map((b) => {
|
|
114
|
+
const idx = b.lastIndexOf(':');
|
|
115
|
+
return idx > 0 ? b.slice(0, idx) : b;
|
|
116
|
+
});
|
|
117
|
+
return assessPlanScope({
|
|
118
|
+
planText,
|
|
119
|
+
implementationFiles,
|
|
120
|
+
criteriaCount: (0, postcheck_1.criterionIds)(block, requirementId).length,
|
|
121
|
+
optIn: cfg.autoApproveSmallPlans === true,
|
|
122
|
+
maxCriteria: typeof cfg.smallPlanMaxCriteria === 'number' ? cfg.smallPlanMaxCriteria : undefined,
|
|
123
|
+
specFile: path.relative(projectRoot, specFile),
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
function formatPlanScope(result) {
|
|
127
|
+
return [`AUTO_APPROVE=${result.autoApprove ? 'yes' : 'no'}`, ...result.reasons.map((r) => `- ${r}`)].join('\n');
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=plan-scope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-scope.js","sourceRoot":"","sources":["../../src/spec-quality/plan-scope.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mechanical post-implement checks (PIPETRUST-DOC, REQ-PIPETRUST-005).
|
|
3
|
+
*
|
|
4
|
+
* On 2026-10-26 every `spec-implement` run needed a human to finish it, for
|
|
5
|
+
* reasons a script can see: test evidence linked by `it()` title strings (no
|
|
6
|
+
* edge, so the requirement could never reach `verified`), criteria with no
|
|
7
|
+
* test, source changes with no CHANGELOG entry, generated reference docs not
|
|
8
|
+
* regenerated. Postcheck checks those mechanically after implement so the
|
|
9
|
+
* workflow can fix them before a human ever looks.
|
|
10
|
+
*
|
|
11
|
+
* File-based by design: it runs inside a workflow worktree, which has no
|
|
12
|
+
* SpecShip index, so it reads the spec file and the test files directly.
|
|
13
|
+
*
|
|
14
|
+
* 1. `verifies:` coverage — every bullet is `path:Symbol` with a real,
|
|
15
|
+
* space-free symbol defined in the test file; every acceptance criterion
|
|
16
|
+
* id appears in at least one of those test files.
|
|
17
|
+
* 2. CHANGELOG — when files under `src/` changed against the base ref, the
|
|
18
|
+
* `## [Unreleased]` section of CHANGELOG.md changed too.
|
|
19
|
+
* 3. Project checks — each `postcheck.commands` entry in specship.config.json
|
|
20
|
+
* (`{ name, check, fix? }`); with `fix`, the fix command runs first.
|
|
21
|
+
*/
|
|
22
|
+
export interface PostcheckFinding {
|
|
23
|
+
check: 'verifies' | 'changelog' | 'command' | 'knowledge' | 'mutation';
|
|
24
|
+
message: string;
|
|
25
|
+
}
|
|
26
|
+
export interface PostcheckResult {
|
|
27
|
+
ok: boolean;
|
|
28
|
+
findings: PostcheckFinding[];
|
|
29
|
+
/** One line per check that ran, for the report. */
|
|
30
|
+
ran: string[];
|
|
31
|
+
}
|
|
32
|
+
export interface PostcheckCommand {
|
|
33
|
+
name: string;
|
|
34
|
+
check: string;
|
|
35
|
+
fix?: string;
|
|
36
|
+
}
|
|
37
|
+
export interface PostcheckOptions {
|
|
38
|
+
projectRoot: string;
|
|
39
|
+
requirementId: string;
|
|
40
|
+
/** Run each configured command's `fix` before its `check`. */
|
|
41
|
+
fix?: boolean;
|
|
42
|
+
/** Base ref for the CHANGELOG check; defaults to the recorded run base, then the merge-base with the default branch. */
|
|
43
|
+
base?: string;
|
|
44
|
+
/** Inject command execution (tests). Returns the exit code. */
|
|
45
|
+
run?: (command: string, cwd: string) => {
|
|
46
|
+
code: number;
|
|
47
|
+
output: string;
|
|
48
|
+
};
|
|
49
|
+
/** Inject git diff lookups (tests). */
|
|
50
|
+
changedFiles?: (base: string) => string[];
|
|
51
|
+
/** Inject the base CHANGELOG content (tests). */
|
|
52
|
+
baseFile?: (base: string, relPath: string) => string | null;
|
|
53
|
+
}
|
|
54
|
+
/** The requirement's block of the spec file: from its id marker to the next requirement-level marker. */
|
|
55
|
+
export declare function requirementBlock(source: string, requirementId: string): string | null;
|
|
56
|
+
/** Acceptance criterion ids declared under the requirement. */
|
|
57
|
+
export declare function criterionIds(block: string, requirementId: string): string[];
|
|
58
|
+
/** Bullets of a `<name>:` link block inside the requirement block. */
|
|
59
|
+
export declare function linkBullets(block: string, blockName: 'verifies' | 'implementations'): string[];
|
|
60
|
+
/** REQ-PIPETRUST-005.A1/A2 — `verifies:` bullets are real named test symbols and cover every criterion. */
|
|
61
|
+
export declare function checkVerifiesCoverage(projectRoot: string, specSource: string, requirementId: string): PostcheckFinding[];
|
|
62
|
+
/** The `## [Unreleased]` section of a CHANGELOG, or '' when absent. */
|
|
63
|
+
export declare function unreleasedSection(changelog: string): string;
|
|
64
|
+
/** Base ref: explicit, else the run base the readiness step recorded, else merge-base with the default branch. */
|
|
65
|
+
export declare function resolveBaseRef(projectRoot: string, explicit?: string): string | null;
|
|
66
|
+
/** REQ-PIPETRUST-005.A3 — source changes need a CHANGELOG [Unreleased] change. */
|
|
67
|
+
export declare function checkChangelog(opts: PostcheckOptions): PostcheckFinding[];
|
|
68
|
+
/** `postcheck.commands` from specship.config.json (empty when absent or malformed). */
|
|
69
|
+
export declare function readPostcheckCommands(projectRoot: string): PostcheckCommand[];
|
|
70
|
+
/** REQ-PIPETRUST-005.A4 — configured check commands, fix first when asked. */
|
|
71
|
+
export declare function checkConfiguredCommands(opts: PostcheckOptions, ran: string[]): PostcheckFinding[];
|
|
72
|
+
/**
|
|
73
|
+
* REQ-THRU-010 — when `enforce.mutation` is configured, the requirement's
|
|
74
|
+
* implementation files must clear the mutant kill-rate threshold in the
|
|
75
|
+
* project's mutation report. Without configuration the check does not exist;
|
|
76
|
+
* an unreadable report is reported as skipped (never a pass, never a failure),
|
|
77
|
+
* matching the enforcement gate (REQ-QGATE-002.A3).
|
|
78
|
+
*/
|
|
79
|
+
export declare function checkMutation(opts: PostcheckOptions, specFile: string | null, ran: string[]): PostcheckFinding[];
|
|
80
|
+
/** Locate the spec file declaring `requirementId` under specs/. */
|
|
81
|
+
export declare function findSpecFile(projectRoot: string, requirementId: string): string | null;
|
|
82
|
+
export declare function runPostcheck(opts: PostcheckOptions): PostcheckResult;
|
|
83
|
+
/** Marker-led rendering; POSTCHECK=passed|failed is the workflow contract. */
|
|
84
|
+
export declare function formatPostcheck(result: PostcheckResult): string;
|
|
85
|
+
//# sourceMappingURL=postcheck.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postcheck.d.ts","sourceRoot":"","sources":["../../src/spec-quality/postcheck.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Mechanical post-implement checks (PIPETRUST-DOC, REQ-PIPETRUST-005).
|
|
4
|
+
*
|
|
5
|
+
* On 2026-10-26 every `spec-implement` run needed a human to finish it, for
|
|
6
|
+
* reasons a script can see: test evidence linked by `it()` title strings (no
|
|
7
|
+
* edge, so the requirement could never reach `verified`), criteria with no
|
|
8
|
+
* test, source changes with no CHANGELOG entry, generated reference docs not
|
|
9
|
+
* regenerated. Postcheck checks those mechanically after implement so the
|
|
10
|
+
* workflow can fix them before a human ever looks.
|
|
11
|
+
*
|
|
12
|
+
* File-based by design: it runs inside a workflow worktree, which has no
|
|
13
|
+
* SpecShip index, so it reads the spec file and the test files directly.
|
|
14
|
+
*
|
|
15
|
+
* 1. `verifies:` coverage — every bullet is `path:Symbol` with a real,
|
|
16
|
+
* space-free symbol defined in the test file; every acceptance criterion
|
|
17
|
+
* id appears in at least one of those test files.
|
|
18
|
+
* 2. CHANGELOG — when files under `src/` changed against the base ref, the
|
|
19
|
+
* `## [Unreleased]` section of CHANGELOG.md changed too.
|
|
20
|
+
* 3. Project checks — each `postcheck.commands` entry in specship.config.json
|
|
21
|
+
* (`{ name, check, fix? }`); with `fix`, the fix command runs first.
|
|
22
|
+
*/
|
|
23
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
24
|
+
if (k2 === undefined) k2 = k;
|
|
25
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
26
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
27
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
28
|
+
}
|
|
29
|
+
Object.defineProperty(o, k2, desc);
|
|
30
|
+
}) : (function(o, m, k, k2) {
|
|
31
|
+
if (k2 === undefined) k2 = k;
|
|
32
|
+
o[k2] = m[k];
|
|
33
|
+
}));
|
|
34
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
35
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
36
|
+
}) : function(o, v) {
|
|
37
|
+
o["default"] = v;
|
|
38
|
+
});
|
|
39
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
40
|
+
var ownKeys = function(o) {
|
|
41
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
42
|
+
var ar = [];
|
|
43
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
44
|
+
return ar;
|
|
45
|
+
};
|
|
46
|
+
return ownKeys(o);
|
|
47
|
+
};
|
|
48
|
+
return function (mod) {
|
|
49
|
+
if (mod && mod.__esModule) return mod;
|
|
50
|
+
var result = {};
|
|
51
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
52
|
+
__setModuleDefault(result, mod);
|
|
53
|
+
return result;
|
|
54
|
+
};
|
|
55
|
+
})();
|
|
56
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
57
|
+
exports.requirementBlock = requirementBlock;
|
|
58
|
+
exports.criterionIds = criterionIds;
|
|
59
|
+
exports.linkBullets = linkBullets;
|
|
60
|
+
exports.checkVerifiesCoverage = checkVerifiesCoverage;
|
|
61
|
+
exports.unreleasedSection = unreleasedSection;
|
|
62
|
+
exports.resolveBaseRef = resolveBaseRef;
|
|
63
|
+
exports.checkChangelog = checkChangelog;
|
|
64
|
+
exports.readPostcheckCommands = readPostcheckCommands;
|
|
65
|
+
exports.checkConfiguredCommands = checkConfiguredCommands;
|
|
66
|
+
exports.checkMutation = checkMutation;
|
|
67
|
+
exports.findSpecFile = findSpecFile;
|
|
68
|
+
exports.runPostcheck = runPostcheck;
|
|
69
|
+
exports.formatPostcheck = formatPostcheck;
|
|
70
|
+
const fs = __importStar(require("fs"));
|
|
71
|
+
const path = __importStar(require("path"));
|
|
72
|
+
const child_process_1 = require("child_process");
|
|
73
|
+
const enforce_1 = require("../knowledge/enforce");
|
|
74
|
+
const criterion_ids_1 = require("./criterion-ids");
|
|
75
|
+
const enforce_2 = require("../enforce/enforce");
|
|
76
|
+
const mutation_1 = require("../enforce/mutation");
|
|
77
|
+
const ID_MARKER = /^<!--\s*id:\s*([A-Za-z0-9._-]+)\s*-->\s*$/;
|
|
78
|
+
/** The requirement's block of the spec file: from its id marker to the next requirement-level marker. */
|
|
79
|
+
function requirementBlock(source, requirementId) {
|
|
80
|
+
const lines = source.split(/\r?\n/);
|
|
81
|
+
let start = -1;
|
|
82
|
+
for (let i = 0; i < lines.length; i++) {
|
|
83
|
+
const m = (lines[i] ?? '').match(ID_MARKER);
|
|
84
|
+
if (!m)
|
|
85
|
+
continue;
|
|
86
|
+
if (start === -1) {
|
|
87
|
+
if (m[1] === requirementId)
|
|
88
|
+
start = i;
|
|
89
|
+
}
|
|
90
|
+
else if (!m[1].startsWith(`${requirementId}.`)) {
|
|
91
|
+
return lines.slice(start, i).join('\n');
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return start === -1 ? null : lines.slice(start).join('\n');
|
|
95
|
+
}
|
|
96
|
+
/** Acceptance criterion ids declared under the requirement. */
|
|
97
|
+
function criterionIds(block, requirementId) {
|
|
98
|
+
const ids = [];
|
|
99
|
+
for (const line of block.split(/\r?\n/)) {
|
|
100
|
+
const m = line.match(ID_MARKER);
|
|
101
|
+
if (m && m[1].startsWith(`${requirementId}.A`))
|
|
102
|
+
ids.push(m[1]);
|
|
103
|
+
}
|
|
104
|
+
return ids;
|
|
105
|
+
}
|
|
106
|
+
/** Bullets of a `<name>:` link block inside the requirement block. */
|
|
107
|
+
function linkBullets(block, blockName) {
|
|
108
|
+
const lines = block.split(/\r?\n/);
|
|
109
|
+
const out = [];
|
|
110
|
+
let inBlock = false;
|
|
111
|
+
for (const line of lines) {
|
|
112
|
+
if (new RegExp(`^${blockName}:\\s*$`).test(line.trim()) && !/^\s/.test(line)) {
|
|
113
|
+
inBlock = true;
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
if (!inBlock)
|
|
117
|
+
continue;
|
|
118
|
+
const m = line.match(/^\s+-\s+(.+?)\s*$/);
|
|
119
|
+
if (m) {
|
|
120
|
+
out.push(m[1]);
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
if (line.trim() === '')
|
|
124
|
+
continue;
|
|
125
|
+
inBlock = false;
|
|
126
|
+
}
|
|
127
|
+
return out;
|
|
128
|
+
}
|
|
129
|
+
function symbolDefined(source, symbol) {
|
|
130
|
+
const s = symbol.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
131
|
+
return new RegExp(`\\b(function\\*?|const|let|var|class|def|fn|func)\\s+${s}\\b|\\b${s}\\s*[:=]\\s*(async\\s+)?(function|\\()`).test(source);
|
|
132
|
+
}
|
|
133
|
+
/** REQ-PIPETRUST-005.A1/A2 — `verifies:` bullets are real named test symbols and cover every criterion. */
|
|
134
|
+
function checkVerifiesCoverage(projectRoot, specSource, requirementId) {
|
|
135
|
+
const findings = [];
|
|
136
|
+
const block = requirementBlock(specSource, requirementId);
|
|
137
|
+
if (!block)
|
|
138
|
+
return [{ check: 'verifies', message: `${requirementId} not found in its spec file` }];
|
|
139
|
+
const testSources = [];
|
|
140
|
+
for (const bullet of linkBullets(block, 'verifies')) {
|
|
141
|
+
const idx = bullet.lastIndexOf(':');
|
|
142
|
+
const file = idx > 0 ? bullet.slice(0, idx) : bullet;
|
|
143
|
+
const symbol = idx > 0 ? bullet.slice(idx + 1) : '';
|
|
144
|
+
if (!symbol) {
|
|
145
|
+
findings.push({ check: 'verifies', message: `verifies bullet "${bullet}" names no symbol (use path:Symbol)` });
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
if (/\s/.test(symbol)) {
|
|
149
|
+
findings.push({
|
|
150
|
+
check: 'verifies',
|
|
151
|
+
message: `verifies bullet "${bullet}" names a title string, not a symbol — pass a named function to it() and list that name`,
|
|
152
|
+
});
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
let source;
|
|
156
|
+
try {
|
|
157
|
+
source = fs.readFileSync(path.join(projectRoot, file), 'utf-8');
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
findings.push({ check: 'verifies', message: `verifies bullet "${bullet}": file ${file} not found` });
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
if (!symbolDefined(source, symbol)) {
|
|
164
|
+
findings.push({ check: 'verifies', message: `verifies bullet "${bullet}": no symbol ${symbol} defined in ${file}` });
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
testSources.push(source);
|
|
168
|
+
}
|
|
169
|
+
// Whole-id match with shorthand expanded: `REQ-X.A1/A3` covers A3, and
|
|
170
|
+
// `REQ-X.A10` never counts for A1 (REQ-PIPETRUST-008).
|
|
171
|
+
const named = new Set(testSources.flatMap((src) => (0, criterion_ids_1.criterionIdsInText)(src)));
|
|
172
|
+
for (const id of criterionIds(block, requirementId)) {
|
|
173
|
+
if (!named.has(id)) {
|
|
174
|
+
findings.push({
|
|
175
|
+
check: 'verifies',
|
|
176
|
+
message: `${id} has no test evidence — no verifies-listed test file mentions it (put the id in the it() title)`,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return findings;
|
|
181
|
+
}
|
|
182
|
+
/** The `## [Unreleased]` section of a CHANGELOG, or '' when absent. */
|
|
183
|
+
function unreleasedSection(changelog) {
|
|
184
|
+
const start = changelog.indexOf('## [Unreleased]');
|
|
185
|
+
if (start === -1)
|
|
186
|
+
return '';
|
|
187
|
+
const next = changelog.indexOf('\n## [', start + 1);
|
|
188
|
+
return changelog.slice(start, next === -1 ? undefined : next);
|
|
189
|
+
}
|
|
190
|
+
function git(cwd, args) {
|
|
191
|
+
return (0, child_process_1.execSync)(`git ${args}`, { cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();
|
|
192
|
+
}
|
|
193
|
+
/** Base ref: explicit, else the run base the readiness step recorded, else merge-base with the default branch. */
|
|
194
|
+
function resolveBaseRef(projectRoot, explicit) {
|
|
195
|
+
if (explicit)
|
|
196
|
+
return explicit;
|
|
197
|
+
try {
|
|
198
|
+
const gitDir = git(projectRoot, 'rev-parse --git-dir');
|
|
199
|
+
const recorded = path.join(path.isAbsolute(gitDir) ? gitDir : path.join(projectRoot, gitDir), 'specship-run-base');
|
|
200
|
+
if (fs.existsSync(recorded)) {
|
|
201
|
+
const ref = fs.readFileSync(recorded, 'utf8').trim();
|
|
202
|
+
if (ref)
|
|
203
|
+
return ref;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
catch {
|
|
207
|
+
/* not a git repo — fall through */
|
|
208
|
+
}
|
|
209
|
+
for (const candidate of ['origin/main', 'main', 'origin/master', 'master']) {
|
|
210
|
+
try {
|
|
211
|
+
return git(projectRoot, `merge-base HEAD ${candidate}`);
|
|
212
|
+
}
|
|
213
|
+
catch {
|
|
214
|
+
/* try the next */
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
219
|
+
/** REQ-PIPETRUST-005.A3 — source changes need a CHANGELOG [Unreleased] change. */
|
|
220
|
+
function checkChangelog(opts) {
|
|
221
|
+
const base = resolveBaseRef(opts.projectRoot, opts.base);
|
|
222
|
+
if (!base)
|
|
223
|
+
return [];
|
|
224
|
+
const changed = opts.changedFiles?.(base) ??
|
|
225
|
+
git(opts.projectRoot, `diff --name-only ${base}`).split('\n').filter(Boolean);
|
|
226
|
+
if (!changed.some((f) => f.startsWith('src/')))
|
|
227
|
+
return [];
|
|
228
|
+
const changelogPath = path.join(opts.projectRoot, 'CHANGELOG.md');
|
|
229
|
+
if (!fs.existsSync(changelogPath))
|
|
230
|
+
return [];
|
|
231
|
+
const now = unreleasedSection(fs.readFileSync(changelogPath, 'utf8'));
|
|
232
|
+
let before;
|
|
233
|
+
if (opts.baseFile)
|
|
234
|
+
before = opts.baseFile(base, 'CHANGELOG.md');
|
|
235
|
+
else {
|
|
236
|
+
try {
|
|
237
|
+
before = git(opts.projectRoot, `show ${base}:CHANGELOG.md`);
|
|
238
|
+
}
|
|
239
|
+
catch {
|
|
240
|
+
before = null;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
if (before !== null && unreleasedSection(before) === now) {
|
|
244
|
+
return [
|
|
245
|
+
{
|
|
246
|
+
check: 'changelog',
|
|
247
|
+
message: 'files under src/ changed but CHANGELOG.md ## [Unreleased] did not — add a user-facing entry',
|
|
248
|
+
},
|
|
249
|
+
];
|
|
250
|
+
}
|
|
251
|
+
return [];
|
|
252
|
+
}
|
|
253
|
+
/** `postcheck.commands` from specship.config.json (empty when absent or malformed). */
|
|
254
|
+
function readPostcheckCommands(projectRoot) {
|
|
255
|
+
try {
|
|
256
|
+
const cfg = JSON.parse(fs.readFileSync(path.join(projectRoot, 'specship.config.json'), 'utf8'));
|
|
257
|
+
const cmds = cfg?.postcheck?.commands;
|
|
258
|
+
if (!Array.isArray(cmds))
|
|
259
|
+
return [];
|
|
260
|
+
return cmds.filter((c) => !!c && typeof c.name === 'string' && typeof c.check === 'string');
|
|
261
|
+
}
|
|
262
|
+
catch {
|
|
263
|
+
return [];
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
function defaultRun(command, cwd) {
|
|
267
|
+
const r = (0, child_process_1.spawnSync)('bash', ['-c', command], { cwd, encoding: 'utf8' });
|
|
268
|
+
return { code: r.status ?? 1, output: `${r.stdout ?? ''}${r.stderr ?? ''}` };
|
|
269
|
+
}
|
|
270
|
+
/** REQ-PIPETRUST-005.A4 — configured check commands, fix first when asked. */
|
|
271
|
+
function checkConfiguredCommands(opts, ran) {
|
|
272
|
+
const run = opts.run ?? defaultRun;
|
|
273
|
+
const findings = [];
|
|
274
|
+
for (const cmd of readPostcheckCommands(opts.projectRoot)) {
|
|
275
|
+
if (opts.fix && cmd.fix)
|
|
276
|
+
run(cmd.fix, opts.projectRoot);
|
|
277
|
+
const res = run(cmd.check, opts.projectRoot);
|
|
278
|
+
ran.push(`command ${cmd.name}: ${res.code === 0 ? 'ok' : 'failed'}`);
|
|
279
|
+
if (res.code !== 0) {
|
|
280
|
+
findings.push({
|
|
281
|
+
check: 'command',
|
|
282
|
+
message: `${cmd.name} failed (${cmd.check})${cmd.fix ? '' : ' — no fix configured'}:\n${res.output.trim().split('\n').slice(-15).join('\n')}`,
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
return findings;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* REQ-THRU-010 — when `enforce.mutation` is configured, the requirement's
|
|
290
|
+
* implementation files must clear the mutant kill-rate threshold in the
|
|
291
|
+
* project's mutation report. Without configuration the check does not exist;
|
|
292
|
+
* an unreadable report is reported as skipped (never a pass, never a failure),
|
|
293
|
+
* matching the enforcement gate (REQ-QGATE-002.A3).
|
|
294
|
+
*/
|
|
295
|
+
function checkMutation(opts, specFile, ran) {
|
|
296
|
+
const cfg = (0, enforce_2.loadEnforceConfig)(opts.projectRoot);
|
|
297
|
+
if (cfg.mutation === undefined)
|
|
298
|
+
return [];
|
|
299
|
+
const deps = (0, mutation_1.loadMutationDeps)(opts.projectRoot, cfg.mutation);
|
|
300
|
+
if (deps.stats === null) {
|
|
301
|
+
ran.push(`mutation: skipped — ${deps.reason ?? 'no report'}`);
|
|
302
|
+
return [];
|
|
303
|
+
}
|
|
304
|
+
const block = specFile ? requirementBlock(fs.readFileSync(specFile, 'utf8'), opts.requirementId) : null;
|
|
305
|
+
const files = new Set((block ? linkBullets(block, 'implementations') : []).map((b) => {
|
|
306
|
+
const idx = b.lastIndexOf(':');
|
|
307
|
+
return (idx > 0 ? b.slice(0, idx) : b).replace(/\\/g, '/');
|
|
308
|
+
}));
|
|
309
|
+
const findings = [];
|
|
310
|
+
const pct = (n) => `${Math.round(n * 100)}%`;
|
|
311
|
+
for (const file of files) {
|
|
312
|
+
const st = deps.stats.get(file);
|
|
313
|
+
if (!st || st.total === 0)
|
|
314
|
+
continue;
|
|
315
|
+
const rate = st.killed / st.total;
|
|
316
|
+
if (rate < deps.threshold) {
|
|
317
|
+
findings.push({
|
|
318
|
+
check: 'mutation',
|
|
319
|
+
message: `${file} mutant kill rate ${pct(rate)} < ${pct(deps.threshold)} threshold (${st.killed}/${st.total} killed) — the tests would not notice this code breaking`,
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
ran.push(`mutation: ${findings.length === 0 ? 'ok' : `${findings.length} weak file(s)`} (threshold ${pct(deps.threshold)})`);
|
|
324
|
+
return findings;
|
|
325
|
+
}
|
|
326
|
+
/** Locate the spec file declaring `requirementId` under specs/. */
|
|
327
|
+
function findSpecFile(projectRoot, requirementId) {
|
|
328
|
+
const marker = `<!-- id: ${requirementId} -->`;
|
|
329
|
+
const walk = (dir) => {
|
|
330
|
+
let entries;
|
|
331
|
+
try {
|
|
332
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
333
|
+
}
|
|
334
|
+
catch {
|
|
335
|
+
return null;
|
|
336
|
+
}
|
|
337
|
+
for (const e of entries) {
|
|
338
|
+
const p = path.join(dir, e.name);
|
|
339
|
+
if (e.isDirectory()) {
|
|
340
|
+
const hit = walk(p);
|
|
341
|
+
if (hit)
|
|
342
|
+
return hit;
|
|
343
|
+
}
|
|
344
|
+
else if (e.name.endsWith('.md') && fs.readFileSync(p, 'utf8').includes(marker)) {
|
|
345
|
+
return p;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
return null;
|
|
349
|
+
};
|
|
350
|
+
return walk(path.join(projectRoot, 'specs'));
|
|
351
|
+
}
|
|
352
|
+
function runPostcheck(opts) {
|
|
353
|
+
const ran = [];
|
|
354
|
+
const findings = [];
|
|
355
|
+
const specFile = findSpecFile(opts.projectRoot, opts.requirementId);
|
|
356
|
+
if (!specFile) {
|
|
357
|
+
findings.push({ check: 'verifies', message: `no spec file under specs/ declares ${opts.requirementId}` });
|
|
358
|
+
}
|
|
359
|
+
else {
|
|
360
|
+
const f = checkVerifiesCoverage(opts.projectRoot, fs.readFileSync(specFile, 'utf8'), opts.requirementId);
|
|
361
|
+
ran.push(`verifies coverage: ${f.length === 0 ? 'ok' : `${f.length} finding(s)`}`);
|
|
362
|
+
findings.push(...f);
|
|
363
|
+
}
|
|
364
|
+
const c = checkChangelog(opts);
|
|
365
|
+
ran.push(`changelog: ${c.length === 0 ? 'ok' : 'missing entry'}`);
|
|
366
|
+
findings.push(...c);
|
|
367
|
+
findings.push(...checkConfiguredCommands(opts, ran));
|
|
368
|
+
// REQ-THRU-010 — the mutation gate, when the project configured one.
|
|
369
|
+
findings.push(...checkMutation(opts, specFile, ran));
|
|
370
|
+
// REQ-KNOW-003.A4 — enforced domain-fact rules are a built-in check.
|
|
371
|
+
const enforced = (0, enforce_1.checkEnforcedRules)(opts.projectRoot);
|
|
372
|
+
if (enforced.rulesChecked > 0) {
|
|
373
|
+
ran.push(`knowledge check: ${enforced.violations.length === 0 ? 'ok' : `${enforced.violations.length} violation(s)`} (${enforced.rulesChecked} enforced rule(s))`);
|
|
374
|
+
}
|
|
375
|
+
for (const v of enforced.violations) {
|
|
376
|
+
findings.push({
|
|
377
|
+
check: 'knowledge',
|
|
378
|
+
message: `${v.file}:${v.line} violates ${v.factId} (${v.rule}): ${v.text.trim()}`,
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
return { ok: findings.length === 0, findings, ran };
|
|
382
|
+
}
|
|
383
|
+
/** Marker-led rendering; POSTCHECK=passed|failed is the workflow contract. */
|
|
384
|
+
function formatPostcheck(result) {
|
|
385
|
+
const lines = [`POSTCHECK=${result.ok ? 'passed' : 'failed'}`, ...result.ran.map((r) => `- ${r}`)];
|
|
386
|
+
for (const f of result.findings)
|
|
387
|
+
lines.push(`✗ [${f.check}] ${f.message}`);
|
|
388
|
+
return lines.join('\n');
|
|
389
|
+
}
|
|
390
|
+
//# sourceMappingURL=postcheck.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postcheck.js","sourceRoot":"","sources":["../../src/spec-quality/postcheck.ts"],"names":[],"mappings":"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"}
|