@shiwenbin1617/pstack 0.14.4

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 (149) hide show
  1. package/LICENSE +28 -0
  2. package/README.md +332 -0
  3. package/adapters/claude-code/overrides/setup-pstack/SKILL.md +48 -0
  4. package/adapters/claude-code.md +29 -0
  5. package/adapters/codex/agents/comment-sicko.toml +7 -0
  6. package/adapters/codex/agents/poteto-agent.toml +7 -0
  7. package/adapters/codex/overrides/setup-pstack/SKILL.md +40 -0
  8. package/adapters/codex.md +34 -0
  9. package/agents/comment-sicko.md +32 -0
  10. package/agents/poteto-agent.md +9 -0
  11. package/automations/benny/FOR_AGENTS.md +89 -0
  12. package/automations/benny/README.md +23 -0
  13. package/automations/benny/skills/reproduce-and-fix-issues/SKILL.md +310 -0
  14. package/automations/benny/skills/reproduce-and-fix-issues/references/control-adapter.md +169 -0
  15. package/automations/benny/skills/reproduce-and-fix-issues/references/feature-map.example.md +205 -0
  16. package/automations/benny/skills/reproduce-and-fix-issues/references/verify-existing-fix.md +93 -0
  17. package/automations/benny/skills/setup-benny/SKILL.md +266 -0
  18. package/automations/benny/skills/triage-issue-reports/SKILL.md +240 -0
  19. package/automations/benny/skills/triage-issue-reports/references/routing.example.md +61 -0
  20. package/automations/benny/templates/configuration.example.yaml +84 -0
  21. package/automations/benny/templates/reproduce-automation-prompt.md +33 -0
  22. package/automations/benny/templates/triage-automation-prompt.md +39 -0
  23. package/bin/pstack.mjs +331 -0
  24. package/package.json +48 -0
  25. package/scripts/build.mjs +218 -0
  26. package/scripts/host-adapters.mjs +128 -0
  27. package/scripts/lib.mjs +181 -0
  28. package/scripts/test.mjs +106 -0
  29. package/skills/architect/SKILL.md +83 -0
  30. package/skills/architect/references/design-red-flags.md +33 -0
  31. package/skills/architect/references/rationale-template.md +35 -0
  32. package/skills/architect/references/runner-prompt.md +20 -0
  33. package/skills/arena/SKILL.md +71 -0
  34. package/skills/automate-me/SKILL.md +109 -0
  35. package/skills/blast-radius/SKILL.md +50 -0
  36. package/skills/bro/SKILL.md +7 -0
  37. package/skills/create-verification-skill/SKILL.md +44 -0
  38. package/skills/create-verification-skill/references/feature-map-example/README.md +47 -0
  39. package/skills/create-verification-skill/references/feature-map-example/create-note.md +39 -0
  40. package/skills/create-verification-skill/references/feature-map-example/search.md +45 -0
  41. package/skills/figure-it-out/SKILL.md +55 -0
  42. package/skills/how/SKILL.md +134 -0
  43. package/skills/how/references/critic-prompt.md +59 -0
  44. package/skills/how/references/critique-rubric.md +58 -0
  45. package/skills/how/references/explainer-prompt.md +55 -0
  46. package/skills/how/references/explorer-prompt.md +52 -0
  47. package/skills/interrogate/SKILL.md +113 -0
  48. package/skills/interrogate/references/code-quality-review.md +47 -0
  49. package/skills/interrogate/references/lead-judgment.md +58 -0
  50. package/skills/interrogate/references/reviewer-prompt.md +72 -0
  51. package/skills/interrogate/references/rubric.md +77 -0
  52. package/skills/maintain-verification-skill/SKILL.md +39 -0
  53. package/skills/no-comments/SKILL.md +24 -0
  54. package/skills/poteto-mode/SKILL.md +140 -0
  55. package/skills/poteto-mode/playbooks/authoring-a-skill.md +12 -0
  56. package/skills/poteto-mode/playbooks/autonomous-run.md +13 -0
  57. package/skills/poteto-mode/playbooks/autopilot-full.md +13 -0
  58. package/skills/poteto-mode/playbooks/autopilot-stack.md +16 -0
  59. package/skills/poteto-mode/playbooks/babysit.md +27 -0
  60. package/skills/poteto-mode/playbooks/bug-fix.md +17 -0
  61. package/skills/poteto-mode/playbooks/eval.md +27 -0
  62. package/skills/poteto-mode/playbooks/feature.md +21 -0
  63. package/skills/poteto-mode/playbooks/hillclimb.md +21 -0
  64. package/skills/poteto-mode/playbooks/investigation.md +14 -0
  65. package/skills/poteto-mode/playbooks/multi-phase-plan.md +155 -0
  66. package/skills/poteto-mode/playbooks/opening-a-pr.md +29 -0
  67. package/skills/poteto-mode/playbooks/orchestrate.md +113 -0
  68. package/skills/poteto-mode/playbooks/pause-safely.md +10 -0
  69. package/skills/poteto-mode/playbooks/perf-issue.md +24 -0
  70. package/skills/poteto-mode/playbooks/prototype.md +14 -0
  71. package/skills/poteto-mode/playbooks/refactoring.md +16 -0
  72. package/skills/poteto-mode/playbooks/runtime-forensics.md +11 -0
  73. package/skills/poteto-mode/playbooks/session-pickup.md +13 -0
  74. package/skills/poteto-mode/playbooks/shipping.md +20 -0
  75. package/skills/poteto-mode/playbooks/trace-forensics.md +14 -0
  76. package/skills/poteto-mode/playbooks/visual-parity.md +11 -0
  77. package/skills/poteto-mode/playbooks/worktree-cleanup.md +14 -0
  78. package/skills/poteto-mode/references/bugbot-triage.md +142 -0
  79. package/skills/poteto-mode/scripts/bootstrap.ts +30 -0
  80. package/skills/poteto-mode/scripts/bun.lock +67 -0
  81. package/skills/poteto-mode/scripts/check-plan.mjs +186 -0
  82. package/skills/poteto-mode/scripts/orch/orch.test.ts +634 -0
  83. package/skills/poteto-mode/scripts/orch/orch.ts +578 -0
  84. package/skills/poteto-mode/scripts/orch/store.ts +1607 -0
  85. package/skills/poteto-mode/scripts/package.json +16 -0
  86. package/skills/poteto-mode/scripts/watch-pr/cli.test.ts +224 -0
  87. package/skills/poteto-mode/scripts/watch-pr/cli.ts +223 -0
  88. package/skills/poteto-mode/scripts/watch-pr/fakes.test-helper.ts +118 -0
  89. package/skills/poteto-mode/scripts/watch-pr/github.test.ts +306 -0
  90. package/skills/poteto-mode/scripts/watch-pr/github.ts +699 -0
  91. package/skills/poteto-mode/scripts/watch-pr/policy.test.ts +420 -0
  92. package/skills/poteto-mode/scripts/watch-pr/policy.ts +832 -0
  93. package/skills/poteto-mode/scripts/watch-pr/render.ts +169 -0
  94. package/skills/poteto-mode/scripts/watch-pr/tsconfig.json +13 -0
  95. package/skills/poteto-mode/scripts/watch-pr/types.compile.ts +93 -0
  96. package/skills/poteto-mode/scripts/watch-pr/types.ts +401 -0
  97. package/skills/poteto-mode/scripts/watch-pr/watch-pr +6 -0
  98. package/skills/poteto-mode/scripts/worktree-audit.sh +89 -0
  99. package/skills/principle-boundary-discipline/SKILL.md +34 -0
  100. package/skills/principle-build-the-lever/SKILL.md +23 -0
  101. package/skills/principle-encode-lessons-in-structure/SKILL.md +31 -0
  102. package/skills/principle-exhaust-the-design-space/SKILL.md +21 -0
  103. package/skills/principle-experience-first/SKILL.md +19 -0
  104. package/skills/principle-fix-root-causes/SKILL.md +23 -0
  105. package/skills/principle-foundational-thinking/SKILL.md +21 -0
  106. package/skills/principle-guard-the-context-window/SKILL.md +17 -0
  107. package/skills/principle-laziness-protocol/SKILL.md +18 -0
  108. package/skills/principle-make-operations-idempotent/SKILL.md +24 -0
  109. package/skills/principle-migrate-callers-then-delete-legacy-apis/SKILL.md +22 -0
  110. package/skills/principle-minimize-reader-load/SKILL.md +23 -0
  111. package/skills/principle-model-the-domain/SKILL.md +26 -0
  112. package/skills/principle-never-block-on-the-human/SKILL.md +23 -0
  113. package/skills/principle-outcome-oriented-execution/SKILL.md +22 -0
  114. package/skills/principle-prove-it-works/SKILL.md +33 -0
  115. package/skills/principle-redesign-from-first-principles/SKILL.md +16 -0
  116. package/skills/principle-separate-before-serializing-shared-state/SKILL.md +16 -0
  117. package/skills/principle-sequence-verifiable-units/SKILL.md +22 -0
  118. package/skills/principle-subtract-before-you-add/SKILL.md +22 -0
  119. package/skills/principle-type-system-discipline/SKILL.md +31 -0
  120. package/skills/recall/SKILL.md +35 -0
  121. package/skills/reflect/SKILL.md +77 -0
  122. package/skills/reflect/references/divergent-reviewer.md +43 -0
  123. package/skills/reflect/references/judgment-reviewer.md +42 -0
  124. package/skills/reflect/references/synthesizer.md +56 -0
  125. package/skills/reflect/references/tooling-reviewer.md +57 -0
  126. package/skills/setup-pstack/SKILL.md +106 -0
  127. package/skills/show-me-your-work/SKILL.md +82 -0
  128. package/skills/show-me-your-work/references/decision-log-template.tsv +1 -0
  129. package/skills/show-me-your-work/scripts/log.sh +40 -0
  130. package/skills/swarm/SKILL.md +46 -0
  131. package/skills/tdd/SKILL.md +44 -0
  132. package/skills/teach/SKILL.md +21 -0
  133. package/skills/technical-writing/SKILL.md +130 -0
  134. package/skills/typescript-best-practices/SKILL.md +28 -0
  135. package/skills/typescript-best-practices/references/patterns.md +292 -0
  136. package/skills/unslop/SKILL.md +80 -0
  137. package/skills/why/SKILL.md +229 -0
  138. package/skills/why/references/epistemics.md +144 -0
  139. package/skills/why/references/investigator-prompt.md +103 -0
  140. package/skills/why/references/source-playbook.md +17 -0
  141. package/skills/why/references/sources/code-archaeology.md +88 -0
  142. package/skills/why/references/sources/databricks.md +70 -0
  143. package/skills/why/references/sources/datadog.md +99 -0
  144. package/skills/why/references/sources/incident-postmortem.md +15 -0
  145. package/skills/why/references/sources/linear.md +48 -0
  146. package/skills/why/references/sources/notion.md +55 -0
  147. package/skills/why/references/sources/sentry.md +100 -0
  148. package/skills/why/references/sources/slack.md +54 -0
  149. package/skills/why/references/synthesizer-prompt.md +135 -0
