@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,129 @@
1
+ # Lane Catalog — what each lane reuses
2
+
3
+ A **lane** is a scan domain the user selected at kickoff; it becomes a feature. Each lane points at
4
+ **existing reference knowledge** the scanners load (so this skill never re-derives pattern catalogs)
5
+ and at the **standalone alternative** — the specialist skill to run *instead of* a campaign when the
6
+ user only needs that one domain. **In-campaign, lanes are references-only**; do not invoke the
7
+ specialist skills mid-campaign (most mint/commit their own items and would bypass the gauntlet).
8
+ Paths are relative to the repo's plugin root (`plugins/`).
9
+
10
+ ## The lanes
11
+
12
+ ### correctness
13
+ - **References (scanner load):** `agile-workflow/skills/bug-scan/references/` — the 8 domains:
14
+ `concurrency-races.md`, `async-promises.md`, `state-closures.md`, `resource-leaks.md`,
15
+ `time-numbers.md`, `error-handling.md`, `data-layer.md`, `language-footguns.md`.
16
+ - **Per-altitude fan-out:** split scanners by `bug-domain × component`. Use bug-scan's own relevance
17
+ test (Phase 2) to skip domains a component can't have (no async → no async scanner).
18
+ - **Standalone alternative:** `/agile-workflow:bug-scan <path>`.
19
+
20
+ ### tests
21
+ - **References (scanner method):** `agile-workflow/skills/gate-tests` — derive *expected* coverage
22
+ from behavior / acceptance criteria / public contracts (NOT from the implementation), map existing
23
+ test coverage, and find the deltas. Reuse its priority rubric (Critical = acceptance criterion with
24
+ no test; High = boundary/error case with no test; Medium = valid partition/rule combo with no test;
25
+ Low = complementary coverage).
26
+ - **What this lane hunts (broader than the release gate):** *test gaps* (uncovered behavior, edges,
27
+ error paths), *bad tests* (asserting on implementation not behavior, weak/empty assertions,
28
+ over-mocking, tautological `expect(true)`), *test issues* (stale fixtures, broken/leaky mocks,
29
+ flaky/timing-dependent tests, order-dependence), and *test improvements* (missing harness, property
30
+ or fuzz opportunities, e2e coverage). For e2e program work specifically, hand off to
31
+ `/agile-workflow:e2e-test-design`.
32
+ - **Altitude:** `module → subsystem → system`. Tests are assessed against a component's behavior, so
33
+ there is rarely a leaf-level test-scan story worth minting.
34
+ - **Spec-source hierarchy + finding shape.** Unlike `gate-tests` (which reads a bound item's
35
+ acceptance criteria), a campaign tests-scanner often has no bound spec. Derive *expected* behavior
36
+ in this order: acceptance criteria of a related item → public contract / signatures / docstrings →
37
+ observable behavior inferred from the code. **If no spec source exists at all, emit a
38
+ documentation/spec gap, NOT an implementation-derived "test gap"** (a test asserting whatever the
39
+ code happens to do is the bad-test failure mode this lane hunts). The tests-lane finding records the
40
+ *missing/weak test and the expected behavior + its source*, not "offending code" — the generic
41
+ scanner evidence field doesn't fit "no test exists", so describe the uncovered contract instead.
42
+ - **Intent-lens note:** respect the project's test-integrity rules (a `skip`/`xfail` linked to a
43
+ backlog id documenting a real bug is *honest*, not a gap — do not "fix" it into a green lie).
44
+ - **Standalone alternative:** `/agile-workflow:gate-tests`.
45
+
46
+ ### performance
47
+ - **References:** `agile-workflow/skills/perf-scout/references/` — the 11 lenses (algorithmic,
48
+ memory/data-locality, parallelism/vectorization, gpu, caching, io/batching, distributed,
49
+ game-engine/realtime, database-internals, compiler/runtime, approximation) plus `idea-ranking.md`
50
+ and `peer-review-pass.md`.
51
+ - **Note:** perf findings are *speculative ideas*, ranked, not severities-as-bugs. Carry perf-scout's
52
+ ranking tiers into the finding severity and lean on its peer-review-pass — it dovetails with the
53
+ review gauntlet.
54
+ - **Standalone alternative:** `/agile-workflow:perf-scout <path>`.
55
+
56
+ ### quality / holistic
57
+ - **References:** `code-audit/skills/repo-eval/references/` — the 9 dimensions + scoring rubric +
58
+ verification-checks.
59
+ - **Note:** this lane *scores*, it doesn't only list findings. Best at the `subsystem`/`system`
60
+ bands where holistic judgment applies; weak at `leaf`. Often run as one or two high-altitude
61
+ stories rather than a full leaf→system spine.
62
+ - **Standalone alternative:** `/code-audit:repo-eval <path>`.
63
+
64
+ ### structure / refactor
65
+ - **References:** `agile-workflow/skills/refactor-design` discovery heuristics + any project
66
+ `.agents/skills/refactor-conventions/`.
67
+ - **Hard intent guard:** the **black-box test** applies — a finding here must be behavior-preserving.
68
+ And documented deliberate patterns (`.agents/skills/patterns/`) are *not* refactor findings. This
69
+ lane is the most prone to goal-fighting fixes; the gauntlet's Intent lens is non-optional for it.
70
+ - **Standalone alternative:** `/agile-workflow:refactor-design <path>`.
71
+
72
+ ### architecture / bold-refactor
73
+ - **References (scanner load):** `agile-workflow/skills/bold-refactor` — the conceptual lenses
74
+ (elimination, unification, inversion, algebraic, declarative, domain crystallization) plus its
75
+ "Beneath you: generic LLM refactoring" anti-pattern list. This lane finds **bold reconceptions**
76
+ ("what single idea would make half this code unnecessary?"), not cleanups.
77
+ - **Altitude:** `subsystem` and `system` ONLY — a reconception needs a whole subsystem in view;
78
+ there is no leaf-level bold refactor. Usually one or two high-altitude stories.
79
+ - **Highest goal-fighting risk of any lane.** Bold reconceptions are by nature "you've been doing
80
+ this wrong" proposals — exactly the findings most likely to fight a deliberate design philosophy.
81
+ The gauntlet's **Intent lens is mandatory and strict here**: a reconception that contradicts a
82
+ documented pattern (`.agents/skills/patterns/`) or stated architecture is a *contested* finding for
83
+ a human, never an auto-emitted fix. Use bold-refactor's anti-pattern list in reverse too — reject
84
+ timid extractions masquerading as bold findings.
85
+ - **Do NOT invoke `bold-refactor` in-campaign.** It materializes and commits its own `[refactor]`
86
+ epic — which would bypass this campaign's gauntlet (the very gate this highest-risk lane needs most)
87
+ and create an epic competing with `fix-<goal>`. In-campaign, load its lenses + anti-pattern list as
88
+ scanner knowledge only; every architecture finding flows through Gate 1/Gate 2 and emits solely via
89
+ `fix-<goal>`. `/agile-workflow:bold-refactor` is the **standalone alternative** — run it *instead of*
90
+ a campaign when the user wants a pure architectural pass and is fine with its own epic + flow.
91
+
92
+ ### security
93
+ - **References:** the security domains `gate-security` selects (auth, injection, secrets, deps, API,
94
+ infra, crypto, data-protection, error-handling). Reuse its audit method.
95
+ - **Standalone alternative:** `/agile-workflow:gate-security` (gate-scoped) or a scoped
96
+ security scanner brief.
97
+
98
+ ### custom (free-form goal)
99
+ - **References:** none prebuilt. Build a bespoke scanner brief from the user's goal — name the
100
+ concrete signal to hunt ("every site that spawns a task without awaiting/cancelling it"), give
101
+ detection heuristics, and require in-context confirmation like every other lane.
102
+ - **Specialist:** none — this is the case the campaign uniquely serves.
103
+
104
+ ## Choosing a lane's story spine
105
+
106
+ Not every lane wants the full `leaf → module → subsystem → system` spine:
107
+
108
+ - **correctness / security** — full spine; bugs and vulns live at every altitude.
109
+ - **tests** — `module → subsystem → system`; coverage is judged against component behavior.
110
+ - **performance** — usually `module → subsystem → system`; single-line leaf micro-opts rarely earn a
111
+ story (let perf-scout handle those directly).
112
+ - **quality / holistic** — `subsystem → system` only; holistic scoring needs altitude.
113
+ - **structure / refactor** — `leaf → module` mostly; cross-cutting refactors are rare and risky.
114
+ - **architecture / bold** — `subsystem → system` only; reconceptions need altitude, and the lane is
115
+ the highest-risk for goal-fighting fixes.
116
+
117
+ Confirm the per-lane spine at the Phase 3 checkpoint — it's part of the plan the user approves.
118
+
119
+ ## In-campaign: always fan out (never invoke the specialist)
120
+
121
+ In a campaign, scanning is **always** the scoped sub-agent fan-out that loads the lane's references.
122
+ Do **not** call the specialist skill mid-campaign, even when one component feels like "just run
123
+ repo-eval here." The specialists mint/commit their own `.work/` items and run their own (non-gauntlet)
124
+ flows — invoking them would create items outside `fix-<goal>` and skip the Reality/Context/Intent
125
+ gauntlet that every campaign finding must clear. The specialist column is the **standalone
126
+ alternative**: what the user runs *instead of* a campaign when one domain is all they need.
127
+
128
+ Never paste a specialist's pattern catalog into this skill or a scanner brief inline — point at the
129
+ reference file. The catalogs are maintained in their home skills; reuse keeps them single-sourced.
@@ -0,0 +1,108 @@
1
+ # The Review Gauntlet — multi-round adversarial culling before any fix ships
2
+
3
+ Auto-generated scan findings have three characteristic failure modes, and **all three produce
4
+ "fixes" that are worse than leaving the code alone**:
5
+
6
+ 1. **False positives** — the finding isn't real. A misread, a theoretical case that can't occur, or
7
+ something already handled elsewhere.
8
+ 2. **Context-ignorant fixes** — the finding is locally real but the proposed remediation ignores the
9
+ broader system: it breaks an invariant a caller relies on, duplicates an existing abstraction, or
10
+ "fixes" a symptom whose cause lives elsewhere.
11
+ 3. **Goal-fighting fixes** — the worst kind. The "fix" undoes a *deliberate* design choice. It
12
+ swaps the repo's hand-rolled, dependency-free parser for a library the project intentionally
13
+ avoids; it adds `thiserror` to a codebase whose convention is hand-written `Display`; it
14
+ "hardens" a fail-open probe that is fail-open *on purpose*. These regress the project while
15
+ looking like diligence.
16
+
17
+ The gauntlet exists to kill all three **before findings become fix items, and again on the drafted
18
+ fix epic**. It is iterative on purpose — one pass rationalizes; several passes in fresh context
19
+ converge on what's actually true.
20
+
21
+ ## The three lenses (every round applies all of them at `rigor ≥ standard`)
22
+
23
+ - **Reality** — *Is this a real problem that can actually occur here?* Re-read the cited code in
24
+ context. Reject theoretical-only, defensive-only-with-no-trigger, and already-mitigated findings.
25
+ - **Context** — *Does the fix respect the broader system?* Check the finding's `fix locality`
26
+ against callers, invariants, and existing abstractions. A `local` fix that violates a `module`- or
27
+ `cross-cutting`-level contract is rejected or escalated to the right altitude.
28
+ - **Intent** — *Does the finding or its fix fight the repo's actual goals?* Cross-check against the
29
+ project's stated intent and deliberate choices:
30
+ - `docs/VISION.md`, `docs/SPEC.md`, `docs/ARCHITECTURE.md` (or the project's foundation docs)
31
+ - `.work/CONVENTIONS.md` (tag taxonomy, design conventions)
32
+ - `.agents/skills/patterns/` and `.agents/rules/` — **documented deliberate patterns are not
33
+ findings**; a finding that contradicts a catalogued pattern is rejected unless it shows the
34
+ pattern itself is being misapplied.
35
+ - In-code comments that explain *why* (an explicit "intentionally fail-open" / "no deps by
36
+ design" comment is binding intent, not an oversight).
37
+
38
+ A finding that survives Reality and Context but fails Intent is **dropped with a note**, not
39
+ emitted — and the note feeds back so future scanners learn the boundary.
40
+
41
+ ## The loop
42
+
43
+ Run rounds until convergence or the rigor cap. **Independence is everything** — each round must be
44
+ genuinely fresh, or it just agrees with itself.
45
+
46
+ 1. **Round 1 — cross-model cull.** Hand the full finding set (with evidence + the project intent
47
+ sources above) to an independent reviewer, per agile-workflow's **advisory-review policy**: when a
48
+ *different* model class is available, use `peeragent` (pre-approved for cross-review); otherwise
49
+ fall back to a fresh-context same-harness sub-agent. The cross-model path is preferred but
50
+ **optional** — the gauntlet degrades to fresh-context review, never skips. For a deep or complex
51
+ campaign where two model classes are available, use **two distinct classes** — the first pass in
52
+ the advisory/completeness posture (is the finding set complete, anything missed?), the next in the
53
+ adversarial posture (which findings don't hold up?). Class selection and peer flags live in
54
+ [../../principles/references/models.md](../../principles/references/models.md). Either way the
55
+ reviewer scores every finding `keep | revise | drop` on all three lenses, with a one-line reason
56
+ each, and the ledger (below) is written regardless of which path ran.
57
+ 2. **Apply.** Drop the rejects. Revise the salvageable (often: re-scope the fix to the right
58
+ altitude, or soften "replace X" to "the real issue is Y"). Record every drop + reason in the
59
+ campaign ledger — dropped findings are evidence the gauntlet worked, not waste.
60
+ 3. **Round 2 — fresh-context re-review of survivors.** A *new* reviewer (different model again where
61
+ possible, no memory of round 1) reviews only the survivors. Does it still agree? New objections?
62
+ New drops/revisions restart the convergence check.
63
+ 4. **Repeat** until a round produces **no new drops or revisions** (converged) or the cap is hit:
64
+ - `rigor: floor` → 1 combined pass (Reality lens minimum).
65
+ - `rigor: standard` → ≥ 2 rounds, all three lenses, cross-model.
66
+ - `rigor: full` → rounds until convergence, cap 4, all three lenses, cross-model, fresh context
67
+ each round.
68
+ 5. **Persistent dissent → advisory, not forced.** A finding that keeps drawing objections across
69
+ rounds without resolving does **not** get forced into the fix epic. Demote it to an advisory note
70
+ on the scan epic ("flagged but contested — needs human judgment") so a person decides, rather
71
+ than shipping a fix the reviewers couldn't agree was correct.
72
+
73
+ ## Two gates, same gauntlet
74
+
75
+ - **Gate 1 — pre-consolidation** (end of Phase 4 / start of Phase 5): the raw finding set runs the
76
+ gauntlet so consolidation clusters only survivors.
77
+ - **Gate 2 — the drafted fix epic** (end of Phase 5, before emission): the *clustered plan* runs one
78
+ more gauntlet pass. Reviewers need a concrete artifact, so consolidation first persists a
79
+ **fix-epic draft packet** at `.work/scan-artifacts/scan-<goal>/fix-draft.md` — hand that path to
80
+ the reviewer. Clustering can introduce new context/intent problems (a feature that bundles three
81
+ findings may, as written, fight a goal none of the three did alone). The fix epic is materialized
82
+ into real `.work/` items **only after the packet passes**. After the durable `.work/` items and
83
+ campaign record are written, the artifact root is deleted.
84
+
85
+ ### Gate 2 verdict schema (per cluster)
86
+
87
+ Gate 2 reviews *clusters*, not raw findings, so it gets a verdict vocabulary to match. For each
88
+ proposed fix feature the reviewer returns one of:
89
+
90
+ - **keep** — cluster and its sequencing are sound.
91
+ - **revise** — keep the cluster, but the body/scope/Intent-constraints need the listed edits.
92
+ - **split** — the cluster bundles findings that don't share a remedy; break it into the named
93
+ sub-clusters.
94
+ - **drop** — the cluster shouldn't be fix work at all (its findings failed re-review on Reality/Intent
95
+ at the plan level; demote to advisory).
96
+
97
+ Each verdict carries its lens reason(s) and, for `revise`/`split`, the **required edits**.
98
+ **Convergence = a pass where no cluster needs `revise`/`split`/`drop`** (all `keep`), or the rigor
99
+ cap. Apply the edits to the packet between rounds; the packet — not your memory — is the artifact
100
+ that converges.
101
+
102
+ ## What lands in the ledger
103
+
104
+ For auditability, the scan epic body records, per round: how many findings entered, how many were
105
+ dropped and why (by lens), how many revised, and the convergence outcome. The point of the gauntlet
106
+ is partly the surviving fixes and partly the **documented reasons** the rejected ones didn't make
107
+ it — that record is what keeps the next campaign (and the human reading it) from re-litigating the
108
+ same non-issues.
@@ -0,0 +1,152 @@
1
+ # Scanner Dispatch — brief template, model diversity, finding schema
2
+
3
+ Scanners are the workers of an altitude story. Use a generic sub-agent prompted with the scanner posture from `../../principles/references/subagents.md`. They are **source-read-only**, **scoped to one component**, and **armed with the lane's
4
+ references**. Their only writes are their assigned artifact files. The orchestrator never re-does
5
+ their work.
6
+
7
+ ## Model diversity (the "different models in parallel" rule)
8
+
9
+ The lane's **scanner tier is locked at plan time** (the kickoff dial, recorded in the lane feature
10
+ body). Read it and honor it; the guidance below is what each tier means, with `mixed` as the
11
+ default. Whatever the scanner tier, the cross-model **gauntlet** (Verification) still runs on a
12
+ *different* class — independence there is non-negotiable.
13
+
14
+ Single-model fan-out gives single-model blind spots, so the default `mixed`
15
+ tier spreads the wave across the host's available model classes or reasoning
16
+ settings. Use stronger reviewer reasoning on dense, subtle, high-altitude, or
17
+ high-risk components; use the capable default for smaller leaf components and
18
+ high-volume waves. The `codex-high` and `codex-xhigh` tiers map directly to
19
+ Codex high and extra-high reasoning; other hosts should map those tiers to
20
+ their closest source-read-only reviewer/scanner settings.
21
+
22
+ The cross-model **adversarial** pass (Verification, `rigor ≥ standard`) should run on a *different*
23
+ model class than the bulk of the scanners — that is where `peeragent` fits, and it is pre-approved
24
+ for cross-review.
25
+
26
+ ## Dispatch rules
27
+
28
+ - All component-scanners for one altitude band go out in **one message** (parallel).
29
+ - Each scanner is scoped to **its component's file list only**, plus the **inherited findings** from
30
+ the band below (so wider scans reason about interactions, not re-find leaf bugs).
31
+ - If a scanner errors, record it as a coverage gap in the story body — do not blind-retry.
32
+ - If a scanner returns >25 findings, ask it to keep the top 25 by severity; a flood
33
+ usually means pattern over-matching.
34
+ - Scanners may write only their assigned artifact files under `.work/scan-artifacts/scan-<goal>/`.
35
+ They must not edit source files, `.work/active/` items, shared manifests, or another scanner's
36
+ paths.
37
+
38
+ ## Scanner brief template
39
+
40
+ > You are a **source-read-only scanner agent** for the **<lane>** lane at the **<band>** altitude.
41
+ > Follow the agile-workflow scanner contract: scoped inspection, caller-authorized artifacts only,
42
+ > no fixes, and no recursive sub-agents.
43
+ >
44
+ > **Scan goal (the campaign north star):** <goal — verbatim from the user>
45
+ > Everything you report must serve this goal. A finding outside the goal is noise.
46
+ >
47
+ > **Reference(s) — load FIRST and apply their named patterns:**
48
+ > <absolute paths from the lane catalog, e.g. bug-scan/references/concurrency-races.md>
49
+ >
50
+ > **Scope — scan ONLY these files:**
51
+ > ```
52
+ > <component file list>
53
+ > ```
54
+ >
55
+ > **Artifact paths — write ONLY these files:**
56
+ > - raw packet: `.work/scan-artifacts/scan-<goal>/raw/<lane>/<band>/<component>.md`
57
+ > - candidate findings: `.work/scan-artifacts/scan-<goal>/candidates/<lane>/<band>/<component>.jsonl`
58
+ > - status: `.work/scan-artifacts/scan-<goal>/status/<lane>/<band>/<component>.json`
59
+ >
60
+ > **Inherited findings from the band below (reason about interactions; don't re-report these):**
61
+ > ```
62
+ > <file:line + one-line summary pairs, or "none — this is the leaf band">
63
+ > ```
64
+ >
65
+ > **Stack profile:** <languages, frameworks, relevant primitives>
66
+ >
67
+ > **Method:**
68
+ > 1. Load the reference(s); note the patterns and detection signals relevant to the goal.
69
+ > 2. (If the lane calls for it) web-search 1–3 times for current pitfalls for this stack/version.
70
+ > 3. Apply the detection signals to the scope. Read every flagged site — **confirm in context**.
71
+ > Grep hits alone are not findings.
72
+ > 4. Consider how your component interacts with the inherited findings (a leaf bug may compose into
73
+ > a module-level hazard worth its own, higher-severity finding).
74
+ >
75
+ > **For each confirmed finding, return:**
76
+ > - **Title** (one line)
77
+ > - **Lane / Band**: <lane> / <band>
78
+ > - **Pattern**: named pattern from the reference, or "new"
79
+ > - **Severity**: Critical | High | Medium | Low (rubric below)
80
+ > - **Location**: `file:line`
81
+ > - **Evidence**: 1–5 lines of the offending code, fenced
82
+ > - **Why it matters** (1–2 sentences — the specific failure mode, tied to the goal)
83
+ > - **Remediation direction** (a direction, not a finished fix)
84
+ > - **Fix locality**: `local` (single site) | `module` (one component) | `cross-cutting` (spans
85
+ > components) — this feeds consolidation clustering.
86
+ >
87
+ > **Rules:** cite `file:line` for every finding; confirm in context; don't fabricate (empty is
88
+ > valid and honest); don't implement fixes; stay in scope; skip anything in the inherited list.
89
+ >
90
+ > **Write artifacts, then return only status:**
91
+ > 1. Write the raw packet markdown to the assigned raw packet path. The packet starts with
92
+ > `## <lane>/<band> — <component>`, then the findings, then a `## Summary` line.
93
+ > 2. Write candidate findings as JSONL to the assigned candidate path. Use one JSON object per
94
+ > confirmed finding; write an empty file if there are no findings.
95
+ > 3. Write the status JSON to the assigned status path, including counts and `status: "ok"` or
96
+ > `status: "error"`.
97
+ > 4. Return one terse line in chat: `wrote <raw> <candidates> <status>`.
98
+
99
+ **Lane-specific schemas override the generic fields above.** The `tests` lane is the notable case:
100
+ "Evidence" as *offending code* doesn't fit a *missing* test. A tests-lane finding instead records:
101
+ - **Title** · **Lane/Band** · **Severity** (gate-tests rubric) · **Location** (the under-tested
102
+ `file:line` / public symbol) · **Expected behavior + its source** (acceptance criterion / contract
103
+ / docstring — or "no spec source → this is a documentation/spec gap, not a test gap") ·
104
+ **What's missing or wrong** (no test / weak assertion / over-mock / stale fixture / flake) ·
105
+ **Suggested test** (direction) · **Fix locality**. See `lane-catalog.md` → tests.
106
+
107
+ ## Severity rubric (shared across lanes)
108
+
109
+ | Severity | Meaning |
110
+ |---|---|
111
+ | Critical | Will cause data loss/corruption/hang/wrong outcome (or, for non-correctness lanes, the lane's equivalent severe failure) under realistic conditions. Must fix. |
112
+ | High | Incorrect behavior, crash, or serious degradation under uncommon-but-real conditions. Must fix. |
113
+ | Medium | Real issue, hard to trigger or limited blast radius. Should fix; deferrable with acknowledgement. |
114
+ | Low | Edge case, latent, defensive-only. Backlog-grade. |
115
+ | Info | Not a finding. Do not return Info entries. |
116
+
117
+ Non-correctness lanes reuse the same five tiers with the lane's meaning of "severe" (a perf
118
+ finding's Critical is a dominant hot path; a security finding's Critical is actively exploitable —
119
+ defer to the specialist reference's own rubric where it has one).
120
+
121
+ ## Recording findings durably
122
+
123
+ Per band, do a **spot-check only** — you (the orchestrator), with full context, re-read the cited
124
+ code for each finding, drop grep-only or fabricated ones, and dedupe within the band. **Do not run
125
+ the multi-round cross-model gauntlet per band** — that fires once at Gate 1, after every lane/band
126
+ has scanned (see Verification in SKILL.md). Running it per band would multiply cost and converge on
127
+ local context the wider bands haven't seen yet.
128
+
129
+ Use the artifact ledger in `artifact-ledger.md`:
130
+
131
+ 1. Preallocate unique raw, candidate, and status paths for each scanner before dispatch.
132
+ 2. After the wave, verify every expected status file exists.
133
+ 3. Build or refresh the manifest from the per-scanner status files.
134
+ 4. Spot-check from the saved raw packet and candidate JSONL.
135
+ 5. Write accepted findings to `accepted/<lane>/<band>.jsonl`.
136
+ 6. Write the compact inheritance input to `rollups/<lane>/<band>.md`.
137
+ 7. Write the summary into the altitude story body under `## Findings`, grouped by severity, with
138
+ links to the raw packet(s) and rollup.
139
+
140
+ Low findings stay under their own advisory heading — not minted as backlog stubs. Advance the story
141
+ `implementing → review → done` once its band is scanned, spot-checked, and its artifact rollup is
142
+ written.
143
+
144
+ ### Rolling findings up to the next band
145
+
146
+ The orchestrator reads `rollups/<lane>/<band-below>.md` between bands (scanner agents are stateless) and
147
+ injects only the relevant subset into each next-band scanner's brief. The roll-up is
148
+ **deterministic by explicit component membership** (defined in the component map — file sets +
149
+ parent edges, see `decomposition.md`), not naive path prefix: a band-N component's inherited set =
150
+ every confirmed band-(N-1) finding whose `file` is in a child component's file set. A finding in a
151
+ file shared by two parents rolls up to **both**; a finding owned by no single higher component goes
152
+ to the **cross-cutting bucket** the `system` band always inherits — so nothing is silently dropped.