@nklisch/pi-agile-workflow 0.15.3

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.
Files changed (203) hide show
  1. package/.claude-plugin/plugin.json +10 -0
  2. package/.codex-plugin/plugin.json +28 -0
  3. package/CHANGELOG.md +591 -0
  4. package/README.md +107 -0
  5. package/docs/ARCHITECTURE.md +716 -0
  6. package/docs/MIGRATION.md +419 -0
  7. package/docs/PRINCIPLES.md +464 -0
  8. package/docs/ROADMAP.md +95 -0
  9. package/docs/SPEC.md +855 -0
  10. package/docs/VISION.md +106 -0
  11. package/extensions/agile-workflow.test.ts +419 -0
  12. package/extensions/agile-workflow.ts +467 -0
  13. package/hooks/hooks.json +52 -0
  14. package/hooks/scripts/prompt-context.py +628 -0
  15. package/hooks/scripts/substrate-maintainer.py +359 -0
  16. package/hooks/scripts/test_prompt_context.py +757 -0
  17. package/package.json +30 -0
  18. package/scripts/install-work-view.sh +165 -0
  19. package/scripts/tests/agent-metadata.test.sh +75 -0
  20. package/scripts/tests/bump-version.test.sh +552 -0
  21. package/scripts/tests/channel-parity.test.sh +117 -0
  22. package/scripts/tests/convert-content-integrity.test.sh +246 -0
  23. package/scripts/tests/convert-install-routing.test.sh +159 -0
  24. package/scripts/tests/install-work-view.test.sh +411 -0
  25. package/scripts/tests/pi-package-metadata.test.sh +119 -0
  26. package/scripts/tests/work-board-shim.test.sh +239 -0
  27. package/scripts/tests/work-view-dist-version.test.sh +105 -0
  28. package/scripts/work-board.sh +64 -0
  29. package/scripts/work-view.sh +423 -0
  30. package/skills/autopilot/SKILL.md +330 -0
  31. package/skills/autopilot/agents/openai.yaml +6 -0
  32. package/skills/board/SKILL.md +62 -0
  33. package/skills/board/agents/openai.yaml +6 -0
  34. package/skills/bold-refactor/SKILL.md +244 -0
  35. package/skills/bold-refactor/agents/openai.yaml +6 -0
  36. package/skills/bug-scan/SKILL.md +378 -0
  37. package/skills/bug-scan/agents/openai.yaml +6 -0
  38. package/skills/bug-scan/references/async-promises.md +119 -0
  39. package/skills/bug-scan/references/concurrency-races.md +148 -0
  40. package/skills/bug-scan/references/data-layer.md +167 -0
  41. package/skills/bug-scan/references/error-handling.md +197 -0
  42. package/skills/bug-scan/references/gate-item-template.md +94 -0
  43. package/skills/bug-scan/references/language-footguns.md +219 -0
  44. package/skills/bug-scan/references/parked-item-template.md +103 -0
  45. package/skills/bug-scan/references/report-template.md +115 -0
  46. package/skills/bug-scan/references/resource-leaks.md +199 -0
  47. package/skills/bug-scan/references/state-closures.md +148 -0
  48. package/skills/bug-scan/references/time-numbers.md +158 -0
  49. package/skills/convert/SKILL.md +1463 -0
  50. package/skills/convert/agents/openai.yaml +6 -0
  51. package/skills/convert/references/legacy-overlap-migration.md +179 -0
  52. package/skills/deep-code-scan/SKILL.md +378 -0
  53. package/skills/deep-code-scan/agents/openai.yaml +6 -0
  54. package/skills/deep-code-scan/references/artifact-ledger.md +148 -0
  55. package/skills/deep-code-scan/references/consolidation.md +91 -0
  56. package/skills/deep-code-scan/references/decomposition.md +127 -0
  57. package/skills/deep-code-scan/references/item-templates.md +263 -0
  58. package/skills/deep-code-scan/references/lane-catalog.md +129 -0
  59. package/skills/deep-code-scan/references/review-gauntlet.md +108 -0
  60. package/skills/deep-code-scan/references/scanner-brief.md +152 -0
  61. package/skills/e2e-test-design/SKILL.md +517 -0
  62. package/skills/e2e-test-design/references/anti-tautology.md +261 -0
  63. package/skills/e2e-test-design/references/service-mocks.md +234 -0
  64. package/skills/e2e-test-design/references/test-taxonomy.md +211 -0
  65. package/skills/epic-design/SKILL.md +476 -0
  66. package/skills/epicize/SKILL.md +210 -0
  67. package/skills/epicize/agents/openai.yaml +6 -0
  68. package/skills/feature-design/SKILL.md +472 -0
  69. package/skills/fix/SKILL.md +173 -0
  70. package/skills/gate-cruft/SKILL.md +258 -0
  71. package/skills/gate-docs/SKILL.md +278 -0
  72. package/skills/gate-patterns/SKILL.md +389 -0
  73. package/skills/gate-refactor/SKILL.md +408 -0
  74. package/skills/gate-security/SKILL.md +275 -0
  75. package/skills/gate-tests/SKILL.md +367 -0
  76. package/skills/groom/SKILL.md +162 -0
  77. package/skills/groom/agents/openai.yaml +6 -0
  78. package/skills/ideate/SKILL.md +185 -0
  79. package/skills/ideate/agents/openai.yaml +6 -0
  80. package/skills/implement/SKILL.md +288 -0
  81. package/skills/implement-orchestrator/SKILL.md +604 -0
  82. package/skills/park/SKILL.md +111 -0
  83. package/skills/perf-design/SKILL.md +427 -0
  84. package/skills/perf-scout/SKILL.md +404 -0
  85. package/skills/perf-scout/agents/openai.yaml +6 -0
  86. package/skills/perf-scout/references/algorithmic-and-data-structures.md +126 -0
  87. package/skills/perf-scout/references/approximation-and-precomputation.md +136 -0
  88. package/skills/perf-scout/references/caching-and-memoization.md +123 -0
  89. package/skills/perf-scout/references/compiler-runtime-and-language.md +136 -0
  90. package/skills/perf-scout/references/database-and-storage-internals.md +144 -0
  91. package/skills/perf-scout/references/distributed-systems.md +150 -0
  92. package/skills/perf-scout/references/game-engine-and-realtime.md +136 -0
  93. package/skills/perf-scout/references/gpu-and-accelerators.md +130 -0
  94. package/skills/perf-scout/references/idea-ranking.md +75 -0
  95. package/skills/perf-scout/references/io-and-batching.md +135 -0
  96. package/skills/perf-scout/references/memory-and-data-locality.md +137 -0
  97. package/skills/perf-scout/references/parallelism-and-vectorization.md +126 -0
  98. package/skills/perf-scout/references/parked-item-template.md +117 -0
  99. package/skills/perf-scout/references/peer-review-pass.md +150 -0
  100. package/skills/perf-scout/references/report-template.md +148 -0
  101. package/skills/principles/SKILL.md +678 -0
  102. package/skills/principles/references/models.md +191 -0
  103. package/skills/principles/references/subagents.md +158 -0
  104. package/skills/prose-author/SKILL.md +185 -0
  105. package/skills/refactor-conventions-creator/SKILL.md +359 -0
  106. package/skills/refactor-conventions-creator/agents/openai.yaml +6 -0
  107. package/skills/refactor-conventions-creator/references/common-structures.md +91 -0
  108. package/skills/refactor-conventions-creator/references/common-styles.md +90 -0
  109. package/skills/refactor-design/SKILL.md +384 -0
  110. package/skills/release-deploy/SKILL.md +667 -0
  111. package/skills/release-deploy/agents/openai.yaml +6 -0
  112. package/skills/research/SKILL.md +166 -0
  113. package/skills/research/agents/openai.yaml +6 -0
  114. package/skills/review/SKILL.md +267 -0
  115. package/skills/review/references/deep-review.md +98 -0
  116. package/skills/review/references/review-lenses.md +68 -0
  117. package/skills/review/references/substrate-side-effects.md +161 -0
  118. package/skills/review/references/target-resolution.md +52 -0
  119. package/skills/scope/SKILL.md +486 -0
  120. package/work-view/Cargo.lock +486 -0
  121. package/work-view/Cargo.toml +9 -0
  122. package/work-view/crates/cli/.work-view-version +1 -0
  123. package/work-view/crates/cli/Cargo.toml +18 -0
  124. package/work-view/crates/cli/src/actionable.rs +500 -0
  125. package/work-view/crates/cli/src/args.rs +792 -0
  126. package/work-view/crates/cli/src/board/assets/board.css +855 -0
  127. package/work-view/crates/cli/src/board/assets/board.js +259 -0
  128. package/work-view/crates/cli/src/board/assets/card.js +139 -0
  129. package/work-view/crates/cli/src/board/assets/components.css +290 -0
  130. package/work-view/crates/cli/src/board/assets/dependency.js +1193 -0
  131. package/work-view/crates/cli/src/board/assets/detail.js +256 -0
  132. package/work-view/crates/cli/src/board/assets/filters.js +389 -0
  133. package/work-view/crates/cli/src/board/assets/index.html +77 -0
  134. package/work-view/crates/cli/src/board/assets/kanban.js +231 -0
  135. package/work-view/crates/cli/src/board/assets/markdown.js +260 -0
  136. package/work-view/crates/cli/src/board/assets/motion.css +131 -0
  137. package/work-view/crates/cli/src/board/assets/state.js +245 -0
  138. package/work-view/crates/cli/src/board/assets/table.js +304 -0
  139. package/work-view/crates/cli/src/board/assets/tokens.css +602 -0
  140. package/work-view/crates/cli/src/board/assets/views.js +41 -0
  141. package/work-view/crates/cli/src/board/assets.rs +162 -0
  142. package/work-view/crates/cli/src/board/feed.rs +204 -0
  143. package/work-view/crates/cli/src/board/mod.rs +246 -0
  144. package/work-view/crates/cli/src/board/open.rs +144 -0
  145. package/work-view/crates/cli/src/board/server.rs +407 -0
  146. package/work-view/crates/cli/src/main.rs +195 -0
  147. package/work-view/crates/cli/src/render.rs +354 -0
  148. package/work-view/crates/cli/src/scope.rs +157 -0
  149. package/work-view/crates/cli/src/stale.rs +581 -0
  150. package/work-view/crates/cli/tests/board-js/dependency-table.test.mjs +64 -0
  151. package/work-view/crates/cli/tests/board-js/expanded-browsing.test.mjs +79 -0
  152. package/work-view/crates/cli/tests/board-js/harness-smoke.test.mjs +11 -0
  153. package/work-view/crates/cli/tests/board-js/harness.mjs +437 -0
  154. package/work-view/crates/cli/tests/board-js/kanban-detail.test.mjs +75 -0
  155. package/work-view/crates/cli/tests/board-js/markdown-filter.test.mjs +60 -0
  156. package/work-view/crates/cli/tests/fixtures/golden/.work/CONVENTIONS.md +3 -0
  157. package/work-view/crates/cli/tests/fixtures/golden/.work/active/epics/epic-alpha.md +16 -0
  158. package/work-view/crates/cli/tests/fixtures/golden/.work/active/features/feat-a.md +16 -0
  159. package/work-view/crates/cli/tests/fixtures/golden/.work/active/features/feat-b.md +16 -0
  160. package/work-view/crates/cli/tests/fixtures/golden/.work/active/stories/story-alpha-1.md +16 -0
  161. package/work-view/crates/cli/tests/fixtures/golden/.work/active/stories/story-research-1.md +19 -0
  162. package/work-view/crates/cli/tests/fixtures/golden/.work/archive/feat-done.md +16 -0
  163. package/work-view/crates/cli/tests/fixtures/golden/.work/archive/feat-shipped.md +18 -0
  164. package/work-view/crates/cli/tests/fixtures/golden/.work/backlog/idea-backlog.md +7 -0
  165. package/work-view/crates/cli/tests/fixtures/golden/.work/releases/v1.0/v1.0.md +16 -0
  166. package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/CONVENTIONS.md +6 -0
  167. package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/active/features/feat-dep-done.md +17 -0
  168. package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/active/features/feat-design-ready.md +17 -0
  169. package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/active/features/feat-impl-ready.md +17 -0
  170. package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/active/stories/story-review-ready.md +17 -0
  171. package/work-view/crates/cli/tests/fixtures/with-malformed/.work/CONVENTIONS.md +4 -0
  172. package/work-view/crates/cli/tests/fixtures/with-malformed/.work/active/epics/malformed-no-closing-fence.md +8 -0
  173. package/work-view/crates/cli/tests/fixtures/with-malformed/.work/active/features/good-item.md +16 -0
  174. package/work-view/crates/cli/tests/integration.rs +2833 -0
  175. package/work-view/crates/core/Cargo.toml +13 -0
  176. package/work-view/crates/core/src/error.rs +61 -0
  177. package/work-view/crates/core/src/filter.rs +804 -0
  178. package/work-view/crates/core/src/graph.rs +324 -0
  179. package/work-view/crates/core/src/index.rs +590 -0
  180. package/work-view/crates/core/src/lib.rs +54 -0
  181. package/work-view/crates/core/src/model.rs +202 -0
  182. package/work-view/crates/core/src/parse.rs +494 -0
  183. package/work-view/crates/core/tests/fixtures/golden/.work/CONVENTIONS.md +15 -0
  184. package/work-view/crates/core/tests/fixtures/golden/.work/active/epics/epic-core.md +16 -0
  185. package/work-view/crates/core/tests/fixtures/golden/.work/active/features/feat-parser.md +16 -0
  186. package/work-view/crates/core/tests/fixtures/golden/.work/active/features/feat-query.md +16 -0
  187. package/work-view/crates/core/tests/fixtures/golden/.work/active/stories/malformed-no-id.md +15 -0
  188. package/work-view/crates/core/tests/fixtures/golden/.work/active/stories/story-parse-unit.md +16 -0
  189. package/work-view/crates/core/tests/fixtures/golden/.work/active/stories/story-security-gate.md +16 -0
  190. package/work-view/crates/core/tests/fixtures/golden/.work/archive/feat-old.md +16 -0
  191. package/work-view/crates/core/tests/fixtures/golden/.work/archive/feat-parser.md +17 -0
  192. package/work-view/crates/core/tests/fixtures/golden/.work/backlog/idea-future-board.md +7 -0
  193. package/work-view/crates/core/tests/fixtures/golden/.work/releases/v1.0/v1.0.md +16 -0
  194. package/work-view/crates/core/tests/fixtures/precedence/.work/CONVENTIONS.md +10 -0
  195. package/work-view/crates/core/tests/fixtures/precedence/.work/archive/dup-item.md +18 -0
  196. package/work-view/crates/core/tests/fixtures/precedence/.work/releases/v2.0/dup-item.md +18 -0
  197. package/work-view/crates/core/tests/integration.rs +541 -0
  198. package/work-view/dist/.gitattributes +1 -0
  199. package/work-view/dist/README.md +42 -0
  200. package/work-view/dist/aarch64-apple-darwin/work-view +0 -0
  201. package/work-view/dist/aarch64-unknown-linux-musl/work-view +0 -0
  202. package/work-view/dist/x86_64-apple-darwin/work-view +0 -0
  203. package/work-view/dist/x86_64-unknown-linux-musl/work-view +0 -0