@@ -0,0 +1,89 @@
1
+ # benny automation intent
2
+
3
+ ## what i want to automate
4
+
5
+ i want two scheduled agent automations that work together in one slack issue channel.
6
+
7
+ ### automation 1: triage issue reports
8
+
9
+ - trigger: when someone posts a new top-level report in my configured source slack channel, i want this automation to start on that report and keep its original thread coordinates.
10
+ - behavior: i want it to read the thread and attachments, classify the report as a bug or performance issue, feature request, question or feedback, or reroute, and trace the likely owning layer before routing.
11
+ - tracker: i want it to search my configured tracker for duplicates, update a confident duplicate, and create a ticket only for a clear net-new bug.
12
+ - tools: i want slack thread read and reply access, my configured tracker integration, and my optional routing map.
13
+ - outcome: i want exactly one reply in the source thread with a short verdict and `[benny:bug]`, `[benny:performance]`, or `[benny:other]`. a bug or performance marker may include the tracker url.
14
+ - boundary: i never want this automation to post a root message in the source channel.
15
+
16
+ ### automation 2: reproduce and fix confirmed bugs
17
+
18
+ - trigger: i want this automation to start from the same new top-level report, or another supported trigger chosen during setup, then wait for the trusted triage marker in the original thread.
19
+ - gates: i want it to stop when someone clearly owns the fix. if an existing pull request or merged commit may fix the report, i want verification instead of a competing change.
20
+ - behavior: i want it to use my configured control adapter and feature map, reproduce the exact symptom twice through the real ui, and capture screenshots, video, and a read-only state cross-check.
21
+ - fix: i want it to verify existing pull requests without authoring over them. after a confirmed repro, it may attempt one bounded root-cause fix, use tdd when the test is cheap, smoke the blast radius, and open a draft pull request only when before-and-after proof passes.
22
+ - tools: i want slack thread read and reply access, repository and history access, draft pull request creation, my configured tracker, and my control adapter.
23
+ - outcome: i want evidence and a verified result in the source or optional operations threads, plus an optional draft pull request. updates should be concise.
24
+ - boundary: i never want this automation to post a root message in the source channel.
25
+
26
+ ### shared rules
27
+
28
+ - i want the source channel and root thread coordinates to stay immutable for the whole run.
29
+ - i treat utility and debug bots as evidence, not delegation or fix ownership.
30
+ - i allow subagents to help, but they cannot post to slack or receive slack credentials.
31
+ - i want this entire pack committed at `.claude/automations/benny/` in the target repository. its `SKILL.md` files are direct automation instructions, not registered plugin skills.
32
+ - i want pstack enabled through the target repository's committed `.claude/settings.json` only for shared dependencies such as `how`, `why`, `tdd`, `unslop`, and the required principle skills.
33
+ - i want each live automation prompt to read its committed operational file directly. i do not want plugin cache paths, copied excerpts, or slash-skill discovery.
34
+ - i keep user-owned configuration, feature maps, routing maps, and secrets outside `.claude/automations/benny/` so pack refreshes cannot overwrite them.
35
+ - i want both automations to fail closed when channel coordinates, tracker access, the control adapter, or the feature map are missing or uncertain.
36
+ - i want draft pull requests only. do not merge or deploy.
37
+
38
+ ### my configuration
39
+
40
+ - source slack channel: `<channel>`
41
+ - optional operations channel: `<channel or none>`
42
+ - repository and default branch: `<repo>`, `<branch>`
43
+ - tracker: `<type, team, project, labels, intake status>`
44
+ - routing map: `<path or none>`
45
+ - triage identity: `<slack identity>`
46
+ - control skill: `<configured skill or adapter>`
47
+ - feature map: `<committed same-repo path outside the copied pack, or behavior to paraphrase>`
48
+ - models: `<triage, reproduce, code, media review>`
49
+ - status emoji strings: `<seen, reproducing, reproduced, blocked, fixing, failed, pull request opened>`
50
+ - budgets: `<polling, verdict wait, follow-up, repro, rejection, fix>`
51
+ - optional bot token capability: `<none, file download, or editable operations status>`
52
+
53
+ start from [`configuration.example.yaml`](./templates/configuration.example.yaml) and [`feature-map.example.md`](./skills/reproduce-and-fix-issues/references/feature-map.example.md). copy and fill them outside this pack, for example under `.claude/benny/`. keep secret values in a secret manager or environment.
54
+
55
+ ## for the agent
56
+
57
+ the human enters setup by pointing their agent at this file. do not look for or invoke a discovered benny slash skill.
58
+
59
+ 1. ask which repository will run the automations.
60
+ 2. treat the directory containing this `FOR_AGENTS.md` as the source pack.
61
+ 3. merge the entire source pack into `<target-repository>/.claude/automations/benny/`.
62
+ 4. preserve every destination-only file. never delete unrelated files or overwrite user-owned configuration, feature maps, or routing maps.
63
+ 5. when an existing destination file at a source-managed path differs, review the diff and merge without discarding local edits. if ownership is ambiguous, stop and ask before replacing it.
64
+ 6. verify that the copied `FOR_AGENTS.md` and `skills/setup-benny/SKILL.md` exist in the target repository.
65
+ 7. read and follow `.claude/automations/benny/skills/setup-benny/SKILL.md` directly from the target repository.
66
+
67
+ i want you to merge this entry into the target repository's `.claude/settings.json`:
68
+
69
+ ```json
70
+ {
71
+ "plugins": {
72
+ "pstack": { "enabled": true }
73
+ }
74
+ }
75
+ ```
76
+
77
+ preserve every unrelated setting and plugin. preserve comments and valid jsonc syntax when the existing file uses jsonc.
78
+
79
+ i want verification from a fresh agent rooted in the target repository. confirm that pstack's `how`, `why`, `tdd`, `unslop`, and the principle skills used by benny resolve in project scope. do not count skills loaded from the current session or a user-scoped install.
80
+
81
+ if project-scoped plugins are unavailable or any shared dependency does not resolve, stop and explain what failed. do not add `.claude/automations/benny/skills/` to a plugin manifest or expect its files to appear in the slash-skill list.
82
+
83
+ tell me that `.claude/settings.json`, `.claude/automations/benny/`, and any referenced secret-free configuration must be committed before either automation is enabled. do not create or update an automation until i explicitly ask.
84
+
85
+ for first-time creation, use built-in `/automate` once for triage and once for repro and fix. complete the draft review, approval, readiness check, and Automations editor handoff for the first automation before starting the second.
86
+
87
+ paraphrase this intent and the finished configuration into each draft. the triage prompt must read and follow `.claude/automations/benny/skills/triage-issue-reports/SKILL.md`. the repro prompt must read and follow `.claude/automations/benny/skills/reproduce-and-fix-issues/SKILL.md`. use these repo-relative paths only after `/automate` confirms they are committed in the repository where the automation will run.
88
+
89
+ for existing automations, do not use `/automate` to inspect or update them. validate the configuration, then use the concise field checklist in the copied setup file so i can edit each automation directly in its editor. do not create duplicates.
@@ -0,0 +1,23 @@
1
+ # benny
2
+
3
+ benny gives you two scheduled agent automations for slack issue reports. one triages each report. the other reproduces confirmed bugs and may prepare a small draft fix.
4
+
5
+ the files in this directory are dormant setup and automation sources. they do not appear as slash skills.
6
+
7
+ ## set it up
8
+
9
+ 1. point your agent at [`FOR_AGENTS.md`](./FOR_AGENTS.md) and name the target repository.
10
+ 2. let setup merge this whole directory into the target at `.claude/automations/benny/`. it must preserve destination-only files and review conflicts instead of overwriting local edits.
11
+ 3. let setup enable pstack in the target repository's `.claude/settings.json` for shared dependencies:
12
+
13
+ ```json
14
+ {
15
+ "plugins": {
16
+ "pstack": { "enabled": true }
17
+ }
18
+ }
19
+ ```
20
+
21
+ 4. keep user-owned configuration outside the copied pack, for example in `.claude/benny/`. adapt [`configuration.example.yaml`](./templates/configuration.example.yaml) and [`feature-map.example.md`](./skills/reproduce-and-fix-issues/references/feature-map.example.md).
22
+ 5. commit `.claude/settings.json`, `.claude/automations/benny/`, and any secret-free configuration before enabling either automation.
23
+ 6. review each new automation draft or update existing automations in their editors. then send a harmless test report and verify every source-channel post stays in the original thread.
@@ -0,0 +1,310 @@
1
+ ---
2
+ name: reproduce-and-fix-issues
3
+ description: Reproduce triaged Slack bugs through a configured app-control adapter, verify existing fixes, and open a bounded draft pull request only after before-and-after proof. Use only from the configured Benny repro automation.
4
+ disable-model-invocation: true
5
+ ---
6
+
7
+ # Reproduce and fix issues
8
+
9
+ Wait for a trusted triage marker in the source thread. Reproduce the exact symptom through the target app's real UI. Verify an existing fix when one exists. Attempt a bounded fix only after a confirmed repro.
10
+
11
+ Load the external Benny configuration supplied by the automation. If the config, required actions, control adapter, or completed feature map is missing, fail closed.
12
+
13
+ ## Hard safety rules
14
+
15
+ - Freeze the source channel and root thread coordinates before doing any work.
16
+ - Never post a root message in the source channel.
17
+ - Preflight the source parent before every source-thread post.
18
+ - The coordinator is the only Slack poster.
19
+ - Delegated analysis workers are read-only and return findings or media notes.
20
+ - A fix-phase code worker may edit only when its environment provably excludes Slack credentials and every Slack write action. Otherwise the coordinator edits.
21
+ - Every child prompt must explicitly forbid `SendSlackMessage`, `PostToSlack`, `chat.postMessage`, and all other Slack writes.
22
+ - Never give a child a Slack token, posting instructions, source coordinates for posting, or permission to report externally.
23
+ - If a child needs Slack write access to run, do not launch it.
24
+ - Utility bots are evidence sources. They do not own the fix unless a person explicitly delegated the fix to them.
25
+ - The exact discriminating symptom must appear twice through real UI interaction.
26
+ - State inspection may confirm an observation. It must not inject or force the symptom.
27
+ - No confirmed repro means no authored fix.
28
+ - Existing pull requests or commits switch the run to verify mode. Do not author over them.
29
+ - Use `github.com` pull request links.
30
+ - Keep captures, recordings, logs, and tokens out of source control.
31
+ - Use pstack's `principle-guard-the-context-window` for delegated analysis.
32
+ - Apply pstack's `principle-sequence-verifiable-units`, `principle-fix-root-causes`, and `principle-prove-it-works` through repro, fix, and verification.
33
+
34
+ ## 1. Freeze source coordinates
35
+
36
+ Before making a work list or delegating:
37
+
38
+ 1. Require the trigger channel to equal the configured source channel.
39
+ 2. Set `SOURCE_THREAD_TS` to `trigger.thread_ts` when present. Otherwise use `trigger.ts`.
40
+ 3. Require a nonempty `SOURCE_THREAD_TS`.
41
+ 4. Store `SOURCE_CHANNEL_ID` and `SOURCE_THREAD_TS` as immutable values.
42
+ 5. Read the source thread and verify its root has those exact coordinates.
43
+ 6. Fetch the source permalink.
44
+
45
+ Never replace these values with a reply timestamp, operations timestamp, or status-message timestamp.
46
+
47
+ Before every source-channel post:
48
+
49
+ 1. Read the thread by the immutable coordinates.
50
+ 2. Confirm the parent exists, is not deleted, and still belongs to the source channel.
51
+ 3. Send only with `channel=SOURCE_CHANNEL_ID` and `thread_ts=SOURCE_THREAD_TS`.
52
+ 4. Read the thread again and verify the new message is a reply.
53
+
54
+ If any check fails, post nothing. Never retry at the root or in a fallback channel.
55
+
56
+ ## 2. Wait for the triage contract
57
+
58
+ Watch the source thread for the configured verdict budget. Stay silent while waiting.
59
+
60
+ Accept a verdict only when:
61
+
62
+ - Its author matches `slack.triage_identity_user_id`.
63
+ - It is a reply under `SOURCE_THREAD_TS`.
64
+ - It contains exactly one configured marker.
65
+
66
+ Public marker forms:
67
+
68
+ ```text
69
+ [benny:bug]
70
+ [benny:bug] tracker=https://tracker.example/issue/123
71
+ [benny:performance]
72
+ [benny:performance] tracker=https://tracker.example/issue/123
73
+ [benny:other]
74
+ ```
75
+
76
+ Proceed only for `bug` or `performance`. Capture the optional tracker URL. Stop silently for `other`, a missing verdict, an untrusted author, conflicting markers, or a timeout.
77
+
78
+ This marker replaces private bot identities and free-form verdict matching.
79
+
80
+ ## 3. Apply ownership and fix-artifact gates
81
+
82
+ Re-read the thread immediately before starting work.
83
+
84
+ ### Someone is explicitly fixing it
85
+
86
+ Stop when a person clearly claims the fix, gives a concrete implementation plan, or asks another agent to implement, patch, fix, or open a pull request.
87
+
88
+ Do not treat these as fix ownership:
89
+
90
+ - A bot summarizes evidence.
91
+ - A tool looks up logs or tickets.
92
+ - Someone asks a bot to diagnose, explain, inspect, or reproduce.
93
+ - A bot posts a cause hypothesis without agreeing to implement it.
94
+
95
+ Judge the requested action, not the presence of a bot.
96
+
97
+ ### A fix artifact already exists
98
+
99
+ If an open pull request or merged commit plausibly fixes this report, switch to `references/verify-existing-fix.md`.
100
+
101
+ An artifact may come from the thread, tracker issue, repository history, or pull request search. A claim without a commit or pull request is not a fix artifact.
102
+
103
+ If a person owns the work but has not produced an artifact, stop. Do not race them.
104
+
105
+ ## 4. Open an optional operations thread
106
+
107
+ If `slack.operations_channel_id` is configured, the coordinator may create one root status message there. This is the only allowed root post in the repro workflow.
108
+
109
+ Store its coordinates as `OPERATIONS_CHANNEL_ID` and `OPERATIONS_THREAD_TS`. Never confuse them with the source coordinates.
110
+
111
+ Use the configured plain Unicode status strings. Keep status text short:
112
+
113
+ - Reproducing
114
+ - Could not reproduce
115
+ - Blocked
116
+ - Reproduced
117
+ - Verifying existing fix
118
+ - Attempting bounded fix
119
+ - Draft pull request opened
120
+ - Fix did not land
121
+
122
+ Prefer the Slack MCP server's actions when one is connected. Use `BENNY_SLACK_BOT_TOKEN` only when the user configured it for a narrow missing capability such as editing this one status message. Never expose the token to a worker.
123
+
124
+ If no operations channel is configured, keep detailed status in the automation run output. Do not substitute a source-channel root message.
125
+
126
+ ## 5. Load and check the control adapter
127
+
128
+ Read `references/control-adapter.md` and the completed map at `control.feature_map_path`, then invoke the skill named by `control.skill_name`.
129
+
130
+ Find the feature-map section that matches the reported user path. Read it before driving the app. If no section covers the feature, mark the run blocked instead of inventing a path or selector.
131
+
132
+ Require all seven capabilities:
133
+
134
+ 1. Bring up the configured target app and test environment.
135
+ 2. Navigate the mapped feature and exercise its documented states.
136
+ 3. Drive the real UI with clicks, typing, keys, scrolling, drag, resize, or navigation.
137
+ 4. Inspect state without mutating it.
138
+ 5. Capture screenshots.
139
+ 6. Start and stop a screen recording.
140
+ 7. Clean up processes, sessions, profiles, and temporary data.
141
+
142
+ If the adapter is absent or any required capability is missing, mark the operations status as blocked and stop. Do not pretend a screenshot, unit test, state mutation, or source reading is a UI repro.
143
+
144
+ ## 6. Study the report
145
+
146
+ Read the full source thread and tracker issue when present.
147
+
148
+ Collect:
149
+
150
+ - Exact action path
151
+ - Expected behavior
152
+ - Observed behavior
153
+ - Discriminating state where they diverge
154
+ - Frequency
155
+ - Version, environment, and platform
156
+ - Attachments and error signatures
157
+ - Candidate code area
158
+
159
+ Inspect screenshots and video. Use read-only parallel workers for code history, test ideas, blast-radius mapping, and media review when useful. Each worker gets a narrow question and the Slack-write prohibition.
160
+
161
+ Use pstack's `how` skill to trace the action through the repository. Use `why` for regression history and defensive code. Form competing cause hypotheses and identify evidence that would separate them.
162
+
163
+ ## 7. Reproduce
164
+
165
+ Bring up the target app through the control adapter.
166
+
167
+ Confirm the correct app, workspace, account, data set, and feature state before acting. Use stable app markers. Do not rely on window order or a familiar title alone.
168
+
169
+ Drive the reported path through real UI actions.
170
+
171
+ Before calling it reproduced:
172
+
173
+ 1. Name the correct final state.
174
+ 2. Name the broken final state.
175
+ 3. Reach the point where they diverge.
176
+ 4. Observe the broken state.
177
+ 5. Reset enough state to make the second attempt independent.
178
+ 6. Repeat the same path and observe the same broken state again.
179
+ 7. Cross-check a real state value when possible.
180
+
181
+ An expected dialog, loading state, or setup step is not the bug. Capture the final state that distinguishes correct from broken behavior.
182
+
183
+ Use the configured repro budget. If the symptom does not reproduce within it, report a clean `Could not reproduce` outcome. If the environment cannot provide a required capability, report `Blocked` and state what was missing.
184
+
185
+ ## 8. Capture and review evidence
186
+
187
+ For a successful repro:
188
+
189
+ - Record the full path through the symptom.
190
+ - Capture a screenshot of the broken final state.
191
+ - Save a short note with the exact steps and observed state.
192
+ - Keep artifacts in the configured temporary artifact directory.
193
+
194
+ Have a read-only media reviewer answer one question: does the evidence visibly show the discriminating broken state?
195
+
196
+ If the answer is no or uncertain, the repro is not confirmed. Capture better evidence or use `Could not reproduce`.
197
+
198
+ Post detailed evidence only in the operations thread when configured. Keep the source update concise.
199
+
200
+ ## 9. Report the repro outcome
201
+
202
+ Update the operations status first.
203
+
204
+ For `Could not reproduce` or `Blocked`, post nothing in the source thread. The operations thread or run output carries the result.
205
+
206
+ For a confirmed repro, run the source preflight and post at most one unprompted source reply:
207
+
208
+ - Say the issue reproduced.
209
+ - Link the operations evidence thread when one exists.
210
+ - Include at most three short findings.
211
+ - Link the tracker issue when one exists.
212
+ - Do not ping an owner by default.
213
+
214
+ Attach evidence only when the configured Slack action keeps it inside the same source thread and the organization's retention policy allows it.
215
+
216
+ Wait for the configured rejection window. If a person shows that the setup or interpretation was wrong, correct the repro once. Do not start the fix phase until the window closes without a valid rejection.
217
+
218
+ ## 10. Verify an existing fix
219
+
220
+ When a fix artifact exists, follow `references/verify-existing-fix.md`.
221
+
222
+ Verification must show the symptom on the baseline and its absence on the patched build. Both paths use the real UI twice.
223
+
224
+ Do not edit the existing fix, add a competing patch, or open a replacement pull request.
225
+
226
+ ## 11. Qualify a bounded fix
227
+
228
+ Attempt a fix only when all of these hold:
229
+
230
+ - The outcome is a plain confirmed repro.
231
+ - Media review confirmed the broken final state.
232
+ - No existing fix artifact appeared.
233
+ - No person claimed the fix during the rejection window.
234
+ - Runtime evidence identifies the root cause.
235
+ - The likely change fits the configured fix budget and repository scope.
236
+ - The control adapter can run both baseline and patched builds.
237
+
238
+ If any condition fails, keep the repro report and stop without a pull request.
239
+
240
+ When the gate passes, update operations status to `Attempting bounded fix`.
241
+
242
+ ## 12. Root-cause and implement
243
+
244
+ The coordinator owns every Slack post, the final diff review, commits, and the pull request.
245
+
246
+ Read-only workers may:
247
+
248
+ - Trace code and history
249
+ - Propose tests
250
+ - Map blast radius
251
+ - Review a diff
252
+ - Review media
253
+
254
+ They do not edit, run external writes, post status, or own the fix.
255
+
256
+ A tightly scoped code edit may be delegated during this phase only when tool isolation removes Slack credentials and every Slack write action from that worker. Its prompt must still carry the explicit Slack-write ban. The coordinator reviews the edit and runs or verifies the required tests. If tool isolation is uncertain, keep the edit in the coordinator.
257
+
258
+ Confirm the mechanism with runtime evidence. Eliminate competing hypotheses before editing.
259
+
260
+ Fix the root cause with the smallest justified change.
261
+
262
+ - Invoke pstack's `tdd` skill when there is a cheap local test target, and write the failing test before the fix.
263
+ - State why TDD was skipped when the path is expensive, unclear, or integration-heavy.
264
+ - Keep unrelated cleanup out.
265
+ - Stop if the change grows beyond the configured effort or risk budget.
266
+
267
+ ## 13. Prove the fix
268
+
269
+ Keep the original baseline evidence.
270
+
271
+ On the patched build:
272
+
273
+ 1. Run the same real UI path.
274
+ 2. Repeat it twice.
275
+ 3. Show that the broken state is gone.
276
+ 4. Show the expected state in its place.
277
+ 5. Capture an after recording and screenshot.
278
+ 6. Cross-check the same real state value used for the baseline.
279
+
280
+ A compile, unit test, code review, or plausible diff is not after evidence.
281
+
282
+ Run focused tests, then smoke the blast radius around the changed behavior. Cover nearby states, inputs, permissions, platforms, and failure paths that the change could affect. Stop without a pull request if a regression remains.
283
+
284
+ ## 14. Open a draft pull request
285
+
286
+ Only after before-and-after proof:
287
+
288
+ - Review the final diff for unrelated changes and secrets.
289
+ - Run the repository's required checks.
290
+ - Create small ordered commits when the repository workflow allows it.
291
+ - Open a draft pull request. Never merge or deploy from this workflow.
292
+ - Link the configured tracker issue using the tracker's supported pull request syntax.
293
+ - Use the configured public URL form, normally `https://github.com/{owner}/{repo}/pull/{number}`.
294
+ - Include the repro steps, root cause, test result, before and after evidence, and blast-radius checks.
295
+ - Run the pull request text and all Slack updates through pstack's `unslop` skill.
296
+
297
+ If pull request creation fails, do not claim success. Keep the commit or branch state in the run output and mark operations status `Fix did not land`.
298
+
299
+ On success, mark operations status `Draft pull request opened` and post one concise reply in the operations thread with the linked pull request. Do not create a second source-channel root or unprompted source reply.
300
+
301
+ ## 15. Follow-ups and cleanup
302
+
303
+ Watch the configured operations thread for one follow-up window.
304
+
305
+ - Answer a direct question from evidence already gathered.
306
+ - Apply one concrete correction and rerun the repro once when it invalidates the setup.
307
+ - Stay out of human coordination and side chatter.
308
+ - Stop when asked.
309
+
310
+ Always call the control adapter's cleanup capability. Keep artifacts only as long as the configured retention policy allows.
@@ -0,0 +1,169 @@
1
+ # Control-adapter contract
2
+
3
+ Benny does not know how to start or drive every app. The user must configure one control skill or adapter that implements this contract for the target app.
4
+
5
+ Set its skill name in `control.skill_name`.
6
+
7
+ Set the completed user-facing feature map path in `control.feature_map_path`. Copy and fill [`feature-map.example.md`](./feature-map.example.md) outside `.claude/automations/benny/` instead of editing the copied example.
8
+
9
+ If the skill, feature map, or a required capability is absent, ambiguous, or incomplete, repro and fix work must fail closed.
10
+
11
+ ## Required capabilities
12
+
13
+ ### Bring up
14
+
15
+ Start the requested app revision in the requested test environment.
16
+
17
+ Input:
18
+
19
+ - Repository and revision
20
+ - Build or start mode
21
+ - Workspace, account, fixture, and feature-state requirements
22
+ - Artifact directory
23
+ - Completed feature-map path
24
+
25
+ Return:
26
+
27
+ - Session identifier
28
+ - How the adapter confirmed the correct app and environment
29
+ - Stable app markers
30
+ - Running process or target details needed by later calls
31
+ - Any missing capability
32
+
33
+ The adapter must distinguish the target app from a similar window, shell, or production instance.
34
+
35
+ ### Drive UI
36
+
37
+ Perform real user actions:
38
+
39
+ - Click
40
+ - Type
41
+ - Press keys
42
+ - Scroll
43
+ - Drag
44
+ - Resize
45
+ - Navigate through app controls
46
+
47
+ Prefer roles, labels, and stable selectors. Use coordinates only after a fresh screenshot.
48
+
49
+ Return each action and the observed state change.
50
+
51
+ Do not set internal state, call hidden app methods, write directly to storage, or inject DOM changes to create the symptom.
52
+
53
+ ### Drive mapped features and states
54
+
55
+ Read the relevant feature-map section before driving the app.
56
+
57
+ The adapter must expose ways to:
58
+
59
+ - Navigate every mapped feature through the user-visible path.
60
+ - Invoke the adapter action names listed for that feature.
61
+ - Interact with default, hover, focus-visible, active, disabled, loading, empty, error, selected, open, expanded, and feature-specific states when they apply.
62
+ - Arrange a state through safe fixture data, permissions, flags, service responses, or supported test controls.
63
+ - Reset the feature for a second independent repro attempt.
64
+ - Capture the screenshot, video, and read-only cross-check named by the feature map.
65
+
66
+ Use roles, accessible names, ARIA relationships, stable component markers, and purpose-named data attributes. Never use generated CSS or StyleX classes, dynamic hashes, child indexes, or brittle DOM position.
67
+
68
+ Arranging a precondition is not permission to inject the reported symptom. The repro itself must still come from real user interaction.
69
+
70
+ ### Inspect state
71
+
72
+ Read state to confirm what the UI shows.
73
+
74
+ Examples:
75
+
76
+ - Accessibility tree
77
+ - DOM or view hierarchy
78
+ - Process state
79
+ - Local logs
80
+ - Network request status
81
+ - App-exposed debug state
82
+
83
+ Inspection is read-only. If a query changes state, it belongs in `drive UI` and must represent a real user action.
84
+
85
+ ### Screenshot
86
+
87
+ Capture the current app state to a requested path.
88
+
89
+ Return:
90
+
91
+ - File path
92
+ - Capture time
93
+ - App marker or window title
94
+ - Short description of what should be visible
95
+
96
+ The screenshot must show enough app chrome to prove that the correct app is under test.
97
+
98
+ ### Recording
99
+
100
+ Start and stop a screen recording around the full repro path.
101
+
102
+ Return:
103
+
104
+ - File path
105
+ - Start and stop times
106
+ - Captured window or region
107
+ - Whether audio or sensitive overlays were omitted
108
+
109
+ The recording must show the discriminating final state, not only setup or a loading screen.
110
+
111
+ ### Cleanup
112
+
113
+ Stop processes and sessions created by the adapter.
114
+
115
+ Remove disposable:
116
+
117
+ - Browser or app profiles
118
+ - Temporary workspaces
119
+ - Test accounts or fixtures when the adapter created them
120
+ - Debug ports and tunnels
121
+ - Captures past their retention window
122
+
123
+ Return what was stopped, removed, retained, or left for a person.
124
+
125
+ Cleanup must not delete user work.
126
+
127
+ ## Adapter behavior
128
+
129
+ The adapter must:
130
+
131
+ - Report capabilities before the repro starts.
132
+ - Report which feature-map sections it can drive and which are blocked.
133
+ - Use the same environment inputs for baseline and patched builds.
134
+ - Surface startup failures as failures.
135
+ - Bound retries.
136
+ - Keep secrets out of logs and artifacts.
137
+ - Keep captures outside the repository.
138
+ - Support a fresh or reset state between the two repro attempts.
139
+ - Avoid production changes unless the user explicitly configured a safe test action.
140
+
141
+ ## Environment translation
142
+
143
+ Before declaring an environment block, restate the defect without platform-specific nouns and ask whether the same behavior can be tested safely in the available environment.
144
+
145
+ Examples:
146
+
147
+ - A named browser may mean any external browser.
148
+ - A named key may mean the configured shortcut.
149
+ - A named remote host may mean a delayed or disconnected remote target.
150
+
151
+ Use a translated attempt only when it tests the same underlying behavior. Label it as translated evidence. Do not call it an exact repro when the missing environment is part of the defect.
152
+
153
+ Hardware prompts, operating-system permission dialogs, device-only APIs, and unavailable account states may be real blocks.
154
+
155
+ ## Setup check
156
+
157
+ Before enabling the repro automation, run one harmless adapter check:
158
+
159
+ 1. Bring up the app.
160
+ 2. Confirm the stable app marker.
161
+ 3. Load one completed feature-map section.
162
+ 4. Navigate to that feature through its user path.
163
+ 5. Exercise one disposable state through mapped adapter actions.
164
+ 6. Inspect the resulting state.
165
+ 7. Capture a screenshot.
166
+ 8. Record a short clip.
167
+ 9. Clean up.
168
+
169
+ Enable repro work only when all nine steps succeed and no source-channel Slack post is involved.