vouchington-tooling 0.20.0 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (257) hide show
  1. package/README.md +73 -10
  2. package/dist/agent-blackboard/snapshot-partition-format.mjs +2 -72
  3. package/dist/agent-blackboard/snapshot-partition-guards.d.mts +3 -0
  4. package/dist/agent-blackboard/snapshot-partition-guards.mjs +9 -0
  5. package/dist/agent-blackboard/snapshot-partition-predicates.d.mts +3 -0
  6. package/dist/agent-blackboard/snapshot-partition-predicates.mjs +65 -0
  7. package/dist/api-contract-discovery/header-contract-parser.d.mts +3 -0
  8. package/dist/api-contract-discovery/header-contract-parser.mjs +93 -0
  9. package/dist/api-contract-discovery/header-contract-registry.d.mts +3 -0
  10. package/dist/api-contract-discovery/header-contract-registry.mjs +38 -0
  11. package/dist/api-contract-discovery/header-contract-types.d.mts +19 -0
  12. package/dist/api-contract-discovery/header-contract-types.mjs +1 -0
  13. package/dist/api-contract-discovery/index.d.mts +31 -0
  14. package/dist/api-contract-discovery/index.mjs +26 -0
  15. package/dist/api-contract-discovery/query-contract-extraction.d.mts +3 -0
  16. package/dist/api-contract-discovery/query-contract-extraction.mjs +65 -0
  17. package/dist/api-contract-discovery/query-contract-literals.d.mts +8 -0
  18. package/dist/api-contract-discovery/query-contract-literals.mjs +54 -0
  19. package/dist/api-contract-discovery/query-contract-registry.d.mts +3 -0
  20. package/dist/api-contract-discovery/query-contract-registry.mjs +68 -0
  21. package/dist/api-contract-discovery/query-contract-types.d.mts +8 -0
  22. package/dist/api-contract-discovery/query-contract-types.mjs +1 -0
  23. package/dist/api-contract-discovery/registered-route-catalog.d.mts +10 -0
  24. package/dist/api-contract-discovery/registered-route-catalog.mjs +81 -0
  25. package/dist/api-contract-discovery/registered-route-handler-analysis.d.mts +2 -0
  26. package/dist/api-contract-discovery/registered-route-handler-analysis.mjs +74 -0
  27. package/dist/api-contract-discovery/request-contract-implicit.d.mts +17 -0
  28. package/dist/api-contract-discovery/request-contract-implicit.mjs +73 -0
  29. package/dist/api-contract-discovery/request-contract-lenient.d.mts +28 -0
  30. package/dist/api-contract-discovery/request-contract-lenient.mjs +59 -0
  31. package/dist/api-contract-discovery/request-contract-registry.d.mts +14 -0
  32. package/dist/api-contract-discovery/request-contract-registry.mjs +61 -0
  33. package/dist/api-contract-discovery/request-contract-route-analysis.d.mts +25 -0
  34. package/dist/api-contract-discovery/request-contract-route-analysis.mjs +68 -0
  35. package/dist/api-contract-discovery/request-contract-types.d.mts +12 -0
  36. package/dist/api-contract-discovery/request-contract-types.mjs +1 -0
  37. package/dist/api-contract-discovery/response-contract-ctx-analysis.d.mts +7 -0
  38. package/dist/api-contract-discovery/response-contract-ctx-analysis.mjs +28 -0
  39. package/dist/api-contract-discovery/response-contract-error-branch.d.mts +15 -0
  40. package/dist/api-contract-discovery/response-contract-error-branch.mjs +47 -0
  41. package/dist/api-contract-discovery/response-contract-implicit-sources.test-helpers.d.mts +145 -0
  42. package/dist/api-contract-discovery/response-contract-implicit-sources.test-helpers.mjs +145 -0
  43. package/dist/api-contract-discovery/response-contract-implicit.d.mts +5 -0
  44. package/dist/api-contract-discovery/response-contract-implicit.mjs +110 -0
  45. package/dist/api-contract-discovery/response-contract-lenient.d.mts +23 -0
  46. package/dist/api-contract-discovery/response-contract-lenient.mjs +52 -0
  47. package/dist/api-contract-discovery/response-contract-media.d.mts +3 -0
  48. package/dist/api-contract-discovery/response-contract-media.mjs +46 -0
  49. package/dist/api-contract-discovery/response-contract-registration.d.mts +11 -0
  50. package/dist/api-contract-discovery/response-contract-registration.mjs +61 -0
  51. package/dist/api-contract-discovery/response-contract-registry.d.mts +7 -0
  52. package/dist/api-contract-discovery/response-contract-registry.mjs +76 -0
  53. package/dist/api-contract-discovery/response-contract-route-analysis.d.mts +13 -0
  54. package/dist/api-contract-discovery/response-contract-route-analysis.mjs +144 -0
  55. package/dist/api-contract-discovery/response-contract-status.d.mts +27 -0
  56. package/dist/api-contract-discovery/response-contract-status.mjs +80 -0
  57. package/dist/api-contract-discovery/response-contract-types.d.mts +16 -0
  58. package/dist/api-contract-discovery/response-contract-types.mjs +1 -0
  59. package/dist/api-contract-discovery/test-setup.test-helpers.d.mts +3 -0
  60. package/dist/api-contract-discovery/test-setup.test-helpers.mjs +2 -0
  61. package/dist/ast-grep-examples/companion-parity-compare.d.mts +3 -0
  62. package/dist/ast-grep-examples/companion-parity-compare.mjs +58 -0
  63. package/dist/ast-grep-examples/companion-parity.d.mts +2 -1
  64. package/dist/ast-grep-examples/companion-parity.mjs +2 -58
  65. package/dist/browser-session-runner/attempt.mjs +29 -48
  66. package/dist/browser-session-runner/termination.d.mts +11 -0
  67. package/dist/browser-session-runner/termination.mjs +34 -0
  68. package/dist/cli/parse-direct-options.d.mts +26 -0
  69. package/dist/cli/parse-direct-options.mjs +72 -0
  70. package/dist/cli/parse-forwarded-commands.d.mts +42 -0
  71. package/dist/cli/parse-forwarded-commands.mjs +29 -0
  72. package/dist/cli/parse-options.d.mts +1 -2
  73. package/dist/cli/parse-options.mjs +2 -72
  74. package/dist/cli/parse.mjs +4 -26
  75. package/dist/compiler-build/freshness.d.mts +27 -0
  76. package/dist/compiler-build/freshness.mjs +116 -0
  77. package/dist/compiler-build/index.d.mts +2 -0
  78. package/dist/compiler-build/index.mjs +2 -0
  79. package/dist/compiler-build/settlement.d.mts +10 -0
  80. package/dist/compiler-build/settlement.mjs +14 -0
  81. package/dist/config-inventory/call-arguments.d.mts +1 -0
  82. package/dist/config-inventory/call-arguments.mjs +30 -0
  83. package/dist/config-inventory/collect.d.mts +3 -0
  84. package/dist/config-inventory/collect.mjs +43 -0
  85. package/dist/config-inventory/dynamic-configs.d.mts +2 -0
  86. package/dist/config-inventory/dynamic-configs.mjs +9 -0
  87. package/dist/config-inventory/env-expression-readers.d.mts +3 -0
  88. package/dist/config-inventory/env-expression-readers.mjs +117 -0
  89. package/dist/config-inventory/env-prefix-readers.d.mts +2 -0
  90. package/dist/config-inventory/env-prefix-readers.mjs +14 -0
  91. package/dist/config-inventory/env-reference-matchers.d.mts +3 -0
  92. package/dist/config-inventory/env-reference-matchers.mjs +9 -0
  93. package/dist/config-inventory/env-var-accumulator.d.mts +6 -0
  94. package/dist/config-inventory/env-var-accumulator.mjs +82 -0
  95. package/dist/config-inventory/env-vars.d.mts +4 -0
  96. package/dist/config-inventory/env-vars.mjs +108 -0
  97. package/dist/config-inventory/format.d.mts +2 -0
  98. package/dist/config-inventory/format.mjs +69 -0
  99. package/dist/config-inventory/index.d.mts +3 -0
  100. package/dist/config-inventory/index.mjs +2 -0
  101. package/dist/config-inventory/package-gates.d.mts +2 -0
  102. package/dist/config-inventory/package-gates.mjs +54 -0
  103. package/dist/config-inventory/shared.d.mts +3 -0
  104. package/dist/config-inventory/shared.mjs +7 -0
  105. package/dist/config-inventory/types.d.mts +96 -0
  106. package/dist/config-inventory/types.mjs +1 -0
  107. package/dist/contract-schema/contract-schema-bounded-array.d.mts +15 -0
  108. package/dist/contract-schema/contract-schema-bounded-array.mjs +32 -0
  109. package/dist/contract-schema/contract-schema-type-extractor.d.mts +2 -8
  110. package/dist/contract-schema/contract-schema-type-extractor.mjs +2 -31
  111. package/dist/coverage-transport/control-v2-parse-object.d.mts +12 -0
  112. package/dist/coverage-transport/control-v2-parse-object.mjs +28 -0
  113. package/dist/coverage-transport/control-v2.mjs +2 -27
  114. package/dist/dependency-license-policy/audit-directory.d.mts +28 -0
  115. package/dist/dependency-license-policy/audit-directory.mjs +115 -0
  116. package/dist/dependency-license-policy/audit-signals.d.mts +12 -0
  117. package/dist/dependency-license-policy/audit-signals.mjs +44 -0
  118. package/dist/dependency-license-policy/audit-store.d.mts +12 -0
  119. package/dist/dependency-license-policy/audit-store.mjs +32 -0
  120. package/dist/dependency-license-policy/collect.d.mts +3 -1
  121. package/dist/dependency-license-policy/collect.mjs +16 -21
  122. package/dist/dependency-license-policy/execute-pnpm.d.mts +10 -0
  123. package/dist/dependency-license-policy/execute-pnpm.mjs +83 -0
  124. package/dist/dependency-license-policy/types.d.mts +11 -9
  125. package/dist/dependency-license-policy/workspace.d.mts +3 -1
  126. package/dist/dependency-license-policy/workspace.mjs +12 -5
  127. package/dist/gh-api-shell-quoting/argument-scan.d.mts +7 -0
  128. package/dist/gh-api-shell-quoting/argument-scan.mjs +35 -0
  129. package/dist/gh-api-shell-quoting/logical-line.d.mts +3 -0
  130. package/dist/gh-api-shell-quoting/logical-line.mjs +90 -0
  131. package/dist/gh-api-shell-quoting/scan.d.mts +2 -4
  132. package/dist/gh-api-shell-quoting/scan.mjs +1 -119
  133. package/dist/gh-cli/diff.d.mts +24 -4
  134. package/dist/gh-cli/diff.mjs +111 -4
  135. package/dist/gh-cli/index.d.mts +2 -1
  136. package/dist/gh-cli/index.mjs +1 -1
  137. package/dist/gha-workspace-policy/docker-options.d.mts +4 -0
  138. package/dist/gha-workspace-policy/docker-options.mjs +93 -0
  139. package/dist/gha-workspace-policy/docker-workspace-user.mjs +1 -168
  140. package/dist/gha-workspace-policy/shell-token-modes.d.mts +10 -0
  141. package/dist/gha-workspace-policy/shell-token-modes.mjs +31 -0
  142. package/dist/gha-workspace-policy/shell-tokens.d.mts +1 -0
  143. package/dist/gha-workspace-policy/shell-tokens.mjs +65 -0
  144. package/dist/index.d.mts +2 -1
  145. package/dist/index.mjs +1 -1
  146. package/dist/openapi-document/contract-schema-types.d.mts +1 -1
  147. package/dist/openapi-document/openapi-types.d.mts +1 -1
  148. package/dist/pnpm-install/native-family.d.mts +3 -0
  149. package/dist/pnpm-install/native-family.mjs +31 -0
  150. package/dist/pnpm-install/native-health.d.mts +1 -4
  151. package/dist/pnpm-install/native-health.mjs +2 -31
  152. package/dist/retrospective-facts/local-merge.d.mts +2 -0
  153. package/dist/retrospective-facts/local-merge.mjs +21 -0
  154. package/dist/retrospective-facts/local.mjs +1 -21
  155. package/dist/retrospective-transcript/claude-blocks.d.mts +3 -0
  156. package/dist/retrospective-transcript/claude-blocks.mjs +38 -0
  157. package/dist/retrospective-transcript/claude.mjs +4 -34
  158. package/dist/retrospective-transcript/codex-payload.d.mts +2 -0
  159. package/dist/retrospective-transcript/codex-payload.mjs +51 -0
  160. package/dist/retrospective-transcript/codex-records.d.mts +2 -0
  161. package/dist/retrospective-transcript/codex-records.mjs +95 -0
  162. package/dist/retrospective-transcript/codex.mjs +2 -144
  163. package/dist/retrospective-transcript/index.d.mts +3 -16
  164. package/dist/retrospective-transcript/index.mjs +4 -48
  165. package/dist/retrospective-transcript/resolve-transcript-file.d.mts +19 -0
  166. package/dist/retrospective-transcript/resolve-transcript-file.mjs +50 -0
  167. package/dist/session-friction/command-segments.d.mts +3 -0
  168. package/dist/session-friction/command-segments.mjs +94 -0
  169. package/dist/session-friction/log-file.d.mts +7 -0
  170. package/dist/session-friction/log-file.mjs +83 -0
  171. package/dist/session-friction/log.mjs +3 -83
  172. package/dist/session-friction/normalize.mjs +1 -94
  173. package/dist/sql-scanner/comments.d.mts +1 -0
  174. package/dist/sql-scanner/comments.mjs +101 -0
  175. package/dist/sql-scanner/index.d.mts +1 -1
  176. package/dist/sql-scanner/index.mjs +1 -100
  177. package/dist/sql-scanner/literals.mjs +1 -35
  178. package/dist/sql-scanner/quote-decode.d.mts +2 -0
  179. package/dist/sql-scanner/quote-decode.mjs +35 -0
  180. package/dist/vitest-diagnostics/index.d.mts +7 -0
  181. package/dist/vitest-diagnostics/index.mjs +4 -0
  182. package/dist/vitest-diagnostics/vitest-fork-exit-error-detail.d.mts +7 -0
  183. package/dist/vitest-diagnostics/vitest-fork-exit-error-detail.mjs +26 -0
  184. package/dist/vitest-diagnostics/vitest-fork-exit-records.d.mts +26 -0
  185. package/dist/vitest-diagnostics/vitest-fork-exit-records.mjs +161 -0
  186. package/dist/vitest-diagnostics/vitest-fork-exit-sentinel.d.mts +14 -0
  187. package/dist/vitest-diagnostics/vitest-fork-exit-sentinel.mjs +131 -0
  188. package/dist/vitest-diagnostics/vitest-fork-leak-detection.d.mts +26 -0
  189. package/dist/vitest-diagnostics/vitest-fork-leak-detection.mjs +96 -0
  190. package/dist/vitest-diagnostics/vitest-fork-leak-diagnostics.d.mts +3 -0
  191. package/dist/vitest-diagnostics/vitest-fork-leak-diagnostics.mjs +14 -0
  192. package/dist/vitest-diagnostics/vitest-fork-leak-episode.d.mts +37 -0
  193. package/dist/vitest-diagnostics/vitest-fork-leak-episode.mjs +118 -0
  194. package/dist/vitest-diagnostics/vitest-worker-exit-diagnostics-errors.d.mts +2 -0
  195. package/dist/vitest-diagnostics/vitest-worker-exit-diagnostics-errors.mjs +42 -0
  196. package/dist/vitest-diagnostics/vitest-worker-exit-diagnostics-reporter.d.mts +12 -0
  197. package/dist/vitest-diagnostics/vitest-worker-exit-diagnostics-reporter.mjs +142 -0
  198. package/dist/workflow-policy/concurrency-scope.d.mts +4 -0
  199. package/dist/workflow-policy/concurrency-scope.mjs +66 -0
  200. package/dist/workflow-policy/concurrency.d.mts +10 -0
  201. package/dist/workflow-policy/concurrency.mjs +77 -0
  202. package/dist/workflow-policy/condition-entailment.d.mts +20 -0
  203. package/dist/workflow-policy/condition-entailment.mjs +132 -0
  204. package/dist/workflow-policy/condition-split.d.mts +15 -0
  205. package/dist/workflow-policy/condition-split.mjs +71 -0
  206. package/dist/workflow-policy/graph.d.mts +2 -0
  207. package/dist/workflow-policy/graph.mjs +138 -0
  208. package/dist/workflow-policy/index.d.mts +7 -0
  209. package/dist/workflow-policy/index.mjs +6 -0
  210. package/dist/workflow-policy/permission-mismatches.d.mts +3 -0
  211. package/dist/workflow-policy/permission-mismatches.mjs +52 -0
  212. package/dist/workflow-policy/permissions.d.mts +16 -0
  213. package/dist/workflow-policy/permissions.mjs +83 -0
  214. package/dist/workflow-policy/secret-readiness.d.mts +18 -0
  215. package/dist/workflow-policy/secret-readiness.mjs +163 -0
  216. package/dist/workflow-policy/shell-comments.d.mts +7 -0
  217. package/dist/workflow-policy/shell-comments.mjs +28 -0
  218. package/dist/workflow-policy/types.d.mts +90 -0
  219. package/dist/workflow-policy/types.mjs +1 -0
  220. package/dist/workspace-gates/manifest-version-parser.mjs +1 -52
  221. package/dist/workspace-gates/manifest-version-skips.d.mts +1 -0
  222. package/dist/workspace-gates/manifest-version-skips.mjs +52 -0
  223. package/docs/workflow-and-compiler.md +74 -0
  224. package/package.json +26 -2
  225. package/skills/agent-workflow/SKILL.md +4 -4
  226. package/skills/agent-workflow/references/review-response.md +47 -44
  227. package/skills/backend-vitest-test-authoring/SKILL.md +9 -6
  228. package/skills/blackboard/SKILL.md +8 -8
  229. package/skills/dependabot/SKILL.md +68 -67
  230. package/skills/dotnet-test-authoring/SKILL.md +11 -12
  231. package/skills/git-commit-checklist/SKILL.md +3 -3
  232. package/skills/github-actions-authoring/SKILL.md +40 -38
  233. package/skills/github-actions-checklist/SKILL.md +93 -85
  234. package/skills/github-issue/SKILL.md +82 -78
  235. package/skills/nextjs-vitest-test-authoring/SKILL.md +8 -6
  236. package/skills/npm-publishing/SKILL.md +42 -38
  237. package/skills/organize-github-issues/SKILL.md +18 -22
  238. package/skills/package-json-checklist/SKILL.md +5 -5
  239. package/skills/planning/SKILL.md +3 -3
  240. package/skills/playwright-authoring/SKILL.md +10 -9
  241. package/skills/postgres-node-performance-tuning/SKILL.md +10 -6
  242. package/skills/postgres-partitioning-uuid-v7/SKILL.md +10 -7
  243. package/skills/pr-description/SKILL.md +4 -3
  244. package/skills/retrospective/SKILL.md +14 -15
  245. package/skills/retrospective-distill/SKILL.md +14 -14
  246. package/skills/review-ci-logs/SKILL.md +18 -19
  247. package/skills/review-github-issue-taxonomy/SKILL.md +21 -18
  248. package/skills/revisit-followups/SKILL.md +3 -3
  249. package/skills/stacked-prs/SKILL.md +30 -61
  250. package/skills/static-analysis-checklist/SKILL.md +6 -4
  251. package/skills/storybook-authoring/SKILL.md +9 -9
  252. package/skills/swift-test-authoring/SKILL.md +10 -9
  253. package/skills/test-authoring/SKILL.md +14 -14
  254. package/skills/test-authoring/references/core-practice.md +12 -11
  255. package/skills/test-authoring/references/dependency-boundaries.md +36 -35
  256. package/skills/test-authoring/references/tautological-tests.md +45 -44
  257. package/skills/vitest-test-authoring/SKILL.md +9 -6
