@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.
- package/.claude-plugin/plugin.json +10 -0
- package/.codex-plugin/plugin.json +28 -0
- package/CHANGELOG.md +591 -0
- package/README.md +107 -0
- package/docs/ARCHITECTURE.md +716 -0
- package/docs/MIGRATION.md +419 -0
- package/docs/PRINCIPLES.md +464 -0
- package/docs/ROADMAP.md +95 -0
- package/docs/SPEC.md +855 -0
- package/docs/VISION.md +106 -0
- package/extensions/agile-workflow.test.ts +419 -0
- package/extensions/agile-workflow.ts +467 -0
- package/hooks/hooks.json +52 -0
- package/hooks/scripts/prompt-context.py +628 -0
- package/hooks/scripts/substrate-maintainer.py +359 -0
- package/hooks/scripts/test_prompt_context.py +757 -0
- package/package.json +30 -0
- package/scripts/install-work-view.sh +165 -0
- package/scripts/tests/agent-metadata.test.sh +75 -0
- package/scripts/tests/bump-version.test.sh +552 -0
- package/scripts/tests/channel-parity.test.sh +117 -0
- package/scripts/tests/convert-content-integrity.test.sh +246 -0
- package/scripts/tests/convert-install-routing.test.sh +159 -0
- package/scripts/tests/install-work-view.test.sh +411 -0
- package/scripts/tests/pi-package-metadata.test.sh +119 -0
- package/scripts/tests/work-board-shim.test.sh +239 -0
- package/scripts/tests/work-view-dist-version.test.sh +105 -0
- package/scripts/work-board.sh +64 -0
- package/scripts/work-view.sh +423 -0
- package/skills/autopilot/SKILL.md +330 -0
- package/skills/autopilot/agents/openai.yaml +6 -0
- package/skills/board/SKILL.md +62 -0
- package/skills/board/agents/openai.yaml +6 -0
- package/skills/bold-refactor/SKILL.md +244 -0
- package/skills/bold-refactor/agents/openai.yaml +6 -0
- package/skills/bug-scan/SKILL.md +378 -0
- package/skills/bug-scan/agents/openai.yaml +6 -0
- package/skills/bug-scan/references/async-promises.md +119 -0
- package/skills/bug-scan/references/concurrency-races.md +148 -0
- package/skills/bug-scan/references/data-layer.md +167 -0
- package/skills/bug-scan/references/error-handling.md +197 -0
- package/skills/bug-scan/references/gate-item-template.md +94 -0
- package/skills/bug-scan/references/language-footguns.md +219 -0
- package/skills/bug-scan/references/parked-item-template.md +103 -0
- package/skills/bug-scan/references/report-template.md +115 -0
- package/skills/bug-scan/references/resource-leaks.md +199 -0
- package/skills/bug-scan/references/state-closures.md +148 -0
- package/skills/bug-scan/references/time-numbers.md +158 -0
- package/skills/convert/SKILL.md +1463 -0
- package/skills/convert/agents/openai.yaml +6 -0
- package/skills/convert/references/legacy-overlap-migration.md +179 -0
- package/skills/deep-code-scan/SKILL.md +378 -0
- package/skills/deep-code-scan/agents/openai.yaml +6 -0
- package/skills/deep-code-scan/references/artifact-ledger.md +148 -0
- package/skills/deep-code-scan/references/consolidation.md +91 -0
- package/skills/deep-code-scan/references/decomposition.md +127 -0
- package/skills/deep-code-scan/references/item-templates.md +263 -0
- package/skills/deep-code-scan/references/lane-catalog.md +129 -0
- package/skills/deep-code-scan/references/review-gauntlet.md +108 -0
- package/skills/deep-code-scan/references/scanner-brief.md +152 -0
- package/skills/e2e-test-design/SKILL.md +517 -0
- package/skills/e2e-test-design/references/anti-tautology.md +261 -0
- package/skills/e2e-test-design/references/service-mocks.md +234 -0
- package/skills/e2e-test-design/references/test-taxonomy.md +211 -0
- package/skills/epic-design/SKILL.md +476 -0
- package/skills/epicize/SKILL.md +210 -0
- package/skills/epicize/agents/openai.yaml +6 -0
- package/skills/feature-design/SKILL.md +472 -0
- package/skills/fix/SKILL.md +173 -0
- package/skills/gate-cruft/SKILL.md +258 -0
- package/skills/gate-docs/SKILL.md +278 -0
- package/skills/gate-patterns/SKILL.md +389 -0
- package/skills/gate-refactor/SKILL.md +408 -0
- package/skills/gate-security/SKILL.md +275 -0
- package/skills/gate-tests/SKILL.md +367 -0
- package/skills/groom/SKILL.md +162 -0
- package/skills/groom/agents/openai.yaml +6 -0
- package/skills/ideate/SKILL.md +185 -0
- package/skills/ideate/agents/openai.yaml +6 -0
- package/skills/implement/SKILL.md +288 -0
- package/skills/implement-orchestrator/SKILL.md +604 -0
- package/skills/park/SKILL.md +111 -0
- package/skills/perf-design/SKILL.md +427 -0
- package/skills/perf-scout/SKILL.md +404 -0
- package/skills/perf-scout/agents/openai.yaml +6 -0
- package/skills/perf-scout/references/algorithmic-and-data-structures.md +126 -0
- package/skills/perf-scout/references/approximation-and-precomputation.md +136 -0
- package/skills/perf-scout/references/caching-and-memoization.md +123 -0
- package/skills/perf-scout/references/compiler-runtime-and-language.md +136 -0
- package/skills/perf-scout/references/database-and-storage-internals.md +144 -0
- package/skills/perf-scout/references/distributed-systems.md +150 -0
- package/skills/perf-scout/references/game-engine-and-realtime.md +136 -0
- package/skills/perf-scout/references/gpu-and-accelerators.md +130 -0
- package/skills/perf-scout/references/idea-ranking.md +75 -0
- package/skills/perf-scout/references/io-and-batching.md +135 -0
- package/skills/perf-scout/references/memory-and-data-locality.md +137 -0
- package/skills/perf-scout/references/parallelism-and-vectorization.md +126 -0
- package/skills/perf-scout/references/parked-item-template.md +117 -0
- package/skills/perf-scout/references/peer-review-pass.md +150 -0
- package/skills/perf-scout/references/report-template.md +148 -0
- package/skills/principles/SKILL.md +678 -0
- package/skills/principles/references/models.md +191 -0
- package/skills/principles/references/subagents.md +158 -0
- package/skills/prose-author/SKILL.md +185 -0
- package/skills/refactor-conventions-creator/SKILL.md +359 -0
- package/skills/refactor-conventions-creator/agents/openai.yaml +6 -0
- package/skills/refactor-conventions-creator/references/common-structures.md +91 -0
- package/skills/refactor-conventions-creator/references/common-styles.md +90 -0
- package/skills/refactor-design/SKILL.md +384 -0
- package/skills/release-deploy/SKILL.md +667 -0
- package/skills/release-deploy/agents/openai.yaml +6 -0
- package/skills/research/SKILL.md +166 -0
- package/skills/research/agents/openai.yaml +6 -0
- package/skills/review/SKILL.md +267 -0
- package/skills/review/references/deep-review.md +98 -0
- package/skills/review/references/review-lenses.md +68 -0
- package/skills/review/references/substrate-side-effects.md +161 -0
- package/skills/review/references/target-resolution.md +52 -0
- package/skills/scope/SKILL.md +486 -0
- package/work-view/Cargo.lock +486 -0
- package/work-view/Cargo.toml +9 -0
- package/work-view/crates/cli/.work-view-version +1 -0
- package/work-view/crates/cli/Cargo.toml +18 -0
- package/work-view/crates/cli/src/actionable.rs +500 -0
- package/work-view/crates/cli/src/args.rs +792 -0
- package/work-view/crates/cli/src/board/assets/board.css +855 -0
- package/work-view/crates/cli/src/board/assets/board.js +259 -0
- package/work-view/crates/cli/src/board/assets/card.js +139 -0
- package/work-view/crates/cli/src/board/assets/components.css +290 -0
- package/work-view/crates/cli/src/board/assets/dependency.js +1193 -0
- package/work-view/crates/cli/src/board/assets/detail.js +256 -0
- package/work-view/crates/cli/src/board/assets/filters.js +389 -0
- package/work-view/crates/cli/src/board/assets/index.html +77 -0
- package/work-view/crates/cli/src/board/assets/kanban.js +231 -0
- package/work-view/crates/cli/src/board/assets/markdown.js +260 -0
- package/work-view/crates/cli/src/board/assets/motion.css +131 -0
- package/work-view/crates/cli/src/board/assets/state.js +245 -0
- package/work-view/crates/cli/src/board/assets/table.js +304 -0
- package/work-view/crates/cli/src/board/assets/tokens.css +602 -0
- package/work-view/crates/cli/src/board/assets/views.js +41 -0
- package/work-view/crates/cli/src/board/assets.rs +162 -0
- package/work-view/crates/cli/src/board/feed.rs +204 -0
- package/work-view/crates/cli/src/board/mod.rs +246 -0
- package/work-view/crates/cli/src/board/open.rs +144 -0
- package/work-view/crates/cli/src/board/server.rs +407 -0
- package/work-view/crates/cli/src/main.rs +195 -0
- package/work-view/crates/cli/src/render.rs +354 -0
- package/work-view/crates/cli/src/scope.rs +157 -0
- package/work-view/crates/cli/src/stale.rs +581 -0
- package/work-view/crates/cli/tests/board-js/dependency-table.test.mjs +64 -0
- package/work-view/crates/cli/tests/board-js/expanded-browsing.test.mjs +79 -0
- package/work-view/crates/cli/tests/board-js/harness-smoke.test.mjs +11 -0
- package/work-view/crates/cli/tests/board-js/harness.mjs +437 -0
- package/work-view/crates/cli/tests/board-js/kanban-detail.test.mjs +75 -0
- package/work-view/crates/cli/tests/board-js/markdown-filter.test.mjs +60 -0
- package/work-view/crates/cli/tests/fixtures/golden/.work/CONVENTIONS.md +3 -0
- package/work-view/crates/cli/tests/fixtures/golden/.work/active/epics/epic-alpha.md +16 -0
- package/work-view/crates/cli/tests/fixtures/golden/.work/active/features/feat-a.md +16 -0
- package/work-view/crates/cli/tests/fixtures/golden/.work/active/features/feat-b.md +16 -0
- package/work-view/crates/cli/tests/fixtures/golden/.work/active/stories/story-alpha-1.md +16 -0
- package/work-view/crates/cli/tests/fixtures/golden/.work/active/stories/story-research-1.md +19 -0
- package/work-view/crates/cli/tests/fixtures/golden/.work/archive/feat-done.md +16 -0
- package/work-view/crates/cli/tests/fixtures/golden/.work/archive/feat-shipped.md +18 -0
- package/work-view/crates/cli/tests/fixtures/golden/.work/backlog/idea-backlog.md +7 -0
- package/work-view/crates/cli/tests/fixtures/golden/.work/releases/v1.0/v1.0.md +16 -0
- package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/CONVENTIONS.md +6 -0
- package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/active/features/feat-dep-done.md +17 -0
- package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/active/features/feat-design-ready.md +17 -0
- package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/active/features/feat-impl-ready.md +17 -0
- package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/active/stories/story-review-ready.md +17 -0
- package/work-view/crates/cli/tests/fixtures/with-malformed/.work/CONVENTIONS.md +4 -0
- package/work-view/crates/cli/tests/fixtures/with-malformed/.work/active/epics/malformed-no-closing-fence.md +8 -0
- package/work-view/crates/cli/tests/fixtures/with-malformed/.work/active/features/good-item.md +16 -0
- package/work-view/crates/cli/tests/integration.rs +2833 -0
- package/work-view/crates/core/Cargo.toml +13 -0
- package/work-view/crates/core/src/error.rs +61 -0
- package/work-view/crates/core/src/filter.rs +804 -0
- package/work-view/crates/core/src/graph.rs +324 -0
- package/work-view/crates/core/src/index.rs +590 -0
- package/work-view/crates/core/src/lib.rs +54 -0
- package/work-view/crates/core/src/model.rs +202 -0
- package/work-view/crates/core/src/parse.rs +494 -0
- package/work-view/crates/core/tests/fixtures/golden/.work/CONVENTIONS.md +15 -0
- package/work-view/crates/core/tests/fixtures/golden/.work/active/epics/epic-core.md +16 -0
- package/work-view/crates/core/tests/fixtures/golden/.work/active/features/feat-parser.md +16 -0
- package/work-view/crates/core/tests/fixtures/golden/.work/active/features/feat-query.md +16 -0
- package/work-view/crates/core/tests/fixtures/golden/.work/active/stories/malformed-no-id.md +15 -0
- package/work-view/crates/core/tests/fixtures/golden/.work/active/stories/story-parse-unit.md +16 -0
- package/work-view/crates/core/tests/fixtures/golden/.work/active/stories/story-security-gate.md +16 -0
- package/work-view/crates/core/tests/fixtures/golden/.work/archive/feat-old.md +16 -0
- package/work-view/crates/core/tests/fixtures/golden/.work/archive/feat-parser.md +17 -0
- package/work-view/crates/core/tests/fixtures/golden/.work/backlog/idea-future-board.md +7 -0
- package/work-view/crates/core/tests/fixtures/golden/.work/releases/v1.0/v1.0.md +16 -0
- package/work-view/crates/core/tests/fixtures/precedence/.work/CONVENTIONS.md +10 -0
- package/work-view/crates/core/tests/fixtures/precedence/.work/archive/dup-item.md +18 -0
- package/work-view/crates/core/tests/fixtures/precedence/.work/releases/v2.0/dup-item.md +18 -0
- package/work-view/crates/core/tests/integration.rs +541 -0
- package/work-view/dist/.gitattributes +1 -0
- package/work-view/dist/README.md +42 -0
- package/work-view/dist/aarch64-apple-darwin/work-view +0 -0
- package/work-view/dist/aarch64-unknown-linux-musl/work-view +0 -0
- package/work-view/dist/x86_64-apple-darwin/work-view +0 -0
- 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
|