@specship/specship-win32-arm64 0.25.0 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/specship.cmd +31 -1
- package/lib/dist/activation/cheatsheet.d.ts +17 -1
- package/lib/dist/activation/cheatsheet.d.ts.map +1 -1
- package/lib/dist/activation/cheatsheet.js +47 -3
- package/lib/dist/activation/cheatsheet.js.map +1 -1
- package/lib/dist/activation/hook-output.d.ts +80 -0
- package/lib/dist/activation/hook-output.d.ts.map +1 -0
- package/lib/dist/activation/hook-output.js +103 -0
- package/lib/dist/activation/hook-output.js.map +1 -0
- package/lib/dist/activation/search-intercept.d.ts +60 -29
- package/lib/dist/activation/search-intercept.d.ts.map +1 -1
- package/lib/dist/activation/search-intercept.js +159 -55
- package/lib/dist/activation/search-intercept.js.map +1 -1
- package/lib/dist/activation/steering.d.ts +8 -10
- package/lib/dist/activation/steering.d.ts.map +1 -1
- package/lib/dist/activation/steering.js +21 -6
- package/lib/dist/activation/steering.js.map +1 -1
- package/lib/dist/behaviour/behaviour-surface.d.ts +47 -0
- package/lib/dist/behaviour/behaviour-surface.d.ts.map +1 -1
- package/lib/dist/behaviour/behaviour-surface.js +108 -2
- package/lib/dist/behaviour/behaviour-surface.js.map +1 -1
- package/lib/dist/bin/node-version-check.d.ts +22 -7
- package/lib/dist/bin/node-version-check.d.ts.map +1 -1
- package/lib/dist/bin/node-version-check.js +39 -9
- package/lib/dist/bin/node-version-check.js.map +1 -1
- package/lib/dist/bin/specship.js +762 -81
- package/lib/dist/bin/specship.js.map +1 -1
- package/lib/dist/commands/specship/learn.md +22 -0
- package/lib/dist/commands/specship/spec.md +12 -0
- package/lib/dist/db/sqlite-adapter.d.ts +7 -5
- package/lib/dist/db/sqlite-adapter.d.ts.map +1 -1
- package/lib/dist/db/sqlite-adapter.js +11 -9
- package/lib/dist/db/sqlite-adapter.js.map +1 -1
- package/lib/dist/enforce/changed-files.d.ts +11 -0
- package/lib/dist/enforce/changed-files.d.ts.map +1 -1
- package/lib/dist/enforce/changed-files.js +42 -0
- package/lib/dist/enforce/changed-files.js.map +1 -1
- package/lib/dist/enforce/enforce.d.ts +25 -1
- package/lib/dist/enforce/enforce.d.ts.map +1 -1
- package/lib/dist/enforce/enforce.js +58 -3
- package/lib/dist/enforce/enforce.js.map +1 -1
- package/lib/dist/enforce/mutation.d.ts +46 -0
- package/lib/dist/enforce/mutation.d.ts.map +1 -0
- package/lib/dist/enforce/mutation.js +104 -0
- package/lib/dist/enforce/mutation.js.map +1 -0
- package/lib/dist/enforce/suppressions.d.ts +33 -0
- package/lib/dist/enforce/suppressions.d.ts.map +1 -0
- package/lib/dist/enforce/suppressions.js +159 -0
- package/lib/dist/enforce/suppressions.js.map +1 -0
- package/lib/dist/extraction/specs/markdown-spec-extractor.d.ts.map +1 -1
- package/lib/dist/extraction/specs/markdown-spec-extractor.js +16 -2
- package/lib/dist/extraction/specs/markdown-spec-extractor.js.map +1 -1
- package/lib/dist/graph/spec-coverage.d.ts +57 -1
- package/lib/dist/graph/spec-coverage.d.ts.map +1 -1
- package/lib/dist/graph/spec-coverage.js +129 -5
- package/lib/dist/graph/spec-coverage.js.map +1 -1
- package/lib/dist/health/smoke-check.js +2 -2
- package/lib/dist/health/smoke-check.js.map +1 -1
- package/lib/dist/index.d.ts +8 -3
- package/lib/dist/index.d.ts.map +1 -1
- package/lib/dist/index.js +65 -9
- package/lib/dist/index.js.map +1 -1
- package/lib/dist/installer/gemini-commands.d.ts +107 -0
- package/lib/dist/installer/gemini-commands.d.ts.map +1 -0
- package/lib/dist/installer/gemini-commands.js +264 -0
- package/lib/dist/installer/gemini-commands.js.map +1 -0
- package/lib/dist/installer/index.d.ts +23 -1
- package/lib/dist/installer/index.d.ts.map +1 -1
- package/lib/dist/installer/index.js +22 -3
- package/lib/dist/installer/index.js.map +1 -1
- package/lib/dist/installer/install-defaults.d.ts +19 -0
- package/lib/dist/installer/install-defaults.d.ts.map +1 -1
- package/lib/dist/installer/install-defaults.js +28 -0
- package/lib/dist/installer/install-defaults.js.map +1 -1
- package/lib/dist/installer/instructions-template.d.ts +22 -0
- package/lib/dist/installer/instructions-template.d.ts.map +1 -1
- package/lib/dist/installer/instructions-template.js +37 -1
- package/lib/dist/installer/instructions-template.js.map +1 -1
- package/lib/dist/installer/targets/claude.d.ts +4 -0
- package/lib/dist/installer/targets/claude.d.ts.map +1 -1
- package/lib/dist/installer/targets/claude.js +8 -25
- package/lib/dist/installer/targets/claude.js.map +1 -1
- package/lib/dist/installer/targets/gemini.d.ts +85 -12
- package/lib/dist/installer/targets/gemini.d.ts.map +1 -1
- package/lib/dist/installer/targets/gemini.js +527 -30
- package/lib/dist/installer/targets/gemini.js.map +1 -1
- package/lib/dist/installer/targets/shared.d.ts +13 -0
- package/lib/dist/installer/targets/shared.d.ts.map +1 -1
- package/lib/dist/installer/targets/shared.js +18 -0
- package/lib/dist/installer/targets/shared.js.map +1 -1
- package/lib/dist/installer/targets/types.d.ts +12 -0
- package/lib/dist/installer/targets/types.d.ts.map +1 -1
- package/lib/dist/jira/auto-publish.d.ts +71 -4
- package/lib/dist/jira/auto-publish.d.ts.map +1 -1
- package/lib/dist/jira/auto-publish.js +186 -17
- package/lib/dist/jira/auto-publish.js.map +1 -1
- package/lib/dist/jira/reconcile.d.ts +24 -1
- package/lib/dist/jira/reconcile.d.ts.map +1 -1
- package/lib/dist/jira/reconcile.js +46 -2
- package/lib/dist/jira/reconcile.js.map +1 -1
- package/lib/dist/jira/repo-config.d.ts +9 -0
- package/lib/dist/jira/repo-config.d.ts.map +1 -1
- package/lib/dist/jira/repo-config.js +11 -0
- package/lib/dist/jira/repo-config.js.map +1 -1
- package/lib/dist/jira/types.d.ts +7 -0
- package/lib/dist/jira/types.d.ts.map +1 -1
- package/lib/dist/jira/types.js.map +1 -1
- package/lib/dist/knowledge/enforce.d.ts +75 -0
- package/lib/dist/knowledge/enforce.d.ts.map +1 -0
- package/lib/dist/knowledge/enforce.js +250 -0
- package/lib/dist/knowledge/enforce.js.map +1 -0
- package/lib/dist/knowledge/facts.d.ts +33 -0
- package/lib/dist/knowledge/facts.d.ts.map +1 -0
- package/lib/dist/knowledge/facts.js +117 -0
- package/lib/dist/knowledge/facts.js.map +1 -0
- package/lib/dist/knowledge/proposals.d.ts +88 -0
- package/lib/dist/knowledge/proposals.d.ts.map +1 -0
- package/lib/dist/knowledge/proposals.js +360 -0
- package/lib/dist/knowledge/proposals.js.map +1 -0
- package/lib/dist/knowledge/stale.d.ts +64 -0
- package/lib/dist/knowledge/stale.d.ts.map +1 -0
- package/lib/dist/knowledge/stale.js +174 -0
- package/lib/dist/knowledge/stale.js.map +1 -0
- package/lib/dist/mcp/gemini-session.d.ts +50 -0
- package/lib/dist/mcp/gemini-session.d.ts.map +1 -0
- package/lib/dist/mcp/gemini-session.js +159 -0
- package/lib/dist/mcp/gemini-session.js.map +1 -0
- package/lib/dist/mcp/jira-tools.d.ts.map +1 -1
- package/lib/dist/mcp/jira-tools.js +25 -0
- package/lib/dist/mcp/jira-tools.js.map +1 -1
- package/lib/dist/mcp/model-context.d.ts +22 -9
- package/lib/dist/mcp/model-context.d.ts.map +1 -1
- package/lib/dist/mcp/model-context.js +35 -13
- package/lib/dist/mcp/model-context.js.map +1 -1
- package/lib/dist/mcp/proxy.js +1 -1
- package/lib/dist/mcp/proxy.js.map +1 -1
- package/lib/dist/mcp/server-instructions.d.ts +16 -15
- package/lib/dist/mcp/server-instructions.d.ts.map +1 -1
- package/lib/dist/mcp/server-instructions.js +67 -1
- package/lib/dist/mcp/server-instructions.js.map +1 -1
- package/lib/dist/mcp/session.js +1 -1
- package/lib/dist/mcp/session.js.map +1 -1
- package/lib/dist/mcp/spec-tools.d.ts +9 -1
- package/lib/dist/mcp/spec-tools.d.ts.map +1 -1
- package/lib/dist/mcp/spec-tools.js +69 -21
- package/lib/dist/mcp/spec-tools.js.map +1 -1
- package/lib/dist/mcp/tools.d.ts +37 -1
- package/lib/dist/mcp/tools.d.ts.map +1 -1
- package/lib/dist/mcp/tools.js +120 -9
- package/lib/dist/mcp/tools.js.map +1 -1
- package/lib/dist/pulse/pulse.d.ts +93 -0
- package/lib/dist/pulse/pulse.d.ts.map +1 -0
- package/lib/dist/pulse/pulse.js +401 -0
- package/lib/dist/pulse/pulse.js.map +1 -0
- package/lib/dist/reflect/apply.d.ts.map +1 -1
- package/lib/dist/reflect/apply.js +38 -3
- package/lib/dist/reflect/apply.js.map +1 -1
- package/lib/dist/reflect/auto-sweep.d.ts +26 -0
- package/lib/dist/reflect/auto-sweep.d.ts.map +1 -0
- package/lib/dist/reflect/auto-sweep.js +90 -0
- package/lib/dist/reflect/auto-sweep.js.map +1 -0
- package/lib/dist/reflect/cli.d.ts +62 -0
- package/lib/dist/reflect/cli.d.ts.map +1 -0
- package/lib/dist/reflect/cli.js +163 -0
- package/lib/dist/reflect/cli.js.map +1 -0
- package/lib/dist/reflect/miner.d.ts.map +1 -1
- package/lib/dist/reflect/miner.js +119 -0
- package/lib/dist/reflect/miner.js.map +1 -1
- package/lib/dist/reflect/sweep.d.ts +1 -0
- package/lib/dist/reflect/sweep.d.ts.map +1 -1
- package/lib/dist/reflect/sweep.js +62 -13
- package/lib/dist/reflect/sweep.js.map +1 -1
- package/lib/dist/reflect/targets.d.ts +2 -0
- package/lib/dist/reflect/targets.d.ts.map +1 -1
- package/lib/dist/reflect/targets.js +33 -0
- package/lib/dist/reflect/targets.js.map +1 -1
- package/lib/dist/reflect/types.d.ts +19 -2
- package/lib/dist/reflect/types.d.ts.map +1 -1
- package/lib/dist/resolution/test-title-links.d.ts.map +1 -1
- package/lib/dist/resolution/test-title-links.js +3 -14
- package/lib/dist/resolution/test-title-links.js.map +1 -1
- package/lib/dist/server/routes/claude.js +15 -7
- package/lib/dist/server/routes/knowledge.js +118 -0
- package/lib/dist/server/server.js +2 -0
- package/lib/dist/spec-lint/lint.d.ts +1 -1
- package/lib/dist/spec-lint/lint.d.ts.map +1 -1
- package/lib/dist/spec-lint/lint.js +63 -2
- package/lib/dist/spec-lint/lint.js.map +1 -1
- package/lib/dist/spec-quality/criterion-ids.d.ts +13 -0
- package/lib/dist/spec-quality/criterion-ids.d.ts.map +1 -0
- package/lib/dist/spec-quality/criterion-ids.js +38 -0
- package/lib/dist/spec-quality/criterion-ids.js.map +1 -0
- package/lib/dist/spec-quality/evidence-kind.d.ts +54 -0
- package/lib/dist/spec-quality/evidence-kind.d.ts.map +1 -0
- package/lib/dist/spec-quality/evidence-kind.js +183 -0
- package/lib/dist/spec-quality/evidence-kind.js.map +1 -0
- package/lib/dist/spec-quality/link-persist.d.ts +65 -0
- package/lib/dist/spec-quality/link-persist.d.ts.map +1 -0
- package/lib/dist/spec-quality/link-persist.js +249 -0
- package/lib/dist/spec-quality/link-persist.js.map +1 -0
- package/lib/dist/spec-quality/plan-scope.d.ts +38 -0
- package/lib/dist/spec-quality/plan-scope.d.ts.map +1 -0
- package/lib/dist/spec-quality/plan-scope.js +129 -0
- package/lib/dist/spec-quality/plan-scope.js.map +1 -0
- package/lib/dist/spec-quality/postcheck.d.ts +85 -0
- package/lib/dist/spec-quality/postcheck.d.ts.map +1 -0
- package/lib/dist/spec-quality/postcheck.js +390 -0
- package/lib/dist/spec-quality/postcheck.js.map +1 -0
- package/lib/dist/spec-quality/readiness.d.ts +72 -0
- package/lib/dist/spec-quality/readiness.d.ts.map +1 -0
- package/lib/dist/spec-quality/readiness.js +226 -0
- package/lib/dist/spec-quality/readiness.js.map +1 -0
- package/lib/dist/workflows/agents/claude.d.ts +16 -0
- package/lib/dist/workflows/agents/claude.d.ts.map +1 -0
- package/lib/dist/workflows/agents/claude.js +82 -0
- package/lib/dist/workflows/agents/claude.js.map +1 -0
- package/lib/dist/workflows/agents/gemini.d.ts +21 -0
- package/lib/dist/workflows/agents/gemini.d.ts.map +1 -0
- package/lib/dist/workflows/agents/gemini.js +124 -0
- package/lib/dist/workflows/agents/gemini.js.map +1 -0
- package/lib/dist/workflows/agents/index.d.ts +28 -0
- package/lib/dist/workflows/agents/index.d.ts.map +1 -0
- package/lib/dist/workflows/agents/index.js +104 -0
- package/lib/dist/workflows/agents/index.js.map +1 -0
- package/lib/dist/workflows/agents/types.d.ts +55 -0
- package/lib/dist/workflows/agents/types.d.ts.map +1 -0
- package/lib/dist/workflows/agents/types.js +46 -0
- package/lib/dist/workflows/agents/types.js.map +1 -0
- package/lib/dist/workflows/batch.d.ts +63 -0
- package/lib/dist/workflows/batch.d.ts.map +1 -0
- package/lib/dist/workflows/batch.js +151 -0
- package/lib/dist/workflows/batch.js.map +1 -0
- package/lib/dist/workflows/defaults/claude-design-implement.yaml +3 -4
- package/lib/dist/workflows/defaults/spec-author.yaml +11 -9
- package/lib/dist/workflows/defaults/spec-implement-mixed.yaml +21 -436
- package/lib/dist/workflows/defaults/spec-implement.yaml +465 -46
- package/lib/dist/workflows/discovery.d.ts +13 -0
- package/lib/dist/workflows/discovery.d.ts.map +1 -1
- package/lib/dist/workflows/discovery.js +79 -17
- package/lib/dist/workflows/discovery.js.map +1 -1
- package/lib/dist/workflows/executor.d.ts +18 -0
- package/lib/dist/workflows/executor.d.ts.map +1 -1
- package/lib/dist/workflows/executor.js +130 -33
- package/lib/dist/workflows/executor.js.map +1 -1
- package/lib/dist/workflows/gc.d.ts +50 -0
- package/lib/dist/workflows/gc.d.ts.map +1 -0
- package/lib/dist/workflows/gc.js +120 -0
- package/lib/dist/workflows/gc.js.map +1 -0
- package/lib/dist/workflows/merge-queue.d.ts +64 -0
- package/lib/dist/workflows/merge-queue.d.ts.map +1 -0
- package/lib/dist/workflows/merge-queue.js +162 -0
- package/lib/dist/workflows/merge-queue.js.map +1 -0
- package/lib/dist/workflows/runners/approval.d.ts +1 -1
- package/lib/dist/workflows/runners/approval.d.ts.map +1 -1
- package/lib/dist/workflows/runners/approval.js +11 -2
- package/lib/dist/workflows/runners/approval.js.map +1 -1
- package/lib/dist/workflows/runners/bash.d.ts +15 -0
- package/lib/dist/workflows/runners/bash.d.ts.map +1 -1
- package/lib/dist/workflows/runners/bash.js +50 -1
- package/lib/dist/workflows/runners/bash.js.map +1 -1
- package/lib/dist/workflows/runners/prompt.d.ts +16 -41
- package/lib/dist/workflows/runners/prompt.d.ts.map +1 -1
- package/lib/dist/workflows/runners/prompt.js +55 -120
- package/lib/dist/workflows/runners/prompt.js.map +1 -1
- package/lib/dist/workflows/runners/types.d.ts +12 -0
- package/lib/dist/workflows/runners/types.d.ts.map +1 -1
- package/lib/dist/workflows/schemas/workflow.d.ts +17 -0
- package/lib/dist/workflows/schemas/workflow.d.ts.map +1 -1
- package/lib/dist/workflows/schemas/workflow.js +27 -0
- package/lib/dist/workflows/schemas/workflow.js.map +1 -1
- package/lib/node_modules/.package-lock.json +1 -1
- package/lib/package.json +2 -2
- package/package.json +5 -3
- package/node.exe +0 -4
|
@@ -1,440 +1,25 @@
|
|
|
1
1
|
name: spec-implement-mixed
|
|
2
2
|
description: Implement a spec with mixed models — sonnet plans, haiku executes, tests + gates verify. Same steps and gates as spec-implement at a fraction of the token cost.
|
|
3
3
|
tags: [spec, default, mixed-model]
|
|
4
|
-
requires: [specship, git]
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
#
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
- mcp__specship__specship_spec
|
|
28
|
-
- mcp__specship__specship_explore
|
|
29
|
-
prompt: |
|
|
30
|
-
Spec ID: $INPUT.SPEC_ID
|
|
31
|
-
|
|
32
|
-
Call specship_spec to fetch the spec. Then call specship_explore on
|
|
33
|
-
a small bag of terms drawn from the spec title and acceptance
|
|
34
|
-
criteria to find the relevant code area.
|
|
35
|
-
|
|
36
|
-
Output: a short summary (≤300 words) of (a) what the spec asks for,
|
|
37
|
-
(b) which code areas / symbols are most relevant, and (c) whether
|
|
38
|
-
any code currently claims to implement it (look at linked_code).
|
|
39
|
-
|
|
40
|
-
- id: plan
|
|
41
|
-
# MIXMODEL-DOC: judgment step → sonnet
|
|
42
|
-
model: sonnet
|
|
43
|
-
kind: prompt
|
|
44
|
-
depends_on: [fetch_spec]
|
|
45
|
-
output_type: plan
|
|
46
|
-
allowed_tools:
|
|
47
|
-
- mcp__specship__specship_explore
|
|
48
|
-
- mcp__specship__specship_node
|
|
49
|
-
- mcp__specship__specship_spec
|
|
50
|
-
- Read
|
|
51
|
-
prompt: |
|
|
52
|
-
Based on this spec summary, write a concrete implementation plan:
|
|
53
|
-
|
|
54
|
-
$fetch_spec.output
|
|
55
|
-
|
|
56
|
-
The plan should list:
|
|
57
|
-
- Files to create or modify (with project-relative paths)
|
|
58
|
-
- Specific functions/methods/classes to add or change
|
|
59
|
-
- Tests to add or update
|
|
60
|
-
- Order of changes
|
|
61
|
-
|
|
62
|
-
Keep it tight (≤500 words). Do NOT edit code in this step.
|
|
63
|
-
|
|
64
|
-
- id: approve_plan
|
|
65
|
-
kind: approval
|
|
66
|
-
depends_on: [plan]
|
|
67
|
-
message: |
|
|
68
|
-
Plan ready for $INPUT.SPEC_ID. Review the plan output and approve
|
|
69
|
-
to proceed with implementation, or reject with feedback to revise.
|
|
70
|
-
capture_response: true
|
|
71
|
-
on_reject:
|
|
72
|
-
prompt: |
|
|
73
|
-
The plan was rejected with this feedback. Revise:
|
|
74
|
-
|
|
75
|
-
$approve_plan.output
|
|
76
|
-
max_attempts: 3
|
|
77
|
-
|
|
78
|
-
- id: implement
|
|
79
|
-
# MIXMODEL-DOC: mechanical step → haiku
|
|
80
|
-
model: haiku
|
|
81
|
-
kind: prompt
|
|
82
|
-
depends_on: [approve_plan]
|
|
83
|
-
output_type: diff
|
|
84
|
-
allowed_tools:
|
|
85
|
-
- Read
|
|
86
|
-
- Edit
|
|
87
|
-
- Write
|
|
88
|
-
- Bash
|
|
89
|
-
- mcp__specship__specship_explore
|
|
90
|
-
- mcp__specship__specship_node
|
|
91
|
-
- mcp__specship__specship_spec
|
|
92
|
-
prompt: |
|
|
93
|
-
Implement the approved plan. Follow it closely.
|
|
94
|
-
|
|
95
|
-
Plan:
|
|
96
|
-
$plan.output
|
|
97
|
-
|
|
98
|
-
Approval feedback (if any):
|
|
99
|
-
$approve_plan.output
|
|
100
|
-
|
|
101
|
-
When done, output a short diff summary (which files changed and why).
|
|
102
|
-
|
|
103
|
-
- id: quality_gate
|
|
104
|
-
kind: bash
|
|
105
|
-
depends_on: [implement]
|
|
106
|
-
output_type: quality_report
|
|
107
|
-
timeout: 600000
|
|
108
|
-
bash: |
|
|
109
|
-
# REQ-AUTHG-005.A1 — the project's own lint/typecheck, run in the
|
|
110
|
-
# worktree right after implement. The QUALITY_GATE marker is the
|
|
111
|
-
# contract the remediation node routes on: a project with neither a lint
|
|
112
|
-
# script nor a typecheck config says so explicitly, so "nothing ran" can
|
|
113
|
-
# never be mistaken for "clean" (same doctrine as VERIFY_RESULT=skipped).
|
|
114
|
-
QUALITY_CMD=""
|
|
115
|
-
if [ -f package.json ]; then
|
|
116
|
-
# The worktree may not have dependencies yet (verify installs them
|
|
117
|
-
# later) and lint needs them — bootstrap quietly, and treat a failed
|
|
118
|
-
# install as "no gate" rather than as a lint failure.
|
|
119
|
-
if [ ! -d node_modules ]; then
|
|
120
|
-
npm ci --no-audit --no-fund >/dev/null 2>&1 || npm install --no-audit --no-fund >/dev/null 2>&1 || true
|
|
121
|
-
fi
|
|
122
|
-
if node -e 'const s=(require("./package.json").scripts)||{};process.exit(s.lint?0:1)' 2>/dev/null; then
|
|
123
|
-
QUALITY_CMD="npm run lint --if-present"
|
|
124
|
-
elif [ -f tsconfig.json ]; then
|
|
125
|
-
QUALITY_CMD="npx --no-install tsc --noEmit"
|
|
126
|
-
fi
|
|
127
|
-
elif [ -f Cargo.toml ]; then
|
|
128
|
-
if command -v cargo >/dev/null 2>&1; then QUALITY_CMD="cargo clippy --no-deps"; fi
|
|
129
|
-
elif [ -f pyproject.toml ] || [ -f requirements.txt ]; then
|
|
130
|
-
if command -v ruff >/dev/null 2>&1; then QUALITY_CMD="ruff check ."; fi
|
|
131
|
-
fi
|
|
132
|
-
if [ -z "$QUALITY_CMD" ]; then
|
|
133
|
-
echo "QUALITY_GATE=skipped"
|
|
134
|
-
echo "QUALITY_REASON=no lint script and no typecheck configuration in this project"
|
|
135
|
-
exit 0
|
|
136
|
-
fi
|
|
137
|
-
echo "QUALITY_CMD=$QUALITY_CMD"
|
|
138
|
-
if OUT=$($QUALITY_CMD 2>&1); then
|
|
139
|
-
echo "QUALITY_GATE=passed"
|
|
140
|
-
else
|
|
141
|
-
echo "QUALITY_GATE=failed"
|
|
142
|
-
printf '%s\n' "$OUT" | tail -n 80
|
|
143
|
-
fi
|
|
144
|
-
# Exiting 0 on a lint failure is deliberate: the marker — not this node's
|
|
145
|
-
# exit code — drives the revise loop. quality_recheck is what halts.
|
|
146
|
-
|
|
147
|
-
- id: fix_quality
|
|
148
|
-
# MIXMODEL-DOC: mechanical step (fix what the linter named) → haiku
|
|
149
|
-
model: haiku
|
|
150
|
-
kind: prompt
|
|
151
|
-
depends_on: [quality_gate]
|
|
152
|
-
output_type: quality_fix
|
|
153
|
-
allowed_tools:
|
|
154
|
-
- Read
|
|
155
|
-
- Edit
|
|
156
|
-
- Write
|
|
157
|
-
- Bash
|
|
158
|
-
- mcp__specship__specship_explore
|
|
159
|
-
- mcp__specship__specship_node
|
|
160
|
-
prompt: |
|
|
161
|
-
Lint / typecheck result for the code you just wrote:
|
|
162
|
-
|
|
163
|
-
$quality_gate.output
|
|
164
|
-
|
|
165
|
-
Route on the QUALITY_GATE marker — do not re-judge the raw output:
|
|
166
|
-
|
|
167
|
-
- QUALITY_GATE=passed or QUALITY_GATE=skipped → change NOTHING. Output
|
|
168
|
-
exactly `FIX_QUALITY=not-needed` and stop.
|
|
169
|
-
- QUALITY_GATE=failed → fix every reported error, then re-run the
|
|
170
|
-
QUALITY_CMD shown above to confirm. Fix the code, never the lint
|
|
171
|
-
configuration; never silence or disable a rule to make it pass.
|
|
172
|
-
|
|
173
|
-
Output `FIX_QUALITY=fixed` (clean re-run) or `FIX_QUALITY=still-failing`
|
|
174
|
-
followed by the errors that remain.
|
|
175
|
-
|
|
176
|
-
- id: quality_recheck
|
|
177
|
-
kind: bash
|
|
178
|
-
depends_on: [fix_quality]
|
|
179
|
-
output_type: quality_result
|
|
180
|
-
timeout: 600000
|
|
181
|
-
bash: |
|
|
182
|
-
# REQ-AUTHG-005.A1 — the authoritative half of the gate. The fix node is
|
|
183
|
-
# a prompt, so its "FIX_QUALITY=fixed" claim is a claim, not evidence:
|
|
184
|
-
# this node re-runs the same command and halts the run while it still
|
|
185
|
-
# fails, so failing lint/typecheck never reaches verify, the link node,
|
|
186
|
-
# or the human gate.
|
|
187
|
-
GATE_OUT=$quality_gate.output
|
|
188
|
-
MARKER=$(printf '%s' "$GATE_OUT" | grep -oE 'QUALITY_GATE=[a-z-]+' | tail -n 1 | cut -d= -f2)
|
|
189
|
-
CMD=$(printf '%s' "$GATE_OUT" | grep -E '^QUALITY_CMD=' | tail -n 1 | cut -d= -f2-)
|
|
190
|
-
if [ "$MARKER" = "skipped" ] || [ -z "$CMD" ]; then
|
|
191
|
-
echo "QUALITY_RESULT=skipped"
|
|
192
|
-
echo "This project has no lint or typecheck gate — nothing was checked."
|
|
193
|
-
exit 0
|
|
194
|
-
fi
|
|
195
|
-
if OUT=$($CMD 2>&1); then
|
|
196
|
-
echo "QUALITY_RESULT=clean"
|
|
197
|
-
exit 0
|
|
198
|
-
fi
|
|
199
|
-
echo "QUALITY_RESULT=failed"
|
|
200
|
-
printf '%s\n' "$OUT" | tail -n 80
|
|
201
|
-
echo "HALT_CAUSE=lint/typecheck still fails after the fix attempt — the change is not reviewable yet"
|
|
202
|
-
exit 1
|
|
203
|
-
|
|
204
|
-
- id: diff
|
|
205
|
-
kind: bash
|
|
206
|
-
depends_on: [quality_recheck]
|
|
207
|
-
output_type: diff
|
|
208
|
-
bash: |
|
|
209
|
-
# REQ-AUTHG-004.A1 — the full diff, from git, into a run artifact. The
|
|
210
|
-
# human gate and the adversarial reviewer read THIS; the implement node's
|
|
211
|
-
# prose about what it believes it changed is not the change.
|
|
212
|
-
# `git add -A -N` registers new files as intent-to-add so untracked work
|
|
213
|
-
# appears in `git diff HEAD` without staging any content.
|
|
214
|
-
git add -A -N >/dev/null 2>&1 || true
|
|
215
|
-
echo "DIFF_BEGIN"
|
|
216
|
-
git --no-pager diff HEAD | head -c 400000
|
|
217
|
-
echo
|
|
218
|
-
echo "DIFF_END"
|
|
219
|
-
|
|
220
|
-
- id: diff_stat
|
|
221
|
-
kind: bash
|
|
222
|
-
depends_on: [diff]
|
|
223
|
-
output_type: diff_stat
|
|
224
|
-
bash: |
|
|
225
|
-
# REQ-AUTHG-004.A2 — the stat block the final gate shows: file names and
|
|
226
|
-
# insertions/deletions counted by git. Its own small node so the approval
|
|
227
|
-
# message carries the summary while the full diff stays in the `diff`
|
|
228
|
-
# artifact.
|
|
229
|
-
echo "DIFF_STAT_BEGIN"
|
|
230
|
-
git --no-pager diff HEAD --stat
|
|
231
|
-
echo "DIFF_STAT_END"
|
|
232
|
-
|
|
233
|
-
- id: verify
|
|
234
|
-
kind: bash
|
|
235
|
-
depends_on: [diff_stat]
|
|
236
|
-
output_type: test_results
|
|
237
|
-
timeout: 600000
|
|
238
|
-
bash: |
|
|
239
|
-
# Run the project's test suite. The verify node's exit code drives
|
|
240
|
-
# the gating for the link node — non-zero halts the workflow.
|
|
241
|
-
# The VERIFY_RESULT marker is the machine-readable contract the link
|
|
242
|
-
# node routes on (REQ-IMPLINT-001.A1): a skipped run must never be
|
|
243
|
-
# mistaken for a passing one.
|
|
244
|
-
# Install and build failures fail fast with their own markers
|
|
245
|
-
# (REQ-REVINT-006.A1) — a broken environment or a build break is NOT a
|
|
246
|
-
# test failure, and must never be attributed to one.
|
|
247
|
-
if [ -f package.json ]; then
|
|
248
|
-
# A fresh worktree has no node_modules/ or build output — a verify
|
|
249
|
-
# failure must mean the tests failed, not that the environment was
|
|
250
|
-
# missing (WF-REJECT-DOC, REQ-WFREJ-005).
|
|
251
|
-
if [ ! -d node_modules ]; then
|
|
252
|
-
if ! { npm ci --no-audit --no-fund || npm install --no-audit --no-fund; }; then
|
|
253
|
-
echo "VERIFY_RESULT=env-failed"; exit 1
|
|
254
|
-
fi
|
|
255
|
-
fi
|
|
256
|
-
if ! npm run build --if-present; then echo "VERIFY_RESULT=build-failed"; exit 1; fi
|
|
257
|
-
if npm test; then echo "VERIFY_RESULT=ran-and-passed"; else echo "VERIFY_RESULT=ran-and-failed"; exit 1; fi
|
|
258
|
-
elif [ -f Cargo.toml ]; then
|
|
259
|
-
if ! cargo build; then echo "VERIFY_RESULT=build-failed"; exit 1; fi
|
|
260
|
-
if cargo test; then echo "VERIFY_RESULT=ran-and-passed"; else echo "VERIFY_RESULT=ran-and-failed"; exit 1; fi
|
|
261
|
-
elif [ -f pyproject.toml ] || [ -f requirements.txt ]; then
|
|
262
|
-
if ! python -c 'import pytest' 2>/dev/null; then echo "VERIFY_RESULT=env-failed"; exit 1; fi
|
|
263
|
-
if python -m pytest; then echo "VERIFY_RESULT=ran-and-passed"; else echo "VERIFY_RESULT=ran-and-failed"; exit 1; fi
|
|
264
|
-
else
|
|
265
|
-
echo "no recognised test framework; tests did NOT run"
|
|
266
|
-
echo "VERIFY_RESULT=skipped"
|
|
267
|
-
fi
|
|
268
|
-
|
|
269
|
-
- id: route_verify
|
|
270
|
-
kind: bash
|
|
271
|
-
depends_on: [verify]
|
|
272
|
-
output_type: verify_route
|
|
273
|
-
bash: |
|
|
274
|
-
# Deterministic verify routing (REQ-VSTATE-005.A1): the VERIFY_RESULT
|
|
275
|
-
# marker is parsed HERE, in code, and turned into a LINK_ACTION the link
|
|
276
|
-
# node obeys. It used to be a prompt reading a test log — the one decision
|
|
277
|
-
# that governs whether links may be promoted was hallucinable.
|
|
278
|
-
VERIFY_OUT=$verify.output
|
|
279
|
-
MARKER=$(printf '%s' "$VERIFY_OUT" | grep -oE 'VERIFY_RESULT=[a-z-]+' | tail -n 1 | cut -d= -f2)
|
|
280
|
-
[ -n "$MARKER" ] || MARKER=missing
|
|
281
|
-
echo "VERIFY_RESULT=$MARKER"
|
|
282
|
-
# env-failed / build-failed halt BEFORE any link mutation, naming the
|
|
283
|
-
# environment cause (REQ-VSTATE-005.A3) — neither is a test failure.
|
|
284
|
-
case "$MARKER" in
|
|
285
|
-
ran-and-passed)
|
|
286
|
-
echo "LINK_ACTION=assert-and-verify-pass" ;;
|
|
287
|
-
ran-and-failed)
|
|
288
|
-
echo "LINK_ACTION=assert-and-verify-fail" ;;
|
|
289
|
-
skipped)
|
|
290
|
-
echo "LINK_ACTION=assert-only" ;;
|
|
291
|
-
env-failed)
|
|
292
|
-
echo "HALT_CAUSE=environment setup failed (dependency install) — nothing is known about the tests"
|
|
293
|
-
exit 1 ;;
|
|
294
|
-
build-failed)
|
|
295
|
-
echo "HALT_CAUSE=build failed — nothing is known about the tests"
|
|
296
|
-
exit 1 ;;
|
|
297
|
-
*)
|
|
298
|
-
echo "HALT_CAUSE=no VERIFY_RESULT marker found in the verify output — an unknown result is never a pass"
|
|
299
|
-
exit 1 ;;
|
|
300
|
-
esac
|
|
301
|
-
|
|
302
|
-
- id: link
|
|
303
|
-
# MIXMODEL-DOC: mechanical step → haiku
|
|
304
|
-
model: haiku
|
|
305
|
-
kind: prompt
|
|
306
|
-
depends_on: [route_verify]
|
|
307
|
-
output_type: link_summary
|
|
308
|
-
allowed_tools:
|
|
309
|
-
- mcp__specship__specship_link_assert
|
|
310
|
-
- mcp__specship__specship_link_verify
|
|
311
|
-
- mcp__specship__specship_spec
|
|
312
|
-
prompt: |
|
|
313
|
-
Assert spec→code links for the changes made in the implement step.
|
|
314
|
-
For each symbol that implements $INPUT.SPEC_ID (or its child
|
|
315
|
-
requirements), call specship_link_assert with the spec_id, the
|
|
316
|
-
file path, and the qualified symbol name.
|
|
317
|
-
|
|
318
|
-
You MUST NOT assert a `tests`-kind link (REQ-REVINT-005.A1). Every
|
|
319
|
-
specship_link_assert call here is an implementation link — leave `kind`
|
|
320
|
-
at its default and never pass kind: 'tests'. Test evidence is
|
|
321
|
-
file-derived only: it comes from the spec's `verifies:` block or an
|
|
322
|
-
`@verifies` comment on the test symbol, never from this node. A workflow
|
|
323
|
-
that minted its own test evidence would be promoting itself past the
|
|
324
|
-
gate that exists to check it.
|
|
325
|
-
|
|
326
|
-
Then act on LINK_ACTION, which a bash node already computed from the
|
|
327
|
-
VERIFY_RESULT marker (REQ-VSTATE-005.A1). Do NOT re-derive it from the
|
|
328
|
-
test log — read it:
|
|
329
|
-
|
|
330
|
-
$route_verify.output
|
|
331
|
-
|
|
332
|
-
- LINK_ACTION=assert-and-verify-pass → after each assert, call
|
|
333
|
-
specship_link_verify with result="pass".
|
|
334
|
-
- LINK_ACTION=assert-and-verify-fail → call specship_link_verify with
|
|
335
|
-
result="fail" and the failing test name as the reason.
|
|
336
|
-
- LINK_ACTION=assert-only → do NOT call specship_link_verify at all;
|
|
337
|
-
the links stay in the `implemented` state. Tests that did not run
|
|
338
|
-
are never reported as passing.
|
|
339
|
-
|
|
340
|
-
A run whose environment or build broke never reaches this node — the
|
|
341
|
-
routing step halts it first (REQ-VSTATE-005.A3).
|
|
342
|
-
|
|
343
|
-
Implementation diff summary:
|
|
344
|
-
$implement.output
|
|
345
|
-
|
|
346
|
-
Test results:
|
|
347
|
-
$verify.output
|
|
348
|
-
|
|
349
|
-
Output: a short list of "spec_id → file:symbol [verified|implemented]"
|
|
350
|
-
lines, ending with one line stating whether verification ran or was
|
|
351
|
-
skipped.
|
|
352
|
-
|
|
353
|
-
- id: coverage
|
|
354
|
-
kind: bash
|
|
355
|
-
depends_on: [link]
|
|
356
|
-
output_type: coverage_summary
|
|
357
|
-
bash: |
|
|
358
|
-
# The acceptance-criteria coverage line is computed FROM THE DB
|
|
359
|
-
# (REQ-VSTATE-005.A2) — `specship coverage --line` renders the same
|
|
360
|
-
# `getSpecCoverage` report the MCP tool and the dashboard read, so the
|
|
361
|
-
# number on the approval gate cannot disagree with them. It used to be
|
|
362
|
-
# counted by a prompt.
|
|
363
|
-
if command -v specship >/dev/null 2>&1; then SS=specship
|
|
364
|
-
elif [ -x node_modules/.bin/specship ]; then SS=node_modules/.bin/specship
|
|
365
|
-
elif [ -x dist/bin/specship.js ]; then SS="node dist/bin/specship.js"
|
|
366
|
-
else SS=""; fi
|
|
367
|
-
if [ -z "$SS" ]; then
|
|
368
|
-
echo "COVERAGE_UNAVAILABLE=specship CLI not found — acceptance-criteria coverage was NOT computed"
|
|
369
|
-
exit 0
|
|
370
|
-
fi
|
|
371
|
-
LINE=$($SS coverage $INPUT.SPEC_ID --line) || {
|
|
372
|
-
echo "COVERAGE_UNAVAILABLE=specship coverage failed — coverage was NOT computed"
|
|
373
|
-
exit 0
|
|
374
|
-
}
|
|
375
|
-
echo "$LINE"
|
|
376
|
-
N=$(printf '%s' "$LINE" | awk '{print $1}')
|
|
377
|
-
M=$(printf '%s' "$LINE" | awk '{print $3}')
|
|
378
|
-
if [ "$N" != "$M" ]; then
|
|
379
|
-
echo "Close the gap with /specship:spec behaviour $INPUT.SPEC_ID."
|
|
380
|
-
fi
|
|
381
|
-
|
|
382
|
-
- id: adversarial_review
|
|
383
|
-
# MIXMODEL-DOC: judgment step (does this diff satisfy the spec?) → sonnet
|
|
384
|
-
model: sonnet
|
|
385
|
-
kind: prompt
|
|
386
|
-
depends_on: [coverage]
|
|
387
|
-
output_type: adversarial_review
|
|
388
|
-
allowed_tools:
|
|
389
|
-
- Read
|
|
390
|
-
- Grep
|
|
391
|
-
- mcp__specship__specship_spec
|
|
392
|
-
- mcp__specship__specship_explore
|
|
393
|
-
- mcp__specship__specship_node
|
|
394
|
-
- mcp__specship__specship_search
|
|
395
|
-
prompt: |
|
|
396
|
-
Adversarial review (REQ-AUTHG-005.A3). You are NOT the implementer — your
|
|
397
|
-
job is to find what the implementation missed. This node is read-only:
|
|
398
|
-
you have no Edit, Write or Bash tool and must not try to fix anything.
|
|
399
|
-
|
|
400
|
-
Call specship_spec($INPUT.SPEC_ID) and read the spec body, including
|
|
401
|
-
every acceptance criterion.
|
|
402
|
-
|
|
403
|
-
The change under review (from git, not from the implementer's summary):
|
|
404
|
-
|
|
405
|
-
$diff.output
|
|
406
|
-
|
|
407
|
-
Report this and nothing else:
|
|
408
|
-
|
|
409
|
-
1. One line per acceptance criterion:
|
|
410
|
-
`<AC id>: satisfied | partial | unaddressed — <one sentence, grounded
|
|
411
|
-
in the diff>`. Judge from the diff and the code you read; "the
|
|
412
|
-
implementer said so" is not evidence.
|
|
413
|
-
2. `Untested new code paths:` the branches/functions this diff adds that
|
|
414
|
-
no test in the diff exercises (`none` if there are none).
|
|
415
|
-
3. `Verdict:` one line — the most serious gap a reviewer should look at
|
|
416
|
-
first, or `no gaps found`.
|
|
417
|
-
|
|
418
|
-
- id: final_review
|
|
419
|
-
kind: approval
|
|
420
|
-
depends_on: [adversarial_review]
|
|
421
|
-
message: |
|
|
422
|
-
Implementation complete for $INPUT.SPEC_ID.
|
|
423
|
-
|
|
424
|
-
Changes (git diff --stat — measured, not summarized):
|
|
425
|
-
$diff_stat.output
|
|
426
|
-
|
|
427
|
-
Lint / typecheck:
|
|
428
|
-
$quality_recheck.output
|
|
429
|
-
|
|
430
|
-
Links asserted:
|
|
431
|
-
$link.output
|
|
432
|
-
|
|
433
|
-
Acceptance-criteria test coverage:
|
|
434
|
-
$coverage.output
|
|
435
|
-
|
|
436
|
-
Adversarial review:
|
|
437
|
-
$adversarial_review.output
|
|
438
|
-
|
|
439
|
-
Approve to finalize the run (worktree is left for you to inspect
|
|
440
|
-
and merge), or reject to abandon.
|
|
5
|
+
# THROUGHPUT-DOC, REQ-THRU-004 — one source of truth for the implement
|
|
6
|
+
# pipeline. This variant inherits every node, gate and prompt from
|
|
7
|
+
# spec-implement and states only what differs: which model runs each step
|
|
8
|
+
# (MIXMODEL-DOC). Judgment steps are pinned up (sonnet); mechanical steps are
|
|
9
|
+
# pinned down (haiku); bash gates, approvals, verify, routing and coverage are
|
|
10
|
+
# model-free and identical by construction.
|
|
11
|
+
extends: spec-implement
|
|
12
|
+
|
|
13
|
+
node_overrides:
|
|
14
|
+
fetch_spec:
|
|
15
|
+
model: haiku # mechanical: read the spec and summarize
|
|
16
|
+
plan:
|
|
17
|
+
model: sonnet # judgment: the plan the human approves
|
|
18
|
+
implement:
|
|
19
|
+
model: haiku # mechanical: execute the approved plan
|
|
20
|
+
fix_quality:
|
|
21
|
+
model: haiku # mechanical: fix what the linter named
|
|
22
|
+
link:
|
|
23
|
+
model: haiku # mechanical: record implementations bullets
|
|
24
|
+
adversarial_review:
|
|
25
|
+
model: sonnet # judgment: try to break the change
|