@@ -5,64 +5,33 @@ description: Recognize a native GitHub stacked pull request and drain it from th
5
5
 
6
6
  # Stacked pull requests
7
7
 
8
- Use whenever a change is submitted as a chain of native GitHub stacked pull requests instead of a
9
- single PR. Read local `AGENTS.md` and `CLAUDE.md` first: they own whether this repository adopts
10
- stacking at all, the tooling used to create, rebase, and merge a stack, and who may authorize a
11
- merge.
12
-
13
- A stack is a sequence of branches, each submitted as its own pull request, where every PR but the
14
- bottom-most one targets the PR below it as its base branch instead of targeting the default branch
15
- directly. GitHub tracks a chain like this as a single stack, and its own documentation on merging
16
- stacked pull requests is explicit about what a merge then does: "the selected pull request and all
17
- unmerged pull requests below it land on the base branch together as a single operation, ordered
18
- from the bottom up," and merging one is only possible once everything below it already satisfies
19
- whatever this repository requires to merge — you cannot merge an isolated middle layer on its own.
20
- That is dedicated stack-merge behavior, not the ordinary single-branch merge semantics a generic
21
- "merge this PR" action assumes, and it comes with its own restrictions: GitHub does not support
22
- auto-merge for stacked pull requests at all, and a plain, non-stack-aware merge mechanism is not
23
- guaranteed to reproduce this cascade correctly. A mid-stack PR's base ref being an unmerged branch,
24
- not the default branch, is the sign to slow down and confirm the merge path in use actually
25
- understands stacks before treating it as routine.
26
-
27
- Treat the forge's own view of a stack — its layers, their order, and each one's base — as the only
28
- reliable source for that structure, and re-read it immediately before acting rather than trusting a
29
- stacking tool's local record. Local metadata about a stack can go stale after a rebase, an
30
- out-of-band relink, or a manual recovery in ways nothing in the working tree reveals, so re-derive
31
- the current topology from the forge before rebasing, merging, or reporting on a stack, not once at
32
- the start of a session and not from memory of how it looked earlier.
33
-
34
- A stack is only as recoverable as its own foundation. If the bottom-most layer's base is not the
35
- default branch, the whole stack is built on unmerged work, and nothing above it can fully drain
36
- until that foundation either merges or the stack is re-rooted onto the default branch — confirm the
37
- root before treating any stack as one that can simply be worked down layer by layer.
38
-
39
- Drain a stack from the bottom, one layer at a time, merging each bottom-most layer as soon as it
40
- becomes ready rather than waiting for every layer above it to be ready first. A stack should stay as
41
- short as it can be: every layer that remains unmerged keeps accumulating rebase surface, CI cost,
42
- and drift against the default branch, and that cost compounds for every layer still stacked above
43
- it. Because stacked pull requests do not auto-merge, draining only happens through a deliberate
44
- merge action taken each time a layer becomes ready — nothing lands on its own just because it is
45
- ready.
46
-
47
- Merging a given layer lands that layer and every unmerged layer below it in the same operation, so
48
- whatever merge target is used must name the bottom-most unmerged layer specifically, not a higher
49
- one, to land exactly the increment intended for that drain step: naming a higher layer either merges
50
- more than intended, when everything below also happens to be ready, or is simply unavailable, when
51
- it is not. Once a layer merges, GitHub retargets the next unmerged layer onto the default branch
52
- directly, so it becomes the new bottom — treat it the same way on the next drain step.
53
-
54
- When a drain stalls — something on the stack needs human attention, or a layer closes without
55
- merging — but the bottom-most layer is otherwise ready to merge, stop before yielding: report the
56
- stack's current state layer by layer, and ask whether to merge that ready bottom layer before
57
- continuing. Do not leave a ready bottom layer sitting under a blocked or stalled upper layer without
58
- saying so.
59
-
60
- A stall belongs to the layer it happened on, not to the stack as a whole: keep readying every other
61
- layer whose progress does not depend on the blocked one, and pause the drain entirely only once
62
- nothing further can be readied without it. The same scoping applies to ownership — shepherd only the
63
- layers actually assigned to you, and treat any other layer in the same stack as something to report
64
- on, not to act on.
65
-
66
- Do not invent a default branch, a stacking tool or its command catalog, an exact merge-selector
67
- syntax, or a merge-authorization policy. A consumer wrapper or local instruction file owns those
68
- choices for this repository.
8
+ Use when a change is a chain of native GitHub stacked pull requests. Read local `AGENTS.md` and
9
+ `AGENTS.md` first. They own whether this repository stacks, which tool creates, rebases, and merges
10
+ a stack, and who may authorize a merge.
11
+
12
+ - Each pull request except the bottom one targets the pull request below it. The bottom pull
13
+ request targets the default branch.
14
+ - GitHub merges the selected pull request and every unmerged pull request below it, bottom-up, as
15
+ one operation. That merge is available only when everything below already meets this repository's
16
+ merge requirements. An isolated middle layer cannot merge.
17
+ - Auto-merge is unsupported. A non-stack merge is not a substitute.
18
+ - When a mid-stack pull request's base is an unmerged branch, confirm the merge path understands
19
+ stacks before merging.
20
+ - Re-read the forge's layers, order, and bases immediately before a rebase, merge, or status
21
+ report. Local stack metadata is stale after a rebase, relink, or manual recovery.
22
+ - The bottom layer's base must be the default branch. Otherwise merge that base or re-root the
23
+ stack onto the default branch before draining.
24
+ - Merge the bottom-most ready layer as soon as it is ready. Do not wait for layers above it.
25
+ Nothing in the stack merges on its own.
26
+ - Name that bottom-most unmerged layer as the merge target. Naming a higher layer merges more than
27
+ this step when everything below is also ready, and is unavailable when it is not.
28
+ - After a merge, GitHub retargets the next unmerged layer onto the default branch. That layer is
29
+ the new bottom.
30
+ - On a stall, or when a layer closes without merging, stop if the bottom layer is otherwise ready.
31
+ Report every layer and ask before merging that bottom layer.
32
+ - A stall blocks only layers that depend on it. Ready the others. Pause the whole drain only when
33
+ nothing further can be readied without the blocked layer.
34
+ - Act only on layers assigned to you. Report the other layers; do not change them.
35
+
36
+ Consumer wrapper owns: default branch, stacking tool and commands, merge-selector syntax, and
37
+ merge authorization.
@@ -5,14 +5,16 @@ description: Use when adding, changing, replacing, or removing static-analysis r
5
5
 