@@ -0,0 +1,367 @@
1
+ ---
2
+ name: gate-tests
3
+ description: >
4
+ Test-quality gate that scans items bound to a release for test coverage gaps. Delegates the full
5
+ analysis to a deep test scanner agent which derives expected coverage from each bound item's
6
+ acceptance criteria (NOT from implementation code), maps existing test coverage, identifies gaps,
7
+ and returns findings. The orchestrator converts findings into gate_origin:tests items in
8
+ .work/active/. Auto-triggers during /agile-workflow:release-deploy.
9
+ ---
10
+
11
+ # Gate-Tests
12
+
13
+ You orchestrate a test-quality gate over the items bound to a release. The
14
+ actual analysis runs inside a **deep test scanner agent** (a generic sub-agent prompted with the scanner posture from `../principles/references/subagents.md`); your role is to prepare the
15
+ bundle context, dispatch the scanner, and convert the gaps it returns into
16
+ items in the substrate.
17
+
18
+ Scanner strength is explicit: spawn exactly one source-read-only deep test
19
+ scanner with the strongest inspection/reviewer setting the host exposes. Use a generic sub-agent prompted with the scanner posture from `../principles/references/subagents.md`. Use extra-high reasoning
20
+ only for broad cross-feature releases, complex state machines,
21
+ concurrency-heavy behavior, or repeated test-quality misses. If the host has no
22
+ scanner path, run the analysis inline and record the reduced isolation
23
+ in the release body.
24
+
25
+ ## Core principle
26
+
27
+ The gate's principle: **tests derive from specs, not implementations**. Each
28
+ bound item's acceptance criteria IS the spec. The scanner verifies those
29
+ criteria are covered, finds gaps, and returns them. It also checks the seams
30
+ BETWEEN bound items — integration coverage where one item's output feeds
31
+ another.
32
+
33
+ Tests derived from reading implementation code are tautological — they verify
34
+ that the code does what the code does. Tests derived from specs verify what
35
+ the code *should* do. That's where bugs live. The scanner brief enforces this
36
+ discipline.
37
+
38
+ ## Trigger
39
+
40
+ - `/agile-workflow:release-deploy` invokes during `quality-gate` stage
41
+ - User can invoke manually: `/agile-workflow:gate-tests <release-version>`
42
+
43
+ ## Workflow
44
+
45
+ ### Phase 1: Identify the bundle
46
+
47
+ ```bash
48
+ # Bound non-release items. `--release` auto-widens to ALL tiers (active + archive + releases).
49
+ # Include late-bound archived stubs; their bodies may be pruned, but their item id is still
50
+ # present and can recover the bundle commits/files. Ignore only the release orchestration item.
51
+ .work/bin/work-view --release <version> --paths | while IFS= read -r item; do
52
+ kind=$(grep -m1 '^kind:' "$item" | awk '{print $2}')
53
+ [ "$kind" = "release" ] && continue
54
+ echo "$item"
55
+ done > /tmp/bundle-items-<version>.txt
56
+ ```
57
+
58
+ If the bundle-items file is empty, halt: "No items bound to release `<version>`."
59
+
60
+ Build the union of files changed by the bundle. For archived stubs, the body is pruned on disk by
61
+ design; use the item id to find implementation commits instead of treating the missing body as a
62
+ skip reason:
63
+
64
+ ```bash
65
+ while IFS= read -r item; do
66
+ id=$(grep -m1 '^id:' "$item" | awk '{print $2}')
67
+ git log --grep "$id" --format='%H' | xargs -I{} git diff-tree --no-commit-id --name-only -r {}
68
+ done < /tmp/bundle-items-<version>.txt | sort -u > /tmp/bundle-files-<version>.txt
69
+ ```
70
+
71
+ ### Phase 2: Read existing gate items (idempotency prep)
72
+
73
+ ```bash
74
+ .work/bin/work-view --release <version> --gate tests --paths
75
+ ```
76
+
77
+ Capture already-tracked findings to feed into the scanner brief.
78
+
79
+ ### Phase 3: Dispatch the test-coverage scanner
80
+
81
+ Spawn ONE source-read-only deep scanner agent with the full analysis brief. Use
82
+ a generic sub-agent prompted with the scanner posture from `../principles/references/subagents.md` and the strongest
83
+ inspection/reviewer setting the host exposes, escalating for broad cross-feature
84
+ releases, complex state machines, concurrency-heavy behavior, or repeated
85
+ test-quality misses. If scanner agents are unavailable, run the analysis
86
+ inline and record the reduced isolation in the release body. The scanner
87
+ extracts behavioral contracts from item bodies, maps existing tests, applies
88
+ test-design techniques to find gaps, and returns structured findings.
89
+
90
+ **Brief template**:
91
+
92
+ > You are conducting a test-quality gate for release `<version>`. Core
93
+ > principle: **tests derive from specs, not implementations**. Each bound
94
+ > item's acceptance criteria IS the spec.
95
+ >
96
+ > Use read/search/shell tools as needed. Do not spawn nested sub-agents or implement
97
+ > fixes.
98
+ >
99
+ > **Bundle scope** (files changed by the bundle):
100
+ > ```
101
+ > <bundle-files>
102
+ > ```
103
+ >
104
+ > **Bound items** (read each item's body for the spec; an archived stub's
105
+ > body is pruned on disk — hydrate it from the stub's `git_ref` frontmatter
106
+ > via `git show <git_ref>:<path>`, trying the item's former `.work/active/`
107
+ > path at that ref):
108
+ > `<bound-item-ids>`
109
+ >
110
+ > **Already-tracked findings to skip**:
111
+ > ```
112
+ > <already-tracked>
113
+ > ```
114
+ >
115
+ > **Methodology**:
116
+ >
117
+ > 1. **Extract the behavioral contract per item.** For each bound item, read
118
+ > its body and decompose along four axes:
119
+ >
120
+ > **Input space:**
121
+ > - All parameters, types, valid ranges and partitions
122
+ > - Invalid inputs the spec says should be rejected or handled
123
+ > - Optional vs required
124
+ > - Edge values: empty, zero, null, max, min
125
+ >
126
+ > **Output space:**
127
+ > - All return types and variants
128
+ > - Error/exception conditions the spec defines
129
+ > - Side effects the spec promises (or prohibits)
130
+ >
131
+ > **State space (where applicable):**
132
+ > - All valid states
133
+ > - All valid transitions
134
+ > - Invalid transitions the spec rejects
135
+ >
136
+ > **Business rules:**
137
+ > - Conditions and combinations producing different outcomes
138
+ > - Priority rules when multiple conditions apply
139
+ >
140
+ > Then extract:
141
+ > - Acceptance criteria (look for `## Acceptance Criteria`,
142
+ > `## Acceptance`, or `- [ ]` checklist items)
143
+ > - Implementation units / unit names
144
+ > - Public interface surface (functions, types, endpoints exposed)
145
+ >
146
+ > These four axes plus the explicit acceptance criteria form the spec.
147
+ >
148
+ > 2. **Map existing test coverage.** For each bound item, find tests that
149
+ > reference its implementation. For files changed by item `<id>`, list all
150
+ > tests covering those files. For each test, identify which acceptance
151
+ > criterion or behavioral contract it verifies. Cite file:line. Note any
152
+ > tests that appear to mirror implementation step-by-step (tautological —
153
+ > should be reworked or deleted). Do NOT read implementation bodies; only
154
+ > test files and types. Read 2-3 key test files yourself to verify the map.
155
+ >
156
+ > 3. **Apply test-design techniques** for each acceptance criterion not
157
+ > covered by tests:
158
+ > - **Equivalence partitioning** — one test per valid partition, one per
159
+ > invalid
160
+ > - **Boundary value analysis** — for ranges: just-below, at, just-above
161
+ > - **Decision table** — for criteria with multiple conditions, enumerate
162
+ > combinations
163
+ > - **State transition** — for state changes, test valid transitions and
164
+ > verify invalid ones are rejected
165
+ > - **Error guessing (spec-driven)** — anything described as "should
166
+ > not", "must not", "invalid", "error", "reject"
167
+ >
168
+ > 4. **Adversarial coverage** — for each bound item, surface failure
169
+ > expectations along these axes. If the item body or design doesn't
170
+ > state the answer, the gap itself is a finding (`stage: drafting`,
171
+ > `tags: [testing]`):
172
+ > 1. Invalid input — when a caller passes invalid data, what should
173
+ > happen? (Reject? Fall back? Log and continue?)
174
+ > 2. Missing config — when required configuration is absent, what's the
175
+ > expected behavior?
176
+ > 3. Unavailable dependency — when a downstream dep (DB, API, queue) is
177
+ > unreachable, what's expected? (Retry? Fail fast? Degraded mode?)
178
+ > 4. Boundary values — at the limits of input ranges, what's the
179
+ > contract?
180
+ > 5. Concurrent / race conditions — for items with shared state, what's
181
+ > the contract under concurrency?
182
+ > 6. Interrupted operations — if a multi-step operation is interrupted,
183
+ > what's the expected end state?
184
+ >
185
+ > Where the spec is silent, produce either: (a) a `[testing]` story to
186
+ > write the test once the spec is settled, or (b) a `[documentation]`
187
+ > story to extend the spec with the missing assertion target.
188
+ >
189
+ > 5. **Map e2e seams.** For items with `depends_on` chains, check whether
190
+ > the seam between them is tested:
191
+ > - Does an integration or e2e test exercise the path from item A's
192
+ > output through item B's input?
193
+ > - Are real conditions used (real DB instance, real HTTP, real
194
+ > filesystem in temp) rather than mocks of mocks?
195
+ >
196
+ > For features with multiple child stories, check that the parent
197
+ > feature's overall acceptance criteria are e2e-covered, not just
198
+ > per-story unit-covered.
199
+ >
200
+ > 6. **Classify gaps**:
201
+ > | Priority | Definition |
202
+ > |---|---|
203
+ > | Critical | Acceptance criterion with no test |
204
+ > | High | Boundary or error case from spec, no test |
205
+ > | Medium | Valid partition or rule combination, no test |
206
+ > | Low | Complementary coverage |
207
+ >
208
+ > Also flag tautological tests found during step 2 — they need rework or
209
+ > deletion.
210
+ >
211
+ > **Output format** — return a single markdown document with:
212
+ >
213
+ > ```
214
+ > ## Findings
215
+ >
216
+ > ### Finding 1
217
+ > - **Title**: <one-line: spec condition not covered>
218
+ > - **Priority**: Critical | High | Medium | Low
219
+ > - **Bound item**: `<item-id>`
220
+ > - **Acceptance criterion**: <quote the criterion>
221
+ > - **Gap type**: missing test for valid partition / boundary / error case /
222
+ > adversarial-spec-silent / e2e-seam / tautological-rework
223
+ > - **Suggested test**:
224
+ > ```<lang>
225
+ > // Sketch of the test — name, scenario, assertion target.
226
+ > ```
227
+ > - **Test location (suggested)**: `<test-file-path>`
228
+ >
229
+ > ### Finding 2
230
+ > ...
231
+ > ```
232
+ >
233
+ > Followed by:
234
+ >
235
+ > ```
236
+ > ## Audit summary
237
+ > - Items with extracted contracts: <count>
238
+ > - Existing tests mapped: <count>
239
+ > - Tautological tests flagged: <count>
240
+ > - Findings by priority: Critical=<n>, High=<n>, Medium=<n>, Low=<n>
241
+ > ```
242
+ >
243
+ > **Rules**:
244
+ > - Derive tests from specs, NOT from implementation code. If you find
245
+ > yourself reading a function body to decide what to verify, stop — go
246
+ > back to the spec.
247
+ > - Test the public interface, not internal implementation.
248
+ > - Cite spec references in every finding. A finding without a spec
249
+ > reference is testing an assumption, not a contract.
250
+ > - Prioritize invalid input, error cases, boundary conditions.
251
+ > - Audit only the bundle's items, not the whole repo.
252
+ > - Skip already-tracked.
253
+ >
254
+ > **Test integrity findings** (additional pass — flag and surface as
255
+ > Critical findings):
256
+ > - Tests that make themselves pass without verifying behavior:
257
+ > `expect(true).toBe(true)`, asserting on the literal return of the
258
+ > function under test, `assert 1 == 1`, tautological mock-on-mock
259
+ > assertions.
260
+ > - Tests that were silenced rather than diagnosed: broad `skip` /
261
+ > `xfail` / `it.todo` with no linked backlog id or written reason.
262
+ > - Tests deleted in the bundle's commits with no replacement coverage
263
+ > for the same acceptance criterion. (Check `git log` of the bundle.)
264
+ > - Tests whose assertion was rewritten to match new-but-undocumented
265
+ > behavior — i.e. the test was made to follow the code instead of the
266
+ > code being made to follow the spec.
267
+ >
268
+ > When you flag a test-integrity finding, also identify whether a real
269
+ > production bug was being silenced. If so, surface BOTH the integrity
270
+ > finding and the underlying-bug finding.
271
+
272
+ ### Phase 4: Convert findings to items
273
+
274
+ For each finding the scanner returned:
275
+
276
+ Read `gate_finding_routing` from `.work/CONVENTIONS.md` before writing items.
277
+ If absent, use the default routing below. Normalize test priority to routing
278
+ keys as: `Critical -> critical`, `High -> high`, `Medium -> medium`, and
279
+ `Low -> low`. If a normalized key maps to `skip`, do not emit an item for that
280
+ finding; include the skipped count in the gate output. If it maps to `backlog`,
281
+ write a `.work/backlog/` item instead of an active story.
282
+
283
+ ```yaml
284
+ ---
285
+ id: gate-tests-<short-slug>
286
+ kind: story
287
+ stage: implementing # critical/high
288
+ # OR drafting for medium
289
+ tags: [testing]
290
+ parent: null
291
+ depends_on: []
292
+ release_binding: <version>
293
+ gate_origin: tests
294
+ created: YYYY-MM-DD
295
+ updated: YYYY-MM-DD
296
+ ---
297
+
298
+ # <one-line description: spec condition not covered>
299
+
300
+ ## Priority
301
+ Critical | High | Medium | Low
302
+
303
+ ## Spec reference
304
+ Item: `<bound-item-id>`
305
+ Acceptance criterion: <quote the criterion>
306
+
307
+ ## Gap type
308
+ <missing test for valid partition / boundary / error case / etc.>
309
+
310
+ ## Suggested test
311
+ \`\`\`<lang>
312
+ // Sketch of the test — name, scenario, assertion target.
313
+ \`\`\`
314
+
315
+ ## Test location (suggested)
316
+ `<test-file-path>` (following project conventions)
317
+ ```
318
+
319
+ Default priority -> placement mapping:
320
+ - **Critical** / **High** → `stage: implementing` in `.work/active/stories/`
321
+ - **Medium** → `stage: drafting` in `.work/active/stories/`
322
+ - **Low** → backlog file in `.work/backlog/` (not stage-managed)
323
+
324
+ Tautological tests get items too:
325
+
326
+ ```yaml
327
+ # id: gate-tests-rework-<original-test-slug>
328
+ # kind: story
329
+ # tags: [testing, refactor]
330
+ # Body describes which test is tautological and what spec behavior it should be
331
+ # rewritten to verify (or marked for deletion).
332
+ ```
333
+
334
+ ### Phase 5: Commit
335
+
336
+ ```bash
337
+ git add .work/active/stories/ .work/backlog/
338
+ git commit -m "gate-tests: <N> coverage gaps for <version>"
339
+ ```
340
+
341
+ ## Output
342
+
343
+ In conversation:
344
+ - **Bundle**: `<version>` — `<N>` items audited
345
+ - **Coverage gaps**: count by priority
346
+ - **Tautological tests flagged**: count
347
+ - **Items created**: count, with new ids
348
+ - **Already-tracked**: count of duplicates skipped
349
+
350
+ ## Guardrails
351
+
352
+ - **The analysis happens in the scanner agent, not here.** Your job is bundle
353
+ prep, dispatch, and item-writing. Don't replicate the scanner's contract
354
+ extraction or coverage mapping.
355
+ - The scanner brief enforces "specs not implementations". Don't substitute
356
+ your own judgment for findings.
357
+ - Cite spec references in every item body. The scanner provides them.
358
+ - Prioritize invalid input, error cases, boundary conditions — that's where
359
+ bugs hide and specs are most often undertested.
360
+ - Audit only the bundle's items, not the whole repo.
361
+ - A failing test that exposes a real spec violation is the most valuable
362
+ output. Don't sand it down — surface it as a Critical finding so the
363
+ implementation gets fixed before shipping.
364
+ - **Test-integrity is a first-class concern of this gate.** A test that
365
+ was made to pass instead of made to fail honestly is worse than a
366
+ missing test — it lies to every future reviewer. Surface those as
367
+ Critical findings even when nominal coverage looks complete.
@@ -0,0 +1,162 @@
1
+ ---
2
+ name: groom
3
+ description: >
4
+ Backlog hygiene sweep for the agile-workflow substrate. Use when the user asks to groom the
5
+ backlog, audit backlog hygiene, find stale/dead/duplicate/superseded backlog items, or clean up
6
+ .work/backlog/. Triggers on "groom the backlog", "backlog hygiene", "find stale items", "what's
7
+ dead in the backlog", "any duplicates in the backlog". Reads .work/backlog/, classifies items
8
+ (DONE / SUPERSEDED / DUPLICATE / STALE / MERGEABLE / VALID) from date/metadata signals plus a
9
+ grounded semantic pass, and writes a triage REPORT of proposals. Propose-not-prune: it never
10
+ auto-archives, merges, or deletes — every disposition is operator-confirmed per finding, and dead
11
+ items route through the project's terminal-tier retention convention. Opt-in and inert when not
12
+ invoked; the staleness face is additionally inert unless backlog_staleness_days is configured.
13
+ ---
14
+
15
+ # Groom
16
+
17
+ You audit the project's `.work/backlog/` tier for hygiene problems and produce a **triage report
18
+ of proposals** — never silent mutation. Backlogs accrete entropy: items finish elsewhere, later
19
+ work supersedes them, duplicates pile up, and parked ideas go stale. Grooming surfaces that for a
20
+ human; it does not prune on its own.
21
+
22
+ This is a **user-invocable sweep, not a release gate.** The backlog has no release binding, so
23
+ grooming is not part of `gates_for_release` / `release-deploy`. It borrows the gates'
24
+ item-producer discipline (produce findings, never mutate silently) and is structured like `park` /
25
+ `scope` (operates on `.work/`, verifies substrate first).
26
+
27
+ ## When to invoke
28
+
29
+ Auto-trigger on hygiene phrases: "groom the backlog", "backlog hygiene", "audit the backlog",
30
+ "find stale / dead / duplicate / superseded items", "what's dead in the backlog", "clean up the
31
+ backlog". If the user wants to *add* an idea, that is `park`; if they want to *promote* one, that
32
+ is `scope`. Groom is for auditing what is already parked.
33
+
34
+ ## Core discipline (load-bearing)
35
+
36
+ - **Propose-not-prune.** Every non-VALID classification is a *proposal*. You write a report; you
37
+ apply a disposition only after explicit per-finding operator confirmation. Archive / merge /
38
+ delete are never automatic.
39
+ - **Ground every claim.** Mechanical findings name the signal that fired (age, missing field, a
40
+ cited id that is now `done`). Semantic findings (DUPLICATE / SUPERSEDED / MERGEABLE) must quote
41
+ the overlapping text from both items — no classification without a citation. Uncertain → propose
42
+ as a question, never assert. This is the anti-fabrication floor: do not claim "superseded"
43
+ without the grounding a reader could check.
44
+ - **Inherit disposition; don't re-decide it.** Confirmed DONE / SUPERSEDED items are disposed
45
+ through the project's **terminal-tier retention** convention (read it from
46
+ `.work/CONVENTIONS.md`), not a policy this skill invents.
47
+ - **No imposed cadence.** Groom runs when invoked. A deployment may schedule a recurring sweep,
48
+ but the skill neither assumes nor requires continuous operation.
49
+
50
+ ## Workflow
51
+
52
+ ### Phase 1: Verify substrate
53
+
54
+ Confirm `.work/CONVENTIONS.md` exists in the project (walk up from CWD). If not, halt:
55
+ > "No agile-workflow substrate found. Run `/agile-workflow:convert` to bootstrap, then retry."
56
+
57
+ Read from `.work/CONVENTIONS.md`: the **Terminal-tier retention** value (`delete-refs` default /
58
+ `retain-bodies`) and whether `backlog_staleness_days` is set.
59
+
60
+ ### Phase 2: Mechanical pass (cheap, deterministic)
61
+
62
+ These signals need no judgment. For each, record the item id + the signal that fired.
63
+
64
+ 1. **STALE (age).** Run `.work/bin/work-view --stale`. This lists backlog items whose last-touched
65
+ date — `updated` if present, else `created` — exceeds `backlog_staleness_days`. If the key is
66
+ absent, `--stale` reports itself inert; note "staleness face inert (no `backlog_staleness_days`
67
+ configured)" in the report and continue with the other checks. Do not invent a threshold.
68
+ 2. **Missing-field.** Flag backlog items missing a required field (`id`, `created`, `tags`) — a
69
+ malformed capture worth a human look.
70
+ 3. **Cites-done-work.** Scan each backlog item body for references to a feature/release/story id;
71
+ cross-check with `work-view` whether that id is now `stage: done` (or shipped). **The check must
72
+ span the terminal tiers** (`archive/`, `releases/`) where completed work usually lives — miss
73
+ them and this check misses exactly the shipped/archived work it exists to catch. On the Rust
74
+ `work-view` binary the active+backlog default hides those tiers, so widen with `--scope all`
75
+ (e.g. `work-view --scope all --stage done`); the bash fallback (`work-view.sh`) does not accept
76
+ `--scope` and already queries all tiers by default, so run it without the flag. An item whose
77
+ premise cites already-completed work is a **DONE candidate** — flag it with the cited id.
78
+
79
+ Mechanical findings are higher-confidence; still proposals, never auto-applied.
80
+
81
+ ### Phase 3: Semantic pass (grounded; default on, skippable)
82
+
83
+ Dispatch **one read-only deep sub-agent** over the backlog item bodies to propose:
84
+
85
+ - **DUPLICATE** — two items expressing the same intent.
86
+ - **SUPERSEDED** — a later item (or landed work) obsoletes an earlier one.
87
+ - **MERGEABLE / CLUSTER** — N items that are really one epic/feature.
88
+
89
+ The sub-agent prompt MUST use the host's generic/general-purpose subagent path
90
+ and carry the grounding requirement verbatim: *every proposed classification
91
+ quotes the overlapping text from each item involved; no classification without a
92
+ citation; uncertain pairings are surfaced as questions, not assertions.* If no
93
+ generic subagent adapter is available, run the pass inline and record the
94
+ reduced isolation in the report.
95
+
96
+ The user may skip this pass ("groom, mechanical only") — then report STALE / missing-field /
97
+ cites-done only.
98
+
99
+ ### Phase 4: Write the triage report
100
+
101
+ Write `groom-report-<date>.md` to the project's scratchpad tier — a transient location, NEVER
102
+ `.work/backlog/` (that would add items to the backlog this sweep exists to shrink). Resolve the
103
+ destination in this order: use `.work/scratch/` if it exists, else `.memory/scratchpad/` if it
104
+ exists, else emit the report inline in conversation and write no file. For each finding:
105
+
106
+ ```
107
+ <CLASSIFICATION> <item-id> — <signal / grounding>
108
+ e.g. STALE idea-foo — 180d since last-touched (threshold 90)
109
+ DONE? idea-bar — cites feature-baz, now stage:done
110
+ DUPLICATE idea-x ~ idea-y — both describe <quoted overlap from each>
111
+ SUPERSEDED idea-old — by idea-new: "<quote>" vs "<quote>"
112
+ MERGEABLE idea-a,b,c — one epic: <shared theme + quotes>
113
+ ```
114
+
115
+ VALID items are not listed individually (a count suffices) — the report is the exception set.
116
+
117
+ ### Phase 5: Per-finding confirmation and disposition
118
+
119
+ For each non-VALID finding, ask the operator before acting. Nothing moves without confirmation.
120
+
121
+ - **DONE / SUPERSEDED (confirmed)** → dispose through **terminal-tier retention**: under
122
+ `delete-refs`, archive as a bodyless stub; under `retain-bodies`, archive with body kept. (This
123
+ is the same terminal disposition the review skill uses — honor the project's value, do not
124
+ re-decide close-vs-archive.) For SUPERSEDED, first fold any unique detail into the superseding
125
+ item.
126
+ - **DUPLICATE (confirmed)** → fold unique detail into the kept item, then dispose the absorbed one
127
+ per the same convention.
128
+ - **MERGEABLE (confirmed)** → this is a `scope` act: hand off to `/agile-workflow:scope` to cluster
129
+ the items into one epic/feature, rather than mutating inline.
130
+ - **STALE (confirmed dead)** → treat as DONE/SUPERSEDED disposition; **STALE but still wanted** →
131
+ leave in place (touching it bumps `updated`, resetting the staleness clock — which is correct: a
132
+ human reaffirmed it).
133
+ - **Declined** → leave the item untouched; optionally note the reaffirmation.
134
+
135
+ Commit only the dispositions the operator confirmed:
136
+
137
+ ```bash
138
+ git add .work/ # the archived stubs / merged items actually changed
139
+ git commit -m "groom: <N> items disposed (<counts by class>)"
140
+ ```
141
+
142
+ ## Output
143
+
144
+ In conversation:
145
+ - **Report**: path (or inline) + counts by classification.
146
+ - **Confirmed**: items disposed and how (archived / merged / handed to scope).
147
+ - **Left**: stale-but-reaffirmed and declined counts.
148
+ - **Next**: `/agile-workflow:scope` for any MERGEABLE clusters the operator wants promoted.
149
+
150
+ ## Guardrails
151
+
152
+ - **Never auto-prune.** No archive / merge / delete without per-finding confirmation. A report with
153
+ zero confirmed dispositions is a valid, complete run.
154
+ - **Never fabricate a supersession or duplicate claim.** Semantic findings without quoted grounding
155
+ do not get written. "I'm not sure these are duplicates — confirm?" is correct; asserting it is not.
156
+ - **Don't add items to the backlog.** The report is transient; it never becomes a `.work/backlog/`
157
+ file. Grooming reduces entropy, it does not produce more items to triage.
158
+ - **Don't re-decide terminal disposition.** Inherit `Terminal-tier retention`; an unrecognized
159
+ value defaults to keeping the body (safe) with a warning, exactly as the release/review paths do.
160
+ - **Don't impose a cadence.** Invocation-driven; schedulability is a deployment choice.
161
+ - **Inert without opt-in.** The staleness face requires `backlog_staleness_days`; absent, it
162
+ reports inert and the other faces still run. The skill as a whole is a no-op unless invoked.
@@ -0,0 +1,6 @@
1
+ interface:
2
+ display_name: "Groom"
3
+ short_description: "Audit backlog hygiene — find stale, dead, duplicate, superseded items"
4
+ default_prompt: "Use $groom to audit the backlog for stale, dead, duplicate, and superseded items."
5
+ policy:
6
+ allow_implicit_invocation: true