@jiroamato/pstack 0.0.0-stage → 0.15.15

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 (225) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +78 -2
  3. package/bin/pstack.js +95 -0
  4. package/lib/install.js +103 -0
  5. package/lib/prompt.js +77 -0
  6. package/lib/targets.js +43 -0
  7. package/package.json +38 -5
  8. package/pstack/.claude-plugin/plugin.json +26 -0
  9. package/pstack/.codex-plugin/plugin.json +36 -0
  10. package/pstack/LICENSE +21 -0
  11. package/pstack/LICENSE-cursor-team-kit +21 -0
  12. package/pstack/NOTICE +8 -0
  13. package/pstack/README.md +300 -0
  14. package/pstack/agents/comment-sicko.md +34 -0
  15. package/pstack/agents/poteto-agent.md +10 -0
  16. package/pstack/automations/benny/FOR_AGENTS.md +92 -0
  17. package/pstack/automations/benny/README.md +28 -0
  18. package/pstack/automations/benny/skills/reproduce-and-fix-issues/SKILL.md +313 -0
  19. package/pstack/automations/benny/skills/reproduce-and-fix-issues/references/control-adapter.md +169 -0
  20. package/pstack/automations/benny/skills/reproduce-and-fix-issues/references/feature-map.example.md +205 -0
  21. package/pstack/automations/benny/skills/reproduce-and-fix-issues/references/verify-existing-fix.md +93 -0
  22. package/pstack/automations/benny/skills/setup-benny/SKILL.md +271 -0
  23. package/pstack/automations/benny/skills/triage-issue-reports/SKILL.md +240 -0
  24. package/pstack/automations/benny/skills/triage-issue-reports/references/routing.example.md +61 -0
  25. package/pstack/automations/benny/templates/configuration.example.yaml +84 -0
  26. package/pstack/automations/benny/templates/reproduce-automation-prompt.md +33 -0
  27. package/pstack/automations/benny/templates/triage-automation-prompt.md +39 -0
  28. package/pstack/codex/agents/comment-sicko.toml +36 -0
  29. package/pstack/codex/agents/poteto-agent.toml +11 -0
  30. package/pstack/docs/guide/01-setup.md +80 -0
  31. package/pstack/docs/guide/02-poteto-mode.md +131 -0
  32. package/pstack/docs/guide/03-understand.md +79 -0
  33. package/pstack/docs/guide/04-design.md +133 -0
  34. package/pstack/docs/guide/05-build-and-clean.md +83 -0
  35. package/pstack/docs/guide/06-verify-and-ship.md +130 -0
  36. package/pstack/docs/guide/07-overnight.md +120 -0
  37. package/pstack/docs/guide/08-principles.md +72 -0
  38. package/pstack/docs/guide/09-make-it-yours.md +100 -0
  39. package/pstack/docs/guide/10-recipes-and-pitfalls.md +156 -0
  40. package/pstack/docs/guide/README.md +38 -0
  41. package/pstack/skills/architect/SKILL.md +85 -0
  42. package/pstack/skills/architect/agents/openai.yaml +2 -0
  43. package/pstack/skills/architect/references/design-red-flags.md +57 -0
  44. package/pstack/skills/architect/references/rationale-template.md +35 -0
  45. package/pstack/skills/architect/references/runner-prompt.md +20 -0
  46. package/pstack/skills/arena/SKILL.md +75 -0
  47. package/pstack/skills/arena/agents/openai.yaml +2 -0
  48. package/pstack/skills/automate-me/SKILL.md +104 -0
  49. package/pstack/skills/automate-me/agents/openai.yaml +2 -0
  50. package/pstack/skills/benchmark-checklist/SKILL.md +39 -0
  51. package/pstack/skills/benchmark-checklist/agents/openai.yaml +2 -0
  52. package/pstack/skills/blast-radius/SKILL.md +52 -0
  53. package/pstack/skills/blast-radius/agents/openai.yaml +2 -0
  54. package/pstack/skills/bro/SKILL.md +7 -0
  55. package/pstack/skills/bro/agents/openai.yaml +2 -0
  56. package/pstack/skills/control-cli/SKILL.md +55 -0
  57. package/pstack/skills/control-cli/agents/openai.yaml +2 -0
  58. package/pstack/skills/control-ui/SKILL.md +72 -0
  59. package/pstack/skills/control-ui/agents/openai.yaml +2 -0
  60. package/pstack/skills/correct/SKILL.md +34 -0
  61. package/pstack/skills/correct/agents/openai.yaml +2 -0
  62. package/pstack/skills/create-verification-skill/SKILL.md +47 -0
  63. package/pstack/skills/create-verification-skill/agents/openai.yaml +2 -0
  64. package/pstack/skills/create-verification-skill/references/feature-map-example/README.md +47 -0
  65. package/pstack/skills/create-verification-skill/references/feature-map-example/create-note.md +39 -0
  66. package/pstack/skills/create-verification-skill/references/feature-map-example/search.md +45 -0
  67. package/pstack/skills/deslop/SKILL.md +30 -0
  68. package/pstack/skills/deslop/agents/openai.yaml +2 -0
  69. package/pstack/skills/figure-it-out/SKILL.md +55 -0
  70. package/pstack/skills/figure-it-out/agents/openai.yaml +2 -0
  71. package/pstack/skills/how/SKILL.md +58 -0
  72. package/pstack/skills/how/agents/openai.yaml +2 -0
  73. package/pstack/skills/how/references/explainer-prompt.md +55 -0
  74. package/pstack/skills/how/references/explorer-prompt.md +52 -0
  75. package/pstack/skills/interrogate/SKILL.md +111 -0
  76. package/pstack/skills/interrogate/agents/openai.yaml +2 -0
  77. package/pstack/skills/interrogate/references/code-quality-review.md +47 -0
  78. package/pstack/skills/interrogate/references/lead-judgment.md +58 -0
  79. package/pstack/skills/interrogate/references/reviewer-prompt.md +70 -0
  80. package/pstack/skills/interrogate/references/rubric.md +77 -0
  81. package/pstack/skills/maintain-verification-skill/SKILL.md +41 -0
  82. package/pstack/skills/maintain-verification-skill/agents/openai.yaml +2 -0
  83. package/pstack/skills/make-bot-ui/SKILL.md +289 -0
  84. package/pstack/skills/make-bot-ui/agents/openai.yaml +2 -0
  85. package/pstack/skills/no-comments/SKILL.md +24 -0
  86. package/pstack/skills/no-comments/agents/openai.yaml +2 -0
  87. package/pstack/skills/poteto-help/SKILL.md +156 -0
  88. package/pstack/skills/poteto-help/agents/openai.yaml +2 -0
  89. package/pstack/skills/poteto-help/references/prompting.md +51 -0
  90. package/pstack/skills/poteto-help/references/recipes.md +47 -0
  91. package/pstack/skills/poteto-mode/SKILL.md +143 -0
  92. package/pstack/skills/poteto-mode/agents/openai.yaml +2 -0
  93. package/pstack/skills/poteto-mode/playbooks/authoring-a-skill.md +12 -0
  94. package/pstack/skills/poteto-mode/playbooks/autonomous-run.md +13 -0
  95. package/pstack/skills/poteto-mode/playbooks/autopilot-full.md +13 -0
  96. package/pstack/skills/poteto-mode/playbooks/autopilot-stack.md +16 -0
  97. package/pstack/skills/poteto-mode/playbooks/babysit.md +29 -0
  98. package/pstack/skills/poteto-mode/playbooks/bug-fix.md +15 -0
  99. package/pstack/skills/poteto-mode/playbooks/eval.md +25 -0
  100. package/pstack/skills/poteto-mode/playbooks/feature.md +21 -0
  101. package/pstack/skills/poteto-mode/playbooks/hillclimb.md +21 -0
  102. package/pstack/skills/poteto-mode/playbooks/investigation.md +14 -0
  103. package/pstack/skills/poteto-mode/playbooks/multi-phase-plan.md +155 -0
  104. package/pstack/skills/poteto-mode/playbooks/opening-a-pr.md +38 -0
  105. package/pstack/skills/poteto-mode/playbooks/orchestrate.md +114 -0
  106. package/pstack/skills/poteto-mode/playbooks/pause-safely.md +10 -0
  107. package/pstack/skills/poteto-mode/playbooks/perf-issue.md +25 -0
  108. package/pstack/skills/poteto-mode/playbooks/prototype.md +14 -0
  109. package/pstack/skills/poteto-mode/playbooks/refactoring.md +16 -0
  110. package/pstack/skills/poteto-mode/playbooks/runtime-forensics.md +11 -0
  111. package/pstack/skills/poteto-mode/playbooks/session-pickup.md +11 -0
  112. package/pstack/skills/poteto-mode/playbooks/shipping.md +17 -0
  113. package/pstack/skills/poteto-mode/playbooks/trace-forensics.md +14 -0
  114. package/pstack/skills/poteto-mode/playbooks/visual-parity.md +11 -0
  115. package/pstack/skills/poteto-mode/playbooks/worktree-cleanup.md +14 -0
  116. package/pstack/skills/poteto-mode/references/bugbot-triage.md +142 -0
  117. package/pstack/skills/poteto-mode/scripts/bootstrap.ts +62 -0
  118. package/pstack/skills/poteto-mode/scripts/bun.lock +67 -0
  119. package/pstack/skills/poteto-mode/scripts/check-plan.mjs +185 -0
  120. package/pstack/skills/poteto-mode/scripts/orch/orch.test.ts +634 -0
  121. package/pstack/skills/poteto-mode/scripts/orch/orch.ts +578 -0
  122. package/pstack/skills/poteto-mode/scripts/orch/store.ts +1607 -0
  123. package/pstack/skills/poteto-mode/scripts/package.json +16 -0
  124. package/pstack/skills/poteto-mode/scripts/watch-pr/cli.test.ts +224 -0
  125. package/pstack/skills/poteto-mode/scripts/watch-pr/cli.ts +223 -0
  126. package/pstack/skills/poteto-mode/scripts/watch-pr/fakes.test-helper.ts +118 -0
  127. package/pstack/skills/poteto-mode/scripts/watch-pr/github.test.ts +306 -0
  128. package/pstack/skills/poteto-mode/scripts/watch-pr/github.ts +699 -0
  129. package/pstack/skills/poteto-mode/scripts/watch-pr/policy.test.ts +420 -0
  130. package/pstack/skills/poteto-mode/scripts/watch-pr/policy.ts +832 -0
  131. package/pstack/skills/poteto-mode/scripts/watch-pr/render.ts +169 -0
  132. package/pstack/skills/poteto-mode/scripts/watch-pr/tsconfig.json +13 -0
  133. package/pstack/skills/poteto-mode/scripts/watch-pr/types.compile.ts +93 -0
  134. package/pstack/skills/poteto-mode/scripts/watch-pr/types.ts +401 -0
  135. package/pstack/skills/poteto-mode/scripts/watch-pr/watch-pr +6 -0
  136. package/pstack/skills/poteto-mode/scripts/worktree-audit.sh +92 -0
  137. package/pstack/skills/principle-attack-the-premise/SKILL.md +23 -0
  138. package/pstack/skills/principle-attack-the-premise/agents/openai.yaml +2 -0
  139. package/pstack/skills/principle-boundary-discipline/SKILL.md +34 -0
  140. package/pstack/skills/principle-boundary-discipline/agents/openai.yaml +2 -0
  141. package/pstack/skills/principle-build-the-lever/SKILL.md +23 -0
  142. package/pstack/skills/principle-build-the-lever/agents/openai.yaml +2 -0
  143. package/pstack/skills/principle-encode-lessons-in-structure/SKILL.md +31 -0
  144. package/pstack/skills/principle-encode-lessons-in-structure/agents/openai.yaml +2 -0
  145. package/pstack/skills/principle-exhaust-the-design-space/SKILL.md +21 -0
  146. package/pstack/skills/principle-exhaust-the-design-space/agents/openai.yaml +2 -0
  147. package/pstack/skills/principle-experience-first/SKILL.md +19 -0
  148. package/pstack/skills/principle-experience-first/agents/openai.yaml +2 -0
  149. package/pstack/skills/principle-explain-the-number/SKILL.md +23 -0
  150. package/pstack/skills/principle-explain-the-number/agents/openai.yaml +2 -0
  151. package/pstack/skills/principle-fix-root-causes/SKILL.md +23 -0
  152. package/pstack/skills/principle-fix-root-causes/agents/openai.yaml +2 -0
  153. package/pstack/skills/principle-foundational-thinking/SKILL.md +21 -0
  154. package/pstack/skills/principle-foundational-thinking/agents/openai.yaml +2 -0
  155. package/pstack/skills/principle-guard-the-context-window/SKILL.md +16 -0
  156. package/pstack/skills/principle-guard-the-context-window/agents/openai.yaml +2 -0
  157. package/pstack/skills/principle-laziness-protocol/SKILL.md +18 -0
  158. package/pstack/skills/principle-laziness-protocol/agents/openai.yaml +2 -0
  159. package/pstack/skills/principle-make-operations-idempotent/SKILL.md +24 -0
  160. package/pstack/skills/principle-make-operations-idempotent/agents/openai.yaml +2 -0
  161. package/pstack/skills/principle-migrate-callers-then-delete-legacy-apis/SKILL.md +22 -0
  162. package/pstack/skills/principle-migrate-callers-then-delete-legacy-apis/agents/openai.yaml +2 -0
  163. package/pstack/skills/principle-minimize-reader-load/SKILL.md +23 -0
  164. package/pstack/skills/principle-minimize-reader-load/agents/openai.yaml +2 -0
  165. package/pstack/skills/principle-model-the-domain/SKILL.md +26 -0
  166. package/pstack/skills/principle-model-the-domain/agents/openai.yaml +2 -0
  167. package/pstack/skills/principle-never-block-on-the-human/SKILL.md +20 -0
  168. package/pstack/skills/principle-never-block-on-the-human/agents/openai.yaml +2 -0
  169. package/pstack/skills/principle-outcome-oriented-execution/SKILL.md +21 -0
  170. package/pstack/skills/principle-outcome-oriented-execution/agents/openai.yaml +2 -0
  171. package/pstack/skills/principle-prove-it-works/SKILL.md +22 -0
  172. package/pstack/skills/principle-prove-it-works/agents/openai.yaml +2 -0
  173. package/pstack/skills/principle-redesign-from-first-principles/SKILL.md +16 -0
  174. package/pstack/skills/principle-redesign-from-first-principles/agents/openai.yaml +2 -0
  175. package/pstack/skills/principle-separate-before-serializing-shared-state/SKILL.md +16 -0
  176. package/pstack/skills/principle-separate-before-serializing-shared-state/agents/openai.yaml +2 -0
  177. package/pstack/skills/principle-sequence-verifiable-units/SKILL.md +17 -0
  178. package/pstack/skills/principle-sequence-verifiable-units/agents/openai.yaml +2 -0
  179. package/pstack/skills/principle-subtract-before-you-add/SKILL.md +21 -0
  180. package/pstack/skills/principle-subtract-before-you-add/agents/openai.yaml +2 -0
  181. package/pstack/skills/principle-test-behavior-not-implementation/SKILL.md +25 -0
  182. package/pstack/skills/principle-test-behavior-not-implementation/agents/openai.yaml +2 -0
  183. package/pstack/skills/principle-type-system-discipline/SKILL.md +31 -0
  184. package/pstack/skills/principle-type-system-discipline/agents/openai.yaml +2 -0
  185. package/pstack/skills/pstack-harness/SKILL.md +67 -0
  186. package/pstack/skills/recall/SKILL.md +35 -0
  187. package/pstack/skills/recall/agents/openai.yaml +2 -0
  188. package/pstack/skills/reflect/SKILL.md +76 -0
  189. package/pstack/skills/reflect/agents/openai.yaml +2 -0
  190. package/pstack/skills/reflect/references/divergent-reviewer.md +43 -0
  191. package/pstack/skills/reflect/references/judgment-reviewer.md +42 -0
  192. package/pstack/skills/reflect/references/synthesizer.md +56 -0
  193. package/pstack/skills/reflect/references/tooling-reviewer.md +55 -0
  194. package/pstack/skills/setup-pstack/SKILL.md +110 -0
  195. package/pstack/skills/show-me-your-work/SKILL.md +82 -0
  196. package/pstack/skills/show-me-your-work/agents/openai.yaml +2 -0
  197. package/pstack/skills/show-me-your-work/references/decision-log-template.tsv +1 -0
  198. package/pstack/skills/show-me-your-work/scripts/log.sh +42 -0
  199. package/pstack/skills/swarm/SKILL.md +48 -0
  200. package/pstack/skills/swarm/agents/openai.yaml +2 -0
  201. package/pstack/skills/tdd/SKILL.md +44 -0
  202. package/pstack/skills/tdd/agents/openai.yaml +2 -0
  203. package/pstack/skills/teach/SKILL.md +21 -0
  204. package/pstack/skills/teach/agents/openai.yaml +2 -0
  205. package/pstack/skills/technical-writing/SKILL.md +106 -0
  206. package/pstack/skills/technical-writing/agents/openai.yaml +2 -0
  207. package/pstack/skills/typescript-best-practices/SKILL.md +31 -0
  208. package/pstack/skills/typescript-best-practices/agents/openai.yaml +2 -0
  209. package/pstack/skills/typescript-best-practices/references/patterns.md +324 -0
  210. package/pstack/skills/unslop/SKILL.md +67 -0
  211. package/pstack/skills/unslop/agents/openai.yaml +2 -0
  212. package/pstack/skills/why/SKILL.md +158 -0
  213. package/pstack/skills/why/agents/openai.yaml +2 -0
  214. package/pstack/skills/why/references/epistemics.md +144 -0
  215. package/pstack/skills/why/references/investigator-prompt.md +103 -0
  216. package/pstack/skills/why/references/source-playbook.md +17 -0
  217. package/pstack/skills/why/references/sources/code-archaeology.md +88 -0
  218. package/pstack/skills/why/references/sources/databricks.md +70 -0
  219. package/pstack/skills/why/references/sources/datadog.md +99 -0
  220. package/pstack/skills/why/references/sources/incident-postmortem.md +15 -0
  221. package/pstack/skills/why/references/sources/linear.md +48 -0
  222. package/pstack/skills/why/references/sources/notion.md +55 -0
  223. package/pstack/skills/why/references/sources/sentry.md +100 -0
  224. package/pstack/skills/why/references/sources/slack.md +54 -0
  225. package/pstack/skills/why/references/synthesizer-prompt.md +135 -0