6
6
  # Static analysis checklist
7
7
 
8
- Use when changing a static-analysis invariant. Read local `AGENTS.md`, `CLAUDE.md`, analyzer
8
+ Use when changing a static-analysis invariant. Read local `AGENTS.md`, analyzer
9
9
  documentation, rule inventory, and fixture conventions before selecting an implementation.
10
10
 
11
11
  1. State the invariant and search for an existing analyzer, rule, or guard that owns it. Prefer the
12
12
  narrowest established owner over a parallel scanner.
13
- 2. For workflow or action policy, parse YAML instead of text matching and inspect only intended tracked
14
- configuration files. A persistent-workspace guard must reject sparse-checkout inputs and unsafe
15
- writable workspace mounts while allowing unrelated YAML keys and ordinary read-only mounts.
13
+ 2. For workflow or action policy, parse YAML instead of text matching. Inspect only intended
14
+ tracked configuration files. A persistent-workspace guard enforces
15
+ [github-actions-checklist](../github-actions-checklist/SKILL.md): reject sparse-checkout inputs
16
+ and unsafe writable workspace mounts, and allow unrelated YAML keys and ordinary read-only
17
+ mounts.
16
18
  3. Add meaningful accepted and rejected fixtures before the rule. Cover path routing, parser
17
19
  boundaries, equivalent YAML forms, and every allowed exception.
18
20
  4. Keep discovery limited to tracked, intended files. Make suppressions and allowlists narrow,
@@ -5,14 +5,14 @@ description: Add maintainable Storybook stories and browser-mode component cover
5
5
 
6
6
  # Storybook authoring
7
7
 
8
- Create stories that show meaningful supported states with realistic args and fixtures. Keep story
9
- data local and deterministic, expose important visual or interaction variants, and add browser-mode
10
- coverage where it catches behavior unavailable to unit tests. Do not use stories as a substitute for
11
- end-to-end setup or production data handling.
8
+ Apply [test-authoring](../test-authoring/SKILL.md).
12
9
 
13
- Consumer wrappers own Storybook configuration, exclusions, visual baselines, and commands.
10
+ - Show a meaningful supported state with realistic args and fixtures.
11
+ - Keep story data local and deterministic.
12
+ - Expose an important visual or interaction variant.
13
+ - Add browser-mode coverage where it catches behavior a unit test cannot see.
14
+ - Do not use a story as end-to-end setup or as production data handling.
15
+ - Read [component coverage](references/component-coverage.md) for direct stories and browser
16
+ isolation.
14
17
 
15
- Read [component coverage](references/component-coverage.md) for direct stories and browser isolation.
16
-
17
- Read [tautological tests](../test-authoring/references/tautological-tests.md) before finishing any
18
- interaction assertion that is not obviously falsifiable by a defect in the component under test.
18
+ Consumer wrapper owns: Storybook configuration, exclusions, visual baselines, and commands.
@@ -5,14 +5,15 @@ description: Add Swift and SwiftUI tests with deterministic state, networking, a
5
5
 