@@ -0,0 +1,93 @@
1
+ # Verify an existing fix
2
+
3
+ Use this mode when an open pull request or merged commit plausibly fixes the report.
4
+
5
+ The existing artifact owns the fix. Verify it. Do not edit it, author a competing patch, or open another pull request.
6
+
7
+ ## Qualify the artifact
8
+
9
+ Require one concrete artifact:
10
+
11
+ - An open pull request with code changes that address the symptom
12
+ - A merged pull request
13
+ - A merged commit with matching code and intent
14
+
15
+ A thread claim, tracker status, branch name, or cause hypothesis without a pull request or commit is not enough.
16
+
17
+ When several artifacts exist, choose the one linked from the source thread or tracker. Otherwise choose the closest match to the affected code and state why.
18
+
19
+ ## Protect the working tree
20
+
21
+ Use an isolated worktree or another clean checkout when the repository supports it. Do not overwrite user changes.
22
+
23
+ Record:
24
+
25
+ - Baseline revision
26
+ - Patched revision
27
+ - Pull request or commit URL
28
+ - Build and environment inputs shared by both runs
29
+
30
+ Use regular `github.com` pull request links.
31
+
32
+ ## Measure the baseline
33
+
34
+ For an open pull request, use its base branch as the baseline.
35
+
36
+ For a merged fix, use the revision immediately before the fix when that revision builds and represents the old behavior.
37
+
38
+ Through the configured control adapter:
39
+
40
+ 1. Bring up the baseline app.
41
+ 2. Confirm the correct app and environment.
42
+ 3. Run the reported path through real UI actions.
43
+ 4. Observe the discriminating symptom.
44
+ 5. Reset and repeat it.
45
+ 6. Capture baseline recording, screenshot, and state check.
46
+
47
+ If the symptom does not appear twice on the baseline, there is no baseline. Do not claim that the fix works.
48
+
49
+ ## Measure the patched build
50
+
51
+ Build and run the pull request or fix commit with the same environment and data.
52
+
53
+ 1. Run the same UI path.
54
+ 2. Repeat it twice.
55
+ 3. Confirm that the broken state is gone.
56
+ 4. Confirm the expected state appears.
57
+ 5. Capture after recording, screenshot, and the same state check.
58
+
59
+ Do not stop at compilation or tests. The after result must come from a running patched app.
60
+
61
+ ## Outcomes
62
+
63
+ ### Confirmed
64
+
65
+ The baseline reproduces twice and the patched build resolves it twice.
66
+
67
+ - Mark operations status as verified.
68
+ - Link the artifact.
69
+ - Post one concise source-thread reply after the source preflight.
70
+ - Include the before and after result.
71
+ - Open no pull request.
72
+
73
+ ### Insufficient fix
74
+
75
+ The symptom appears on both baseline and patched builds.
76
+
77
+ - Mark operations status as reproduced but not fixed.
78
+ - Link the artifact and say it did not resolve the symptom.
79
+ - Post the normal confirmed-repro source update if the run has not already used it.
80
+ - Open no competing pull request.
81
+
82
+ ### Inconclusive
83
+
84
+ The baseline does not reproduce, the patched app cannot run, or the evidence does not show the discriminating state.
85
+
86
+ - Do not claim success.
87
+ - State which half could not be measured.
88
+ - Keep the result in the operations thread or run output.
89
+ - Post nothing in the source thread unless a direct question requires an answer.
90
+
91
+ ## Cleanup
92
+
93
+ Stop both builds, remove temporary profiles and captures according to retention policy, and return the repository to its prior state without discarding user work.
@@ -0,0 +1,271 @@
1
+ ---
2
+ name: setup-benny
3
+ description: Configure Benny and prepare its triage and repro automations. Use when installing Benny or changing its Slack, tracker, repository, routing, control, model, or budget settings.
4
+ disable-model-invocation: true
5
+ ---
6
+
7
+ # Set up Benny
8
+
9
+ Benny ships as a dormant automation pack inside pstack. The plugin manifest exposes only pstack's normal skill root; this file and the two operational files are not slash skills.
10
+
11
+ The human enters setup by pointing their agent at the pack's `FOR_AGENTS.md`. The bootstrap flow copies the whole pack into the target repository, then reads this file directly at `.pstack/automations/benny/skills/setup-benny/SKILL.md`.
12
+
13
+ Benny needs external configuration and two live automations (Claude Code scheduled tasks, or Codex Automations).
14
+
15
+ Do not create or update an automation until the user explicitly asks. Never put a secret value in plugin files, prompts, or committed configuration.
16
+
17
+ ## 1. Copy the pack and enable shared pstack skills
18
+
19
+ Do this before asking for Benny configuration and before invoking the harness's automation creator.
20
+
21
+ Ask which repository will run the automations. The source pack is the directory containing `FOR_AGENTS.md`. The destination is `<target-repository>/.pstack/automations/benny/`.
22
+
23
+ Merge the entire source pack into the destination:
24
+
25
+ 1. Create the destination when it is absent.
26
+ 2. Copy every source file to the same relative path.
27
+ 3. Preserve destination-only files. Never delete unrelated files during install or refresh.
28
+ 4. Keep user-owned configuration, feature maps, and routing maps outside the destination. Never overwrite them.
29
+ 5. When an existing source-managed file differs, inspect the diff and merge without discarding local edits. If ownership is ambiguous, stop and ask before replacing it.
30
+ 6. Verify that the destination contains `FOR_AGENTS.md`, this setup file, both operational files, their references, and the templates.
31
+
32
+ If this file is already being read from the target destination, treat the copy as complete and run the same verification before continuing.
33
+
34
+ Enable pstack for the target repository.
35
+
36
+ On Claude Code, add it to the repository's `.claude/settings.json`. If the file or `.claude` directory does not exist, create it. Merge this into the existing JSON:
37
+
38
+ ```json
39
+ {
40
+ "extraKnownMarketplaces": {
41
+ "pstack-plugins": {
42
+ "source": { "source": "github", "repo": "jiroamato/pstack" }
43
+ }
44
+ },
45
+ "enabledPlugins": { "pstack@pstack-plugins": true }
46
+ }
47
+ ```
48
+
49
+ Preserve every unrelated top-level setting and every other plugin entry. If the `pstack@pstack-plugins` entry already exists, change only its value. Validate the file after editing it.
50
+
51
+ On Codex, plugins are user-scoped. Install pstack for the user who runs the automations with `codex plugin marketplace add jiroamato/pstack`, then `codex plugin add pstack`.
52
+
53
+ Reload the target project or start a fresh agent rooted there. Verify that these shared pstack skills resolve from project scope:
54
+
55
+ - `how`
56
+ - `why`
57
+ - `tdd`
58
+ - `unslop`
59
+ - `principle-separate-before-serializing-shared-state`
60
+ - `principle-minimize-reader-load`
61
+ - `principle-guard-the-context-window`
62
+ - `principle-sequence-verifiable-units`
63
+ - `principle-fix-root-causes`
64
+ - `principle-prove-it-works`
65
+
66
+ On Claude Code, do not count a skill loaded from the current session or a user-scoped plugin. The check must show that a fresh agent in the target repository receives pstack through project settings. On Codex, confirm the automation's user has pstack installed.
67
+
68
+ If project-scoped plugin installation is unavailable or any shared dependency does not resolve, stop and explain the failure.
69
+
70
+ The Benny files are read directly from `.pstack/automations/benny/`. Do not add that directory to a plugin manifest or expect its `SKILL.md` files to appear in the slash-skill list.
71
+
72
+ Tell the user that the pstack settings (`.claude/settings.json` on Claude Code), `.pstack/automations/benny/`, and any referenced secret-free configuration must be committed before either automation is enabled. Do not commit them unless the user asks.
73
+
74
+ Once this check passes, live automation prompts may read the committed operational files by their stable repository-relative paths. They must not embed a plugin cache path or copy the file contents.
75
+
76
+ ## 2. Adapt the configuration
77
+
78
+ Open these copied examples:
79
+
80
+ - `../../templates/configuration.example.yaml`
81
+ - `../reproduce-and-fix-issues/references/feature-map.example.md`
82
+
83
+ Create user-owned copies outside `.pstack/automations/benny/`. These are configuration files, not pack files. Example locations:
84
+
85
+ - Project config, such as `.pstack/benny/configuration.yaml`
86
+ - Project feature map, such as `.pstack/benny/feature-map.md`
87
+ - Project routing map, such as `.pstack/benny/routing.md`
88
+ - User config, such as `~/.config/benny/configuration.yaml`
89
+ - User feature map, such as `~/.config/benny/feature-map.md`
90
+
91
+ Fill one feature-map section for every user-facing feature the automation may reproduce. Keep it at the user point of view. Do not freeze implementation details or current code paths in the map.
92
+
93
+ Do not edit the copied examples. Pack refreshes may update source-managed files after conflict review, but they must never touch the user-owned copies.
94
+
95
+ Prefer committed, secret-free files in the target repository when a fresh automation checkout must read them. Otherwise paraphrase the required values into the live prompt. Reference a repository file only after the automation creator confirms that the file is committed in the repository where the automation runs.
96
+
97
+ Use stable repository-relative paths for committed pack and configuration files. Never reference the plugin source directory or a plugin cache path from a live automation.
98
+
99
+ ## 3. Fill the required choices
100
+
101
+ Ask for or confirm:
102
+
103
+ - Source Slack channel ID
104
+ - Optional operations or status channel ID
105
+ - Repository URL and default branch
106
+ - Triage identity or Slack user ID
107
+ - Issue tracker type, team, project, labels, and intake status
108
+ - Tracker adapter skill or MCP actions
109
+ - Optional routing map path
110
+ - Required app-specific verification skill name (uses bundled pstack `control-ui` for web/IDE/Electron)
111
+ - Required user-facing feature-map path
112
+ - Status emoji strings
113
+ - Pull request URL format
114
+ - Polling and effort budgets
115
+ - Model slug for triage, repro, code work, and media review
116
+
117
+ Use only model ids shown as available in the user's model picker or supported model list. Do not guess a slug and do not carry over a private default.
118
+
119
+ The source channel, triage identity, repository, tracker adapter, app-specific verification skill, and feature map must be explicit. Fail setup if any required value stays ambiguous. There is no separate generic `control` skill; web/IDE/Electron driving uses bundled pstack `control-ui` with the configured app-specific adapter.
120
+
121
+ Use pstack's `unslop` skill on the final automation names, descriptions, and prompt shims before saving them.
122
+
123
+ ## 4. Check integration capabilities
124
+
125
+ The triage automation needs:
126
+
127
+ - Read access to the configured source Slack channel and its threads
128
+ - Thread-reply access in that channel
129
+ - Attachment metadata and file download access when reports include media
130
+ - Search, read, create, and update access through the configured issue-tracker adapter
131
+
132
+ The repro automation needs:
133
+
134
+ - Read access to the source thread
135
+ - Thread-reply access in the source channel
136
+ - Optional post and edit access in the configured operations channel
137
+ - Repository read and history access
138
+ - A pull request action that can open a draft pull request
139
+ - The configured control-adapter skill
140
+
141
+ Prefer the Slack actions your harness provides (a Slack MCP server or channel) for reads and posts. The optional `BENNY_SLACK_BOT_TOKEN` may fill a narrow gap such as editing one operations status message or downloading an attachment. Store the value in a secret manager or environment, not in YAML.
142
+
143
+ Do not use undocumented integration endpoints.
144
+
145
+ ## 5. Prepare the routing map
146
+
147
+ If the user wants reroutes or owner pings:
148
+
149
+ 1. Copy `../triage-issue-reports/references/routing.example.md` outside `.pstack/automations/benny/`.
150
+ 2. Replace every placeholder with public or organization-local values.
151
+ 3. Keep owner pings off by default.
152
+ 4. Allow a ping only for a configured feature owner or a confirmed likely regression author.
153
+
154
+ If no routing map is configured, triage may classify a report but must not guess a destination or owner.
155
+
156
+ ## 6. Verify the control adapter
157
+
158
+ Read `../reproduce-and-fix-issues/references/control-adapter.md` and the user's completed feature map.
159
+
160
+ Confirm that the named skill can:
161
+
162
+ - Bring up the target app
163
+ - Navigate every mapped feature through the real UI
164
+ - Exercise mapped states through declared adapter actions
165
+ - Inspect state without forcing the result
166
+ - Capture screenshots
167
+ - Start and stop a recording
168
+ - Clean up its processes and temporary data
169
+
170
+ If any capability is missing, leave the repro automation disabled. It must fail closed rather than claim a reproduction it did not perform.
171
+
172
+ ## 7. Prepare the live automations
173
+
174
+ Ask whether this is first-time creation or configuration of existing automations.
175
+
176
+ Read `../../FOR_AGENTS.md` from the copied pack as the primary user-intent source for either path. Use it to understand the two triggers, tools, instructions, outcomes, and shared rules.
177
+
178
+ ### First-time creation
179
+
180
+ Create one automation at a time.
181
+
182
+ For each automation:
183
+
184
+ 1. Read the matching copied prompt template as secondary internal source material.
185
+ 2. Turn `FOR_AGENTS.md`, the finished Benny configuration, and the template intent into a complete natural-language request.
186
+ 3. Tell the live prompt to read and follow its exact committed operational file under `.pstack/automations/benny/`.
187
+ 4. Use the stable repository-relative path, not a plugin source or cache path. Do not copy the operational file contents into the live prompt.
188
+ 5. Read and follow the harness's automation creator (the `schedule` skill on Claude Code, the Automations editor in the Codex app).
189
+ 6. Let it discover Slack channels, the repository, and connected integrations.
190
+ 7. Let it confirm that the copied pack and any referenced configuration files are committed in the same repository where the automation will run.
191
+ 8. Let it show its draft, obtain approval, ask readiness, and open the automation editor.
192
+ 9. Finish the editor handoff for this automation before starting the next one.
193
+
194
+ Give the automation creator this complete triage intent, filled from configuration:
195
+
196
+ - Name `benny-triage`.
197
+ - Read and follow `.pstack/automations/benny/skills/triage-issue-reports/SKILL.md` for every run.
198
+ - Trigger on each new top-level report in the configured source Slack channel.
199
+ - Read the triggering thread and reply only inside it.
200
+ - Use the configured issue-tracker integration.
201
+ - Classify, inspect evidence, trace cause, dedupe, and create only clear new bugs.
202
+ - End one thread-only verdict with the configured `[benny:bug]`, `[benny:performance]`, or `[benny:other]` marker and optional tracker URL.
203
+ - Never post a source-channel root message.
204
+
205
+ After the triage editor handoff is complete, give the automation creator this complete repro and fix intent:
206
+
207
+ - Name `benny-reproduce`.
208
+ - Read and follow `.pstack/automations/benny/skills/reproduce-and-fix-issues/SKILL.md` for every run.
209
+ - Trigger on the same new top-level reports in the configured source Slack channel.
210
+ - Use the configured repository and default branch.
211
+ - Read the source thread and reply only inside it.
212
+ - Include pull request creation and the configured tracker, control-adapter, and feature-map requirements. Paraphrase mapped user paths and states unless the automation creator confirms an eligible committed file in the same repository.
213
+ - Wait for a trusted triage marker before acting.
214
+ - Reproduce the exact symptom twice through the mapped real UI and capture evidence.
215
+ - Verify an existing fix without authoring over it.
216
+ - Attempt an optional bounded fix only after confirmed repro, then open a draft pull request when proof and checks pass.
217
+ - Never post a source-channel root message.
218
+
219
+ Do not duplicate the automation creator's Slack, repository, integration, completeness, authentication, draft-review, approval, readiness, or editor-handoff work.
220
+
221
+ ### Existing automations
222
+
223
+ The automation creator is creation-only. Do not use it to search for, inspect, or update existing automations.
224
+
225
+ Finish configuration, routing, control-adapter, and feature-map validation. Then give the user this concise editor checklist.
226
+
227
+ For the existing triage automation, update:
228
+
229
+ - Name and description
230
+ - Direct instruction to read `.pstack/automations/benny/skills/triage-issue-reports/SKILL.md`
231
+ - New top-level Slack report trigger and source channel
232
+ - Slack thread read and reply capabilities
233
+ - Issue-tracker integration
234
+ - Paraphrased triage instructions, thread-only rule, and Benny verdict markers
235
+
236
+ For the existing repro automation, update:
237
+
238
+ - Name and description
239
+ - Direct instruction to read `.pstack/automations/benny/skills/reproduce-and-fix-issues/SKILL.md`
240
+ - Matching Slack trigger and source channel
241
+ - Repository and default branch
242
+ - Slack thread read and reply capabilities
243
+ - Pull request action
244
+ - Tracker, control-adapter, and feature-map requirements
245
+ - Paraphrased marker wait, evidence, verification, and bounded-fix instructions
246
+
247
+ Ask the user to update each existing automation directly in its automation editor. Do not create replacements or duplicates.
248
+
249
+ ### Creation boundary
250
+
251
+ Never call a direct automation backend service or backend automation tool. Never use a browser URL that carries draft fields. Never build or open a harness deep link. For new automations, the only finish path is the automation creator's reviewed editor handoff.
252
+
253
+ Do not enable either automation until the thread-safety test passes after the editor save.
254
+
255
+ ## 8. Test thread safety
256
+
257
+ Use a test channel or a harmless test report.
258
+
259
+ Before testing, confirm that the target repository's pstack settings (`.claude/settings.json` on Claude Code), `.pstack/automations/benny/`, and every referenced secret-free configuration file are committed on the branch used by the automation checkout. Confirm that both live prompts point at their exact committed operational files. If any check fails, stop. Tell the user that the automation cannot be enabled yet.
260
+
261
+ Verify:
262
+
263
+ 1. Triage stores the root `thread_ts` and posts exactly one verdict as a reply.
264
+ 2. The verdict contains one configured marker.
265
+ 3. Repro accepts the marker only from the configured triage identity.
266
+ 4. Repro keeps the same immutable source coordinates.
267
+ 5. No source-channel root message appears.
268
+ 6. A delegated worker cannot use any Slack write action.
269
+ 7. Missing coordinates, a deleted parent, or a failed preflight produces no post and no tracker issue.
270
+
271
+ Enable normal traffic only after all seven checks pass.
@@ -0,0 +1,240 @@
1
+ ---
2
+ name: triage-issue-reports
3
+ description: Triage Slack issue reports with one thread-only verdict, evidence review, cause-aware routing, tracker dedupe, and fail-closed ticket creation. Use only from the configured Benny triage automation.
4
+ disable-model-invocation: true
5
+ ---
6
+
7
+ # Triage issue reports
8
+
9
+ Classify one Slack report and post one useful verdict in its source thread. Create a tracker issue only for a clear, new bug. Do not reproduce or fix it here.
10
+
11
+ Load the external Benny configuration supplied by the automation. If the config is missing, malformed, or incomplete, stop without posting or writing to the tracker.
12
+
13
+ ## Hard safety rules
14
+
15
+ - The source channel and root thread coordinates are immutable.
16
+ - Never post a root message in the source channel.
17
+ - Never post to another channel, broadcast a reply, send a DM, or start a replacement thread.
18
+ - Preflight the source parent before any tracker write and immediately before the verdict post.
19
+ - If the parent is missing, deleted, inaccessible, or uncertain, stop with no writes.
20
+ - Post one substantive verdict. Do not narrate progress.
21
+ - The coordinator is the only Slack poster.
22
+ - Delegated workers return findings only. They must be read-only and receive no Slack credentials or write actions.
23
+ - Every child prompt must forbid `SendSlackMessage`, `PostToSlack`, `chat.postMessage`, and every other Slack write.
24
+ - If worker isolation cannot enforce those limits, do the work in the coordinator.
25
+ - Never create an issue that cannot link back to the source thread.
26
+ - Prefer no ticket over a guessed or duplicate ticket.
27
+ - Apply pstack's `principle-separate-before-serializing-shared-state` to source coordinates.
28
+ - Apply pstack's `principle-minimize-reader-load` and `unslop` skills to the final verdict.
29
+
30
+ ## 1. Freeze source coordinates
31
+
32
+ Before making a work list or delegating:
33
+
34
+ 1. Read `source_channel_id` from the trigger.
35
+ 2. Require it to equal the configured source channel.
36
+ 3. Set `SOURCE_THREAD_TS` to `trigger.thread_ts` when present. Otherwise use `trigger.ts`.
37
+ 4. Require a nonempty `SOURCE_THREAD_TS`.
38
+ 5. Store `SOURCE_CHANNEL_ID` and `SOURCE_THREAD_TS` as immutable values.
39
+ 6. Read the thread and verify that its root has exactly those coordinates.
40
+ 7. Fetch a stable source permalink.
41
+
42
+ Every later source read and post must use those stored values. Never replace them with a reply timestamp or an operations-thread timestamp.
43
+
44
+ ## 2. Read the whole report
45
+
46
+ Read the root and current replies before deciding.
47
+
48
+ Capture:
49
+
50
+ - Reporter wording
51
+ - Product version, app build, environment, and platform when present
52
+ - Expected behavior
53
+ - Observed behavior
54
+ - Frequency and trigger
55
+ - Error text or stack signature
56
+ - Existing issue, commit, or pull request links
57
+ - Any explicit statement that someone is already fixing it
58
+
59
+ Inspect every relevant attachment.
60
+
61
+ - Read screenshots at full useful resolution.
62
+ - Review video for the state transition that separates correct and broken behavior.
63
+ - Read logs, traces, and crash text for concrete signatures.
64
+ - If media needs specialist review, use a read-only media worker and ask a narrow question. The worker returns findings only.
65
+ - If an attachment cannot be read, say so in the verdict. Do not invent what it shows.
66
+
67
+ Use evidence already in the thread before asking the reporter for more.
68
+
69
+ ## 3. Trace cause before routing
70
+
71
+ Do a bounded source and history pass before choosing an owner or destination. Use pstack's `how` skill to trace the path from the reported action to the observed result. Use `why` when the report looks like a regression or touches defensive code.
72
+
73
+ 1. Identify the likely code path from the reported action to the observed result.
74
+ 2. Check whether the visible symptom belongs to that code path or a dependency below it.
75
+ 3. Check recent changes when the report looks like a regression.
76
+ 4. Check whether a merged commit or open pull request already addresses the same symptom.
77
+ 5. Separate confirmed facts from hypotheses.
78
+
79
+ This pass does not need a complete root cause. It must be strong enough to avoid routing a visible symptom to the wrong owner.
80
+
81
+ If the repository cannot be read, do not guess a code owner. Continue with a conservative classification and say that cause tracing was unavailable.
82
+
83
+ ## 4. Classify
84
+
85
+ Choose one category.
86
+
87
+ ### Bug
88
+
89
+ Something violates intended behavior. Examples include wrong output, broken state, an error, a crash, a hang, a silent no-op, or a regression.
90
+
91
+ ### Performance
92
+
93
+ The report describes measurable slowness, excess memory, battery drain, jank, or another resource problem. Treat it as a bug, but preserve measurements and profiles.
94
+
95
+ ### Feature request
96
+
97
+ The current behavior appears intentional and the reporter wants a different behavior or affordance.
98
+
99
+ ### Question or feedback
100
+
101
+ The report asks how something works, expresses a preference without a concrete defect, or gives general feedback.
102
+
103
+ ### Reroute
104
+
105
+ Cause tracing shows that another configured destination owns the issue.
106
+
107
+ When the bug versus feature line is unclear, do not file. The one verdict may ask one focused question and use the `other` marker.
108
+
109
+ ## 5. Apply configured routing
110
+
111
+ Read the optional routing map from `routing.map_path`.
112
+
113
+ - Match on confirmed product area, code path, or error signature.
114
+ - A visible symptom alone is not enough when cause tracing points elsewhere.
115
+ - If no route matches, say the owner is unclear. Do not guess.
116
+ - Do not cross-post. Tell the reporter where to take the issue in the source thread.
117
+
118
+ Owner pings are off by default. A ping is allowed only when all of these hold:
119
+
120
+ 1. The routing map explicitly names the owner.
121
+ 2. The config allows that ping type.
122
+ 3. The item is a feature request that needs owner input, or recent history identifies a likely regression author with strong evidence.
123
+ 4. The owner is not a broad on-call group.
124
+
125
+ No other case gets a ping.
126
+
127
+ ## 6. Use the issue-tracker adapter
128
+
129
+ The tracker is an adapter, not a required vendor. A Linear adapter is one valid example. A GitHub Issues adapter or another tracker may implement the same contract.
130
+
131
+ The configured adapter must provide:
132
+
133
+ - Search issues by text, state, label, source URL, and date range
134
+ - Read one issue and its links
135
+ - Create an issue with title, body, status, labels, and source URL
136
+ - Update an existing issue without replacing unrelated fields
137
+ - Add a source link and recurrence note
138
+ - Cancel, close, or delete an issue created by this run if the Slack handoff fails
139
+
140
+ If a required operation is unavailable, fail closed for that write.
141
+
142
+ Resolve configured team, project, status, and labels at runtime. Do not invent IDs, create labels, assign owners, or set priority unless the config explicitly requires it.
143
+
144
+ ## 7. Dedupe
145
+
146
+ Always check whether this source permalink is already linked to a tracker issue or a prior triage reply. If so, do not post or create a duplicate.
147
+
148
+ For bugs and performance reports, search the tracker using:
149
+
150
+ - Exact error or crash signature
151
+ - Product area
152
+ - Trigger
153
+ - Symptom
154
+ - Version or date window
155
+ - Suspected regression commit
156
+ - Source permalink
157
+
158
+ Choose one outcome:
159
+
160
+ - Confident duplicate: same signature, or the same area, trigger, and symptom, or a confirmed shared cause.
161
+ - Possibly related: a shared cause is plausible but not proven.
162
+ - Weak resemblance: similarity is superficial.
163
+ - No match.
164
+
165
+ For a confident duplicate, update the existing issue with the source permalink and one short recurrence note. Do not reopen, relabel, or reassign it unless the config says to.
166
+
167
+ For a possible match, link it in the verdict as uncertain and create nothing.
168
+
169
+ A long-closed issue is a regression lead, not automatically a live duplicate.
170
+
171
+ ## 8. Decide whether to create
172
+
173
+ Create only when all of these are true:
174
+
175
+ 1. The classification is bug or performance.
176
+ 2. The behavior is clearly broken.
177
+ 3. The issue is still live or not known to be fixed.
178
+ 4. Dedupe found no confident or plausible live match.
179
+ 5. The source parent and permalink passed preflight.
180
+ 6. The tracker target fields resolved.
181
+ 7. The adapter can compensate if the verdict post fails.
182
+
183
+ Never create for a feature request, question, feedback item, reroute, possible duplicate, confident duplicate, or already-fixed issue.
184
+
185
+ The new issue must be self-contained:
186
+
187
+ - Plain title that names the area and symptom
188
+ - Reporter quote
189
+ - Expected and observed behavior
190
+ - Version and environment, or `unknown`
191
+ - Trigger and frequency
192
+ - Source thread permalink
193
+ - Short cause-tracing findings with hypotheses labeled as hypotheses
194
+ - Inline screenshot or representative video frame when supported
195
+ - Links to remaining artifacts
196
+ - Configured intake status and labels
197
+
198
+ Do not put a guessed root cause in the title.
199
+
200
+ ## 9. Post one verdict
201
+
202
+ Run a fresh source-parent preflight. Then post exactly one reply with `channel=SOURCE_CHANNEL_ID` and `thread_ts=SOURCE_THREAD_TS`.
203
+
204
+ Never call a source-channel posting action without a nonempty `thread_ts`.
205
+
206
+ Keep the reply short:
207
+
208
+ - Lead with the outcome.
209
+ - Link the existing or new tracker issue when there is one.
210
+ - Mention a reroute or one missing fact when needed.
211
+ - Include at most one allowed owner ping.
212
+ - End with exactly one marker line.
213
+
214
+ Marker contract:
215
+
216
+ ```text
217
+ [benny:bug]
218
+ [benny:bug] tracker=https://tracker.example/issue/123
219
+ [benny:performance]
220
+ [benny:performance] tracker=https://tracker.example/issue/123
221
+ [benny:other]
222
+ ```
223
+
224
+ Use only the configured marker strings. The repro automation trusts the marker only when it comes from the configured triage identity in this source thread.
225
+
226
+ After posting, read the same source thread and verify the verdict appears under `SOURCE_THREAD_TS`. If it does not, never retry at the root.
227
+
228
+ If this run created a tracker issue and the verdict did not land, use the adapter's compensation action. Verify that the issue is canceled, closed, or deleted. If compensation cannot be verified, report the failure only in the automation run output.
229
+
230
+ ## 10. Watch one follow-up window
231
+
232
+ Watch the source thread for the configured follow-up window, then stop.
233
+
234
+ - Answer only a direct question to the triage identity.
235
+ - Apply a concrete correction to the tracker issue when safe.
236
+ - Do not emit a second marker in the same run.
237
+ - Stay out of human coordination and side chatter.
238
+ - Stop early if someone asks the automation to stop.
239
+
240
+ Do not extend the window more than once. A new report should start a new run.
@@ -0,0 +1,61 @@
1
+ # Routing map example
2
+
3
+ Copy this file outside `.pstack/automations/benny/`, for example to `.pstack/benny/routing.md`, and replace every placeholder. Point `routing.map_path` at the copy. Pack refreshes must not overwrite it.
4
+
5
+ The triage skill treats this as data. A route needs evidence from the report or cause trace. A keyword match alone is not enough.
6
+
7
+ ```yaml
8
+ routes:
9
+ - name: "billing-example"
10
+ match:
11
+ product_areas:
12
+ - "billing-area-placeholder"
13
+ code_paths:
14
+ - "billing-code-path-placeholder"
15
+ error_signatures:
16
+ - "billing-error-placeholder"
17
+ destination:
18
+ slack_channel: "billing-channel-placeholder"
19
+ tracker_team: "billing-team-placeholder"
20
+ owners:
21
+ - "billing-owner-placeholder"
22
+ allow_feature_owner_ping: false
23
+
24
+ - name: "desktop-example"
25
+ match:
26
+ product_areas:
27
+ - "desktop-area-placeholder"
28
+ code_paths:
29
+ - "desktop-code-path-placeholder"
30
+ error_signatures:
31
+ - "desktop-error-placeholder"
32
+ destination:
33
+ slack_channel: "desktop-channel-placeholder"
34
+ tracker_team: "desktop-team-placeholder"
35
+ owners:
36
+ - "desktop-owner-placeholder"
37
+ allow_feature_owner_ping: false
38
+
39
+ fallback:
40
+ destination: ""
41
+ owners: []
42
+ allow_feature_owner_ping: false
43
+
44
+ ping_policy:
45
+ default: "off"
46
+ allow:
47
+ - "configured-feature-owner"
48
+ - "confirmed-regression-author"
49
+ deny:
50
+ - "broad-on-call-group"
51
+ - "unverified-owner"
52
+ ```
53
+
54
+ ## Rules
55
+
56
+ - Leave `fallback.destination` empty unless one team accepts all unmatched reports.
57
+ - Use stable product areas, code paths, and error signatures.
58
+ - Do not include private data in a public copy.
59
+ - Do not paste raw user or channel IDs into an example that will be published.
60
+ - Keep feature-owner pings off until the target team agrees to them.
61
+ - A reroute tells the reporter where to go. The automation never cross-posts.