6
6
  # Swift test authoring
7
7
 
8
- Test public behavior with deterministic inputs and injected dependencies. For SwiftUI, inspect or
9
- interact through the project's supported test approach; for networking, use a protocol-level test
10
- double and keep request/response synchronization explicit. Avoid sleeps and global state, and keep
11
- fixtures small enough to make failures readable.
8
+ Apply [test-authoring](../test-authoring/SKILL.md).
12
9
 
13
- Consumer wrappers own test targets, coverage thresholds, view-inspection libraries, and fixture APIs.
10
+ - Test public behavior with deterministic inputs and injected dependencies.
11
+ - For SwiftUI, inspect or interact through the project's supported test approach.
12
+ - For networking, use a protocol-level test double. Keep request and response synchronization
13
+ explicit.
14
+ - Avoid sleeps and global state. Keep fixtures small enough that a failure is readable.
15
+ - Read [network test doubles](references/network-test-doubles.md) for cancellation and shared-state
16
+ safety.
14
17
 
15
- Read [network test doubles](references/network-test-doubles.md) for cancellation and shared-state safety.
16
-
17
- Read [tautological tests](../test-authoring/references/tautological-tests.md) before finishing any
18
- assertion that is not obviously falsifiable by a defect in the code under test.
18
+ Consumer wrapper owns: test targets, coverage thresholds, view-inspection libraries, and fixture
19
+ APIs.
@@ -5,19 +5,19 @@ description: Write focused, maintainable tests and test fixtures for application
5
5
 
6
6
  # Test authoring
7
7
 
8
- Use the repository's test conventions and runner skill. Test observable behavior, boundary failures,
9
- and regressions rather than implementation details. Build fixtures through public constructors or
10
- documented helpers; keep data minimal, explicit, and representative. Add a focused failing test
11
- before a behavior change when practical, then run the narrowest relevant test and required checks.
8
+ Use the repository's test conventions and the matching runner skill.
12
9
 
13
- Do not invent project test commands, coverage targets, mock libraries, or integration environments.
14
- A consumer wrapper owns those choices.
10
+ - Test observable behavior, boundary failures, and regressions. Do not test implementation details.
11
+ - Build fixtures through public constructors or documented helpers. Keep data minimal, explicit, and
12
+ representative.
13
+ - Add a focused failing test before a behavior change when that behavior can be tested. Then run the
14
+ narrowest relevant test and the required checks.
15
+ - Read [core practice](references/core-practice.md) before choosing a runner-specific approach.
16
+ - Read [tautological tests](references/tautological-tests.md) before finishing a test whose
17
+ assertion
18
+ is not obviously falsifiable by a defect in the code under test.
19
+ - Read [dependency boundaries](references/dependency-boundaries.md) before asserting on anything a
20
+ dependency produces, and whenever a dependency upgrade breaks a test.
15
21
 
16
- Read [core practice](references/core-practice.md) for the shared boundary, completion, and evidence
17
- rules before choosing a runner-specific approach.
18
-
19
- Read [tautological tests](references/tautological-tests.md) before finishing any test whose
20
- assertion is not obviously falsifiable by a defect in the code under test.
21
-
22
- Read [dependency boundaries](references/dependency-boundaries.md) before asserting on anything a
23
- dependency produces, and whenever a dependency upgrade breaks a test.
22
+ Consumer wrapper owns: project test commands, coverage targets, mock libraries, and integration
23
+ environments.
@@ -1,13 +1,14 @@
1
1
  # Core test practice
2
2
 
3
- Choose the lowest realistic boundary that can observe the contract. Mock external systems and
4
- uncontrolled infrastructure; exercise internal module composition where practical. Test behavior,
5
- failure paths, authorization, and security-relevant validation rather than private calls, and
6
- assert what this repository owns rather than what its [dependencies](dependency-boundaries.md)
7
- produce.
8
-
9
- Start with a failing test when the behavior is testable. Finish only when the production path, its
10
- public contract, documentation, and generated artifacts move together. Do not leave placeholders or
11
- test-only production branches. For every acceptance criterion, retain evidence from a focused test,
12
- review, or explicitly justified manual check — evidence only counts if it is falsifiable, so confirm
13
- the assertion is not [tautological](tautological-tests.md) before treating it as coverage.
3
+ - Choose the lowest realistic boundary that can observe the contract.
4
+ - Mock an external system or uncontrolled infrastructure. Exercise internal module composition where
5
+ that is practical.
6
+ - Test behavior, failure paths, authorization, and security-relevant validation. Do not reach it
7
+ through a private call. Assert what this repository owns, not what its
8
+ [dependencies](dependency-boundaries.md) produce.
9
+ - Start with a failing test when the behavior is testable.
10
+ - Finish only when the production path, its public contract, documentation, and generated artifacts
11
+ move together. Do not leave a placeholder or a test-only production branch.
12
+ - For every acceptance criterion, keep evidence from a focused test, a review, or an explicitly
13
+ justified manual check. Evidence counts only when it is falsifiable. Confirm the assertion is not
14
+ [tautological](tautological-tests.md) before treating it as coverage.
@@ -1,37 +1,38 @@
1
1
  # Dependency boundaries
2
2
 
3
- Test the code this repository owns. A dependency's behavior — its algorithms, error messages, output
4
- formats, internal file layout, exit codes, the URLs and query strings it builds, its pagination and
5
- retry strategy, and the order or number of calls it makes — belongs to that dependency's own tests.
6
- An assertion that pins any of it fails when the dependency ships a release rather than when this
7
- repository regresses, so every upgrade arrives as a red build that no change here caused.
8
-
9
- Apply the [tautological tests](tautological-tests.md) falsifiability check with ownership added: for
10
- every assertion, name a defect in this repository's code that would make it fail. If only a
11
- dependency release could fail it, delete it. If it covers owned logic but also pins incidental
12
- dependency detail, rewrite it to assert the owned outcome. What the repository chooses or promises
13
- is owned even when a dependency carries it out — the rules it enables, its thresholds and scopes,
14
- the arguments, endpoints, and parameters it passes, how it handles a dependency's exit codes and
15
- errors, and any call count or order its own logic requires — so test it, but through the
16
- dependency's public API rather than its internals.
17
-
18
- Watch for these shapes. A version-drift guard deep-imports a package's private files or calls its
19
- internal functions so the suite notices when upstream behavior changes; it couples the suite to a
20
- layout the package never promised, so delete it, and when documentation relies on dependency
21
- behavior, link to the dependency's own documentation instead of restating and pinning it. A
22
- dependency re-test runs a dependency with fabricated input and asserts what it returns; a wrapper
23
- that only forwards configuration needs one test proving the configuration arrives, not a second copy
24
- of the dependency's suite. An upstream-output pin asserts exact dependency-owned messages, markdown,
25
- JSON envelopes, or renderer markup when the owned contract is narrower; assert the rule identifier,
26
- status, or owned field instead. A sequence-bound fake answers by call order — chained one-shot mock
27
- responses, or a queue of canned replies consumed in turn — when the code under test does not own
28
- that order, so a dependency that adds a request, paginates differently, or reorders its calls hands
29
- the wrong reply to the wrong call; route the fake by request meaning, such as method and pathname,
30
- and assert the owned result rather than dependency-incidental URL, query-string, or call-count
31
- details.
32
-
33
- When a dependency upgrade breaks a test, first ask whether the test pinned dependency behavior. If
34
- it did, fix the test by deleting or rewriting it rather than re-pinning the new upstream value, and
35
- do not add a guard that fails on the next release. If the failure traces to owned code or owned
36
- configuration — the dependency now rejects arguments this repository passes, or returns a result
37
- this repository's logic mishandles — it is a real regression, so fix the owned code instead.
3
+ Test the code this repository owns. The dependency's own tests own its algorithms, error messages,
4
+ output formats, internal file layout, exit codes, the URLs and query strings it builds, its
5
+ pagination and retry strategy, and the order or number of calls it makes. An assertion that pins
6
+ any of that fails on a dependency release, not on a regression here.
7
+
8
+ Apply the [tautological tests](tautological-tests.md) check with ownership added. Name a defect in
9
+ this repository that would fail the assertion.
10
+
11
+ - If only a dependency release could fail it, delete it.
12
+ - If it covers owned logic and also pins incidental dependency detail, rewrite it to the owned
13
+ outcome.
14
+
15
+ Owned even when a dependency carries it out: enabled rules, thresholds, scopes, arguments,
16
+ endpoints, parameters, handling of the dependency's exit codes and errors, and any call count or
17
+ order this repository's logic requires. Test those through the dependency's public API.
18
+
19
+ Shapes:
20
+
21
+ - Version-drift guard: a deep import of private files, or a call to internal functions, so the
22
+ suite notices an upstream change. Delete it. When docs rely on dependency behavior, link to the
23
+ dependency's docs.
24
+ - Dependency re-test: fabricated input asserted against what the dependency returns. A wrapper that
25
+ only forwards configuration needs one test that the configuration arrives.
26
+ - Upstream-output pin: an exact dependency-owned message, markdown blob, JSON envelope, or renderer
27
+ markup when the owned contract is narrower. Assert the rule identifier, status, or owned field.
28
+ - Sequence-bound fake: one-shot responses, or a queue consumed in call order, when this repository
29
+ does not own that order. An added request, a pagination change, or a reorder then hands the wrong
30
+ reply to the wrong call. Route the fake by request meaning, such as method and pathname. Assert
31
+ the owned result, not an incidental URL, query string, or call count.
32
+
33
+ When a dependency upgrade breaks a test:
34
+
35
+ - If the test pinned dependency behavior, delete or rewrite it. Do not re-pin the new value. Do not
36
+ add a guard that fails on the next release.
37
+ - If owned code or configuration failed — the dependency rejects arguments this repository passes,
38
+ or returns a result this repository mishandles — fix the owned code.
@@ -1,46 +1,47 @@
1
1
  # Tautological tests
2
2
 
3
- A test is tautological when no defect in the code under test could make its assertion fail. Before
4
- trusting an assertion, name a concrete defect it would catch; if none exists, the assertion proves
5
- nothing regardless of how many lines it exercises. A test name is part of the assertion: `it('returns
6
- 200')` that never reads the status is itself the defect, since reviewers trust the name and skim the
7
- body instead of checking that it matches what is asserted.
8
-
9
- Watch for these shapes, most consequential first. A forced-value tautology transforms the result
10
- before asserting on the transformed constant, as in `expect(x.then(() => undefined))
11
- .resolves.toBeUndefined()`: the `.then` still depends on `x` fulfilling rather than rejecting, but
12
- every fulfillment value collapses to the same `undefined`, so the assertion no longer depends on what
13
- the code actually returned — ask whether the assertion still depends on the code's output, not merely
14
- on whether it threw; a test named after the data it claims to return is asserting nothing about that
15
- data. A literal tautology asserts a literal against itself, `expect(true).toBe(true)`, with
16
- equivalents in other runners (`XCTAssertTrue(true)`, `Assert.True(true)`). A self-comparison,
17
- `expect(x).toBe(x)`, and a literal echo that asserts on a value the test itself just wrote fail the
18
- same way: the input and the expectation are the same value with no code path in between. A mock echo
19
- asserts that a mock returns what it was configured to return, exercising the mock's configuration
20
- rather than the code under test. A re-implementation recomputes the production algorithm inside the
21
- test and compares the two computations, so a bug shared by both cancels out invisibly. A vacuous
22
- range or shape check — `expect(x.length).toBeGreaterThanOrEqual(0)`, or a `toBeDefined()`/`typeof`
23
- check on a static import or a value the test just constructed — holds for every possible output. A
24
- no-assert test awaits a call and asserts nothing afterward: it fails if the call throws, but nothing
25
- distinguishes a correct return value from an incorrect one, and an `expect-expect` lint rule will
26
- flag the missing assertion regardless.
27
-
28
- Coverage pressure is the usual root cause: a line must be covered and no assertion is obvious. Before
29
- reaching for a weak assertion, check whether the code takes a null- or error-swallowing path for the
30
- case under test — a repository-lookup helper that returns `null` instead of throwing for a not-found
31
- condition, for example — and assert the exact expected outcome for the case under test, such as
32
- `.toBeNull()` for the not-found path or a definite non-null shape for the found path, rather than a
33
- looser definedness check that would still pass if a regression collapsed the two. Otherwise assert
34
- the shape of the returned payload. Only when neither is available, fall back to an assertion that
35
- depends on nothing but successful completion, such as `await expect(run())
36
- .resolves.not.toBeInstanceOf(Error)`, paired with a test name that says "resolves" rather than
37
- "succeeds" or "returns 200" — a legitimately weak assertion, honestly labeled as weak. Satisfying a
38
- coverage percentage while asserting nothing is never acceptable; a 403 executes the same lines as a
39
- 200, and coverage tooling cannot tell them apart.
40
-
41
- Delete a tautological test if removing it does not reduce coverage; if it does, that test was the sole
42
- owner of that coverage and must be strengthened in place, not deleted, since a steady coverage number
43
- is not evidence the remaining tests check anything real. Consumer repositories may enforce the
44
- mechanical shapes above with ast-grep rules and an `expect-expect` lint rule; this document is the
45
- judgment layer for shapes those tools cannot express, such as a definedness check that needs dataflow
46
- analysis, a mock echo, or a re-implementation — tooling and this guidance should agree, not diverge.
3
+ A test is tautological when no defect in the code under test could make its assertion fail. Name a
4
+ concrete defect the assertion would catch. If none exists, the assertion proves nothing.
5
+
6
+ A test name is part of the assertion. `it('returns 200')` that never reads the status is the
7
+ defect: reviewers trust the name and skim the body.
8
+
9
+ Shapes, most consequential first:
10
+
11
+ - Forced-value: the test transforms the result, then asserts the transformed constant.
12
+ `expect(x.then(() => undefined)).resolves.toBeUndefined()` still depends on `x` fulfilling, but
13
+ every fulfillment value collapses to `undefined`. The assertion must depend on the code's output,
14
+ not only on whether it threw. A test named for returned data that never reads that data asserts
15
+ nothing about it.
16
+ - Literal: `expect(true).toBe(true)`, and the same shape in other runners (`XCTAssertTrue(true)`,
17
+ `Assert.True(true)`).
18
+ - Self-comparison: `expect(x).toBe(x)`.
19
+ - Literal echo: the test asserts a value it just wrote. Input and expectation are the same value,
20
+ with no code path between them.
21
+ - Mock echo: the assertion checks that a mock returns the value the test configured.
22
+ - Re-implementation: the test recomputes the production algorithm and compares the two results, so
23
+ a shared bug cancels out.
24
+ - Vacuous range or shape: `expect(x.length).toBeGreaterThanOrEqual(0)`, or `toBeDefined()` /
25
+ `typeof` on a static import or a value the test just constructed. It holds for every output.
26
+ - No-assert: the test awaits a call and asserts nothing afterward. It fails only when the call
27
+ throws. An `expect-expect` lint rule flags the missing assertion.
28
+
29
+ Coverage pressure is the usual cause: a line must be covered and no assertion is obvious.
30
+
31
+ - When the code returns null or swallows an error for the case under test, assert that exact
32
+ outcome, such as `.toBeNull()` for not-found or a definite non-null shape for found. A
33
+ definedness check still passes if a regression collapses the two paths.
34
+ - Otherwise assert the shape of the returned payload.
35
+ - Only when neither is available, assert completion alone, such as
36
+ `await expect(run()).resolves.not.toBeInstanceOf(Error)`, and name the test for resolving rather
37
+ than for success or a status code.
38
+ - A 403 can execute the same lines as a 200. Do not satisfy a coverage percentage with an
39
+ assertion that cannot fail.
40
+
41
+ Delete a tautological test when removing it does not reduce coverage. When removal drops coverage,
42
+ that test owns those lines: strengthen it in place. A steady coverage number does not show that the
43
+ remaining tests check anything.
44
+
45
+ Consumer repositories may enforce the mechanical shapes above with ast-grep and an `expect-expect`
46
+ rule. This document judges the shapes those tools cannot express: a definedness check that needs
47
+ dataflow analysis, a mock echo, or a re-implementation. Do not contradict the mechanical rules.
@@ -5,11 +5,14 @@ description: Apply Vitest-specific patterns when adding or changing Vitest tests
5
5
 
6
6
  # Vitest test authoring
7
7
 
8
- Apply [test-authoring](../test-authoring/SKILL.md) first. Keep tests isolated with Vitest lifecycle
9
- hooks, restore spies and globals after each test, and prefer deterministic async assertions over
10
- timing waits. Mock external boundaries rather than modules under test, and use typed factories when
11
- the project supplies them. Run the selected file or project before broader validation.
8
+ Apply [test-authoring](../test-authoring/SKILL.md) first.
12
9
 
13
- Consumer wrappers own project selection, mock boundaries, fixture names, and coverage policy.
10
+ - Isolate tests with Vitest lifecycle hooks. Restore spies and globals after each test.
11
+ - Prefer a deterministic async assertion over a timing wait.
12
+ - Mock an external boundary. Do not mock the module under test.
13
+ - Use a typed factory when the project supplies one.
14
+ - Run the selected file or project before broader validation.
15
+ - Read [mock boundaries](references/mock-boundaries.md) when adding a module mock or changing an
16
+ export.
14
17
 
15
- Read [mock boundaries](references/mock-boundaries.md) when adding module mocks or changing exports.
18
+ Consumer wrapper owns: project selection, mock boundaries, fixture names, and coverage policy.