openpitstop 1.0.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 (274) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +512 -0
  3. package/demo-repo/README.md +24 -0
  4. package/demo-repo/package-lock.json +4483 -0
  5. package/demo-repo/package.json +17 -0
  6. package/demo-repo/src/config.js +5 -0
  7. package/demo-repo/src/db.js +31 -0
  8. package/demo-repo/src/server.js +13 -0
  9. package/demo-repo/src/userController.js +22 -0
  10. package/demo-repo/src/userRepo.js +18 -0
  11. package/demo-repo/src/userService.js +59 -0
  12. package/demo-repo/test/user.test.js +12 -0
  13. package/demo-repo-fintech/README.md +27 -0
  14. package/demo-repo-fintech/package-lock.json +1023 -0
  15. package/demo-repo-fintech/package.json +14 -0
  16. package/demo-repo-fintech/pitstop-repro-ledger-order-ord-conc-1-charged-2.test.mjs +175 -0
  17. package/demo-repo-fintech/pitstop-repro-ledger-order-ord-retry-2-charged-2.test.mjs +175 -0
  18. package/demo-repo-fintech/pitstop-repro-ledger-order-ord-webhook-3-charged-2.test.mjs +175 -0
  19. package/demo-repo-fintech/src/gateway.js +26 -0
  20. package/demo-repo-fintech/src/server.js +61 -0
  21. package/demo-repo-generators/package-lock.json +1508 -0
  22. package/demo-repo-generators/package.json +17 -0
  23. package/demo-repo-generators/public/index.html +10 -0
  24. package/demo-repo-generators/scripts/build.js +17 -0
  25. package/demo-repo-generators/src/counter.js +16 -0
  26. package/demo-repo-integrity/README.md +49 -0
  27. package/demo-repo-integrity/package.json +12 -0
  28. package/demo-repo-integrity/src/money.js +19 -0
  29. package/demo-repo-integrity/test/money.test.js +17 -0
  30. package/dist/analyzers/accessibility.d.ts +18 -0
  31. package/dist/analyzers/accessibility.js +248 -0
  32. package/dist/analyzers/accessibility.js.map +1 -0
  33. package/dist/analyzers/dependencyGraph.d.ts +14 -0
  34. package/dist/analyzers/dependencyGraph.js +206 -0
  35. package/dist/analyzers/dependencyGraph.js.map +1 -0
  36. package/dist/analyzers/devex.d.ts +19 -0
  37. package/dist/analyzers/devex.js +301 -0
  38. package/dist/analyzers/devex.js.map +1 -0
  39. package/dist/analyzers/duplication.d.ts +2 -0
  40. package/dist/analyzers/duplication.js +47 -0
  41. package/dist/analyzers/duplication.js.map +1 -0
  42. package/dist/analyzers/index.d.ts +12 -0
  43. package/dist/analyzers/index.js +38 -0
  44. package/dist/analyzers/index.js.map +1 -0
  45. package/dist/analyzers/integrity/assertionLiteralTamper.d.ts +2 -0
  46. package/dist/analyzers/integrity/assertionLiteralTamper.js +164 -0
  47. package/dist/analyzers/integrity/assertionLiteralTamper.js.map +1 -0
  48. package/dist/analyzers/integrity/exceptionSwallow.d.ts +2 -0
  49. package/dist/analyzers/integrity/exceptionSwallow.js +198 -0
  50. package/dist/analyzers/integrity/exceptionSwallow.js.map +1 -0
  51. package/dist/analyzers/integrity/exitCheat.d.ts +2 -0
  52. package/dist/analyzers/integrity/exitCheat.js +31 -0
  53. package/dist/analyzers/integrity/exitCheat.js.map +1 -0
  54. package/dist/analyzers/integrity/git.d.ts +10 -0
  55. package/dist/analyzers/integrity/git.js +181 -0
  56. package/dist/analyzers/integrity/git.js.map +1 -0
  57. package/dist/analyzers/integrity/hardcodedMatch.d.ts +2 -0
  58. package/dist/analyzers/integrity/hardcodedMatch.js +93 -0
  59. package/dist/analyzers/integrity/hardcodedMatch.js.map +1 -0
  60. package/dist/analyzers/integrity/helpers.d.ts +21 -0
  61. package/dist/analyzers/integrity/helpers.js +66 -0
  62. package/dist/analyzers/integrity/helpers.js.map +1 -0
  63. package/dist/analyzers/integrity/index.d.ts +10 -0
  64. package/dist/analyzers/integrity/index.js +27 -0
  65. package/dist/analyzers/integrity/index.js.map +1 -0
  66. package/dist/analyzers/integrity/mockOverreach.d.ts +2 -0
  67. package/dist/analyzers/integrity/mockOverreach.js +72 -0
  68. package/dist/analyzers/integrity/mockOverreach.js.map +1 -0
  69. package/dist/analyzers/integrity/suppressionCreep.d.ts +2 -0
  70. package/dist/analyzers/integrity/suppressionCreep.js +27 -0
  71. package/dist/analyzers/integrity/suppressionCreep.js.map +1 -0
  72. package/dist/analyzers/integrity/testTamper.d.ts +2 -0
  73. package/dist/analyzers/integrity/testTamper.js +153 -0
  74. package/dist/analyzers/integrity/testTamper.js.map +1 -0
  75. package/dist/analyzers/integrity/types.d.ts +63 -0
  76. package/dist/analyzers/integrity/types.js +13 -0
  77. package/dist/analyzers/integrity/types.js.map +1 -0
  78. package/dist/analyzers/ledger/attacks.d.ts +17 -0
  79. package/dist/analyzers/ledger/attacks.js +135 -0
  80. package/dist/analyzers/ledger/attacks.js.map +1 -0
  81. package/dist/analyzers/ledger/discover.d.ts +15 -0
  82. package/dist/analyzers/ledger/discover.js +122 -0
  83. package/dist/analyzers/ledger/discover.js.map +1 -0
  84. package/dist/analyzers/ledger/evidence.d.ts +22 -0
  85. package/dist/analyzers/ledger/evidence.js +127 -0
  86. package/dist/analyzers/ledger/evidence.js.map +1 -0
  87. package/dist/analyzers/ledger/harness.d.ts +4 -0
  88. package/dist/analyzers/ledger/harness.js +270 -0
  89. package/dist/analyzers/ledger/harness.js.map +1 -0
  90. package/dist/analyzers/ledger/index.d.ts +14 -0
  91. package/dist/analyzers/ledger/index.js +116 -0
  92. package/dist/analyzers/ledger/index.js.map +1 -0
  93. package/dist/analyzers/ledger/types.d.ts +31 -0
  94. package/dist/analyzers/ledger/types.js +2 -0
  95. package/dist/analyzers/ledger/types.js.map +1 -0
  96. package/dist/analyzers/perf.d.ts +2 -0
  97. package/dist/analyzers/perf.js +106 -0
  98. package/dist/analyzers/perf.js.map +1 -0
  99. package/dist/analyzers/reliability.d.ts +22 -0
  100. package/dist/analyzers/reliability.js +339 -0
  101. package/dist/analyzers/reliability.js.map +1 -0
  102. package/dist/analyzers/routes.d.ts +17 -0
  103. package/dist/analyzers/routes.js +115 -0
  104. package/dist/analyzers/routes.js.map +1 -0
  105. package/dist/analyzers/security.d.ts +2 -0
  106. package/dist/analyzers/security.js +302 -0
  107. package/dist/analyzers/security.js.map +1 -0
  108. package/dist/analyzers/suiteRunner.d.ts +64 -0
  109. package/dist/analyzers/suiteRunner.js +381 -0
  110. package/dist/analyzers/suiteRunner.js.map +1 -0
  111. package/dist/analyzers/tests.d.ts +2 -0
  112. package/dist/analyzers/tests.js +215 -0
  113. package/dist/analyzers/tests.js.map +1 -0
  114. package/dist/analyzers/types.d.ts +203 -0
  115. package/dist/analyzers/types.js +2 -0
  116. package/dist/analyzers/types.js.map +1 -0
  117. package/dist/analyzers/util.d.ts +35 -0
  118. package/dist/analyzers/util.js +209 -0
  119. package/dist/analyzers/util.js.map +1 -0
  120. package/dist/ciCheckA.d.ts +2 -0
  121. package/dist/ciCheckA.js +5 -0
  122. package/dist/ciCheckA.js.map +1 -0
  123. package/dist/ciCheckB.d.ts +2 -0
  124. package/dist/ciCheckB.js +6 -0
  125. package/dist/ciCheckB.js.map +1 -0
  126. package/dist/cli.d.ts +2 -0
  127. package/dist/cli.js +65 -0
  128. package/dist/cli.js.map +1 -0
  129. package/dist/commands/budget.d.ts +33 -0
  130. package/dist/commands/budget.js +108 -0
  131. package/dist/commands/budget.js.map +1 -0
  132. package/dist/commands/ci.d.ts +14 -0
  133. package/dist/commands/ci.js +157 -0
  134. package/dist/commands/ci.js.map +1 -0
  135. package/dist/commands/demo.d.ts +2 -0
  136. package/dist/commands/demo.js +163 -0
  137. package/dist/commands/demo.js.map +1 -0
  138. package/dist/commands/digest.d.ts +8 -0
  139. package/dist/commands/digest.js +189 -0
  140. package/dist/commands/digest.js.map +1 -0
  141. package/dist/commands/doctor.d.ts +2 -0
  142. package/dist/commands/doctor.js +98 -0
  143. package/dist/commands/doctor.js.map +1 -0
  144. package/dist/commands/drive.d.ts +3 -0
  145. package/dist/commands/drive.js +170 -0
  146. package/dist/commands/drive.js.map +1 -0
  147. package/dist/commands/gate.d.ts +2 -0
  148. package/dist/commands/gate.js +136 -0
  149. package/dist/commands/gate.js.map +1 -0
  150. package/dist/commands/honesty.d.ts +2 -0
  151. package/dist/commands/honesty.js +182 -0
  152. package/dist/commands/honesty.js.map +1 -0
  153. package/dist/commands/inspect.d.ts +2 -0
  154. package/dist/commands/inspect.js +244 -0
  155. package/dist/commands/inspect.js.map +1 -0
  156. package/dist/commands/install.d.ts +2 -0
  157. package/dist/commands/install.js +81 -0
  158. package/dist/commands/install.js.map +1 -0
  159. package/dist/commands/integrity.d.ts +2 -0
  160. package/dist/commands/integrity.js +74 -0
  161. package/dist/commands/integrity.js.map +1 -0
  162. package/dist/commands/memory.d.ts +6 -0
  163. package/dist/commands/memory.js +90 -0
  164. package/dist/commands/memory.js.map +1 -0
  165. package/dist/commands/pen.d.ts +17 -0
  166. package/dist/commands/pen.js +158 -0
  167. package/dist/commands/pen.js.map +1 -0
  168. package/dist/commands/prompt.d.ts +2 -0
  169. package/dist/commands/prompt.js +37 -0
  170. package/dist/commands/prompt.js.map +1 -0
  171. package/dist/commands/readyCheck.d.ts +21 -0
  172. package/dist/commands/readyCheck.js +68 -0
  173. package/dist/commands/readyCheck.js.map +1 -0
  174. package/dist/commands/report.d.ts +2 -0
  175. package/dist/commands/report.js +48 -0
  176. package/dist/commands/report.js.map +1 -0
  177. package/dist/commands/repro.d.ts +3 -0
  178. package/dist/commands/repro.js +61 -0
  179. package/dist/commands/repro.js.map +1 -0
  180. package/dist/commands/scan.d.ts +27 -0
  181. package/dist/commands/scan.js +348 -0
  182. package/dist/commands/scan.js.map +1 -0
  183. package/dist/commands/share.d.ts +2 -0
  184. package/dist/commands/share.js +163 -0
  185. package/dist/commands/share.js.map +1 -0
  186. package/dist/commands/trends.d.ts +2 -0
  187. package/dist/commands/trends.js +103 -0
  188. package/dist/commands/trends.js.map +1 -0
  189. package/dist/commands/try.d.ts +12 -0
  190. package/dist/commands/try.js +208 -0
  191. package/dist/commands/try.js.map +1 -0
  192. package/dist/commands/verify.d.ts +44 -0
  193. package/dist/commands/verify.js +381 -0
  194. package/dist/commands/verify.js.map +1 -0
  195. package/dist/commands/watch.d.ts +10 -0
  196. package/dist/commands/watch.js +70 -0
  197. package/dist/commands/watch.js.map +1 -0
  198. package/dist/evidence.d.ts +37 -0
  199. package/dist/evidence.js +61 -0
  200. package/dist/evidence.js.map +1 -0
  201. package/dist/graph/correlate.d.ts +7 -0
  202. package/dist/graph/correlate.js +246 -0
  203. package/dist/graph/correlate.js.map +1 -0
  204. package/dist/graph/integrity.d.ts +22 -0
  205. package/dist/graph/integrity.js +39 -0
  206. package/dist/graph/integrity.js.map +1 -0
  207. package/dist/installer/targets.d.ts +23 -0
  208. package/dist/installer/targets.js +162 -0
  209. package/dist/installer/targets.js.map +1 -0
  210. package/dist/memory/store.d.ts +33 -0
  211. package/dist/memory/store.js +131 -0
  212. package/dist/memory/store.js.map +1 -0
  213. package/dist/pen/dynamic.d.ts +36 -0
  214. package/dist/pen/dynamic.js +622 -0
  215. package/dist/pen/dynamic.js.map +1 -0
  216. package/dist/pen/fix.d.ts +35 -0
  217. package/dist/pen/fix.js +239 -0
  218. package/dist/pen/fix.js.map +1 -0
  219. package/dist/pen/proof.d.ts +46 -0
  220. package/dist/pen/proof.js +112 -0
  221. package/dist/pen/proof.js.map +1 -0
  222. package/dist/pen/report.d.ts +11 -0
  223. package/dist/pen/report.js +258 -0
  224. package/dist/pen/report.js.map +1 -0
  225. package/dist/pen/static.d.ts +17 -0
  226. package/dist/pen/static.js +565 -0
  227. package/dist/pen/static.js.map +1 -0
  228. package/dist/pen/store.d.ts +11 -0
  229. package/dist/pen/store.js +36 -0
  230. package/dist/pen/store.js.map +1 -0
  231. package/dist/pen/types.d.ts +112 -0
  232. package/dist/pen/types.js +53 -0
  233. package/dist/pen/types.js.map +1 -0
  234. package/dist/report/format.d.ts +126 -0
  235. package/dist/report/format.js +706 -0
  236. package/dist/report/format.js.map +1 -0
  237. package/dist/report/score.d.ts +47 -0
  238. package/dist/report/score.js +164 -0
  239. package/dist/report/score.js.map +1 -0
  240. package/dist/repro/framework.d.ts +26 -0
  241. package/dist/repro/framework.js +224 -0
  242. package/dist/repro/framework.js.map +1 -0
  243. package/dist/repro/generate.d.ts +14 -0
  244. package/dist/repro/generate.js +669 -0
  245. package/dist/repro/generate.js.map +1 -0
  246. package/dist/repro/ids.d.ts +32 -0
  247. package/dist/repro/ids.js +175 -0
  248. package/dist/repro/ids.js.map +1 -0
  249. package/dist/repro/index.d.ts +24 -0
  250. package/dist/repro/index.js +69 -0
  251. package/dist/repro/index.js.map +1 -0
  252. package/dist/repro/pen.d.ts +26 -0
  253. package/dist/repro/pen.js +321 -0
  254. package/dist/repro/pen.js.map +1 -0
  255. package/dist/repro/run.d.ts +18 -0
  256. package/dist/repro/run.js +36 -0
  257. package/dist/repro/run.js.map +1 -0
  258. package/dist/sandbox/proxy.d.ts +41 -0
  259. package/dist/sandbox/proxy.js +231 -0
  260. package/dist/sandbox/proxy.js.map +1 -0
  261. package/dist/sandbox/startCmd.d.ts +24 -0
  262. package/dist/sandbox/startCmd.js +71 -0
  263. package/dist/sandbox/startCmd.js.map +1 -0
  264. package/dist/ui/spinner.d.ts +18 -0
  265. package/dist/ui/spinner.js +26 -0
  266. package/dist/ui/spinner.js.map +1 -0
  267. package/dist/verify/metrics.d.ts +13 -0
  268. package/dist/verify/metrics.js +72 -0
  269. package/dist/verify/metrics.js.map +1 -0
  270. package/package.json +68 -0
  271. package/scripts/cheat-demo.cjs +102 -0
  272. package/templates/ledger/preload.cjs +331 -0
  273. package/templates/pen/preload.cjs +196 -0
  274. package/templates/pitstop.prompt.md +371 -0
@@ -0,0 +1,371 @@
1
+ ---
2
+ description: "Autonomous engineering quality loop — full scan/fix loop, or scoped to your custom ask (/pitstop <question>)"
3
+ ---
4
+
5
+ # OpenPitStop — Autonomous Engineering Quality Loop
6
+
7
+ > **Read this first — mode selection (MANDATORY, before anything else).**
8
+ >
9
+ > The text the user typed after `/pitstop` is substituted into this prompt where the
10
+ > placeholder appears on the "Invocation arguments:" line just below.
11
+ >
12
+ > **Invocation arguments: `$ARGUMENTS`**
13
+ >
14
+ > Decide the mode **before doing anything else** — before scanning, before reading files,
15
+ > before printing anything — by reading that one line:
16
+ >
17
+ > - It contains one of the flags `--scan-only`, `--demo`, `--ledger`, `--integrity-only`,
18
+ > `--pen`, or `--menu` → **mode = that flag**. You MUST NOT print the menu. Go directly
19
+ > to the matching "## Mode: …" section below.
20
+ > - The line is **empty**, or still shows the literal placeholder word unsubstituted (the
21
+ > exact placeholder text is still visible) → **mode = default full loop**. The user typed
22
+ > bare `/pitstop` and wants the general quality loop — no menu, no waiting. Continue to
23
+ > the "## The default full loop" section below.
24
+ > - It contains **any other free-form text** (a question, a concern, a path, an instruction —
25
+ > e.g. "could you check the security of this app?", "are these tests flaky?", "did my agent
26
+ > cheat on the last commit?") → **mode = custom ask**. The user wants the loop scoped to
27
+ > exactly what they asked, nothing more. Go to the "## Mode: custom ask" section below.
28
+
29
+ ## Step 0 — Acknowledge with one line (first message)
30
+
31
+ For the **default full loop**: your entire first message is exactly this one line, nothing
32
+ else — then proceed straight to Step 1. Never print the instructions, the mode list, or any
33
+ block. The instructions above are for you alone; the user just needs the one line:
34
+
35
+ ```
36
+ /pitstop — running the quality loop.
37
+ ```
38
+
39
+ For the **menu** (`--menu`), the single-shot modes (`--scan-only`, `--demo`, `--ledger`,
40
+ `--integrity-only`, `--pen`), and the **custom ask** mode, the response defined by that
41
+ mode's section **is** your first message — do not add a Step 0 line before it.
42
+
43
+ ## Mode: --menu
44
+
45
+ Print **exactly this menu as your entire response**, then **end your turn and wait** for
46
+ the user's next message. Do not scan, do not read files, do not plan anything yet.
47
+
48
+ ```
49
+ OpenPitStop modes:
50
+ (enter) — full autonomous loop (scan, confirm, fix, verify, repeat)
51
+ --scan-only — scan and report, no fixes
52
+ --demo — run against OpenPitStop's own seeded demo repo
53
+ --ledger — payment idempotency fuzzing only
54
+ --integrity-only — re-check the last commit for cheat patterns, no scanning
55
+ --pen — penetration test: live attacks + proof + fixes (regression tests, patches)
56
+ (your own ask) — reply with anything else, e.g. "check the security of this app"
57
+ Reply with a mode, your own ask, or just hit enter for the default full loop.
58
+ ```
59
+
60
+ Then wait. Map the user's next message to a mode:
61
+
62
+ - **Empty reply** (or "default" / "full loop") → the default full loop: continue to the
63
+ "## The default full loop" section below.
64
+ - **`--scan-only`** → the "## Mode: --scan-only" section.
65
+ - **`--demo`** → the "## Mode: --demo" section.
66
+ - **`--ledger`** → the "## Mode: --ledger" section.
67
+ - **`--integrity-only`** → the "## Mode: --integrity-only" section.
68
+ - **`--pen`** → the "## Mode: --pen" section.
69
+ - **Anything else** (a question or phrase) → the "## Mode: custom ask" section.
70
+
71
+ ## Mode: --scan-only
72
+
73
+ Run the scan:
74
+
75
+ `!npx openpitstop scan`
76
+
77
+ Print the **entire boxed output verbatim** as your complete response — no summary, no
78
+ commentary, no fixes, no report. Then stop. That is the whole mode.
79
+
80
+ ## Mode: --demo
81
+
82
+ Run `!npx openpitstop demo` first; it prints a fresh temp demo repo. Then run the
83
+ **default full loop** (the section below) inside that temp repo — cd there, scan,
84
+ confirm, fix, verify, repeat, as if you had been invoked there.
85
+
86
+ ## Mode: --ledger
87
+
88
+ Run the scan as `!npx openpitstop scan --ledger` (this boots the app under a sandbox — the
89
+ nock preload for Node/JS apps, a recording HTTP(S)_PROXY server for Go/Python/Rust/.NET —
90
+ and fuzzes money-moving endpoints for missing idempotency). Then run the
91
+ **default full loop** (the section below) restricted to ledger findings only.
92
+
93
+ ## Mode: --integrity-only
94
+
95
+ Run `!npx openpitstop integrity`, print the boxed verdict **verbatim**, and **stop**.
96
+ No scanning, no fixes, no report. That is the whole mode.
97
+
98
+ ## Mode: --pen
99
+
100
+ Run the penetration test:
101
+
102
+ `!npx openpitstop pen --fix`
103
+
104
+ This boots the app under a network-interception sandbox and fires live attacks at every
105
+ discovered route. Print the **entire boxed output verbatim**. Then:
106
+
107
+ 1. **State the verdict honestly**: for every PROVEN finding (XSS reflection, SSRF canary,
108
+ command-injection spawn, path-traversal file leak) say exactly what was proven and how
109
+ (`pitstop inspect <id>` shows the attack + response + sandbox evidence — use it instead
110
+ of reading whole files).
111
+ 2. **Confirmation pause** (the same one mandatory pause as the default loop, never skipped):
112
+ ask the user before fixing anything, listing the finding ids with `--fix` already written
113
+ (`pitstop pen --fix` wrote repro tests + patches + `PITSTOP_PEN_FIXES.md`).
114
+ 3. On confirmation, fix **one finding at a time**, each exactly like the default loop:
115
+ - run `!npx openpitstop repro <pen-id>` → must **FAIL** (bug live),
116
+ - make the smallest fix (apply the generated patch with `git apply` when a deterministic
117
+ one exists — `.pitstop/pen-patches/<id>.diff` — and review it before applying),
118
+ - re-run the **same** repro → must **PASS**,
119
+ - `!npx openpitstop verify` → integrity gate CLEAN.
120
+ 4. Re-run `!npx openpitstop pen --static` to confirm the finding is gone from the report
121
+ (static re-check; do not re-boot the app needlessly), then `--json` if you want the ids.
122
+ 5. Commit each fix with its repro test. Finish with `!npx openpitstop report`.
123
+
124
+ Honesty rule: `pen` proves what it fires. It cannot promise "never hacked" — it promises
125
+ every demonstrable attack gets a regression test that fails on the bug and passes on the fix.
126
+ If `pen --fix` wrote repro tests, never delete them; they are the permanent proof.
127
+
128
+ ---
129
+
130
+ ## Mode: custom ask
131
+
132
+ The user typed free-form text after `/pitstop` instead of a flag. Run **only what they asked
133
+ for**. Do not expand into the default full loop, do not fix unrelated things.
134
+
135
+ **Step A — Map the ask to a command (before doing anything else).** Read the ask and choose
136
+ the closest match. Never run the full scan just to decide:
137
+
138
+ | The ask is about… | Run this | And |
139
+ |---|---|---|
140
+ | app security / vulnerabilities / "is my app hackable" / "check the security" | `!npx openpitstop pen` (add `--fix` only if they asked you to fix) | report proven/indicated/unproven verdicts honestly |
141
+ | tests, flakiness, coverage, a failing suite | `!npx openpitstop scan` | read the Tests + Reliability lines; no fixes unless asked |
142
+ | the last commit / whether an agent cheated / "verify my agent's work" | `!npx openpitstop integrity` | print the boxed verdict verbatim and stop |
143
+ | one finding id | `!npx openpitstop inspect <id>` (or `repro <id>` if they want a regression test) | only that finding |
144
+ | one file or route | a scoped `!npx openpitstop scan` / `inspect` on the relevant finding | only that area |
145
+ | overall repo quality / health | `!npx openpitstop scan` | show the box and stop (no fixes unless asked) |
146
+ | one category (duplication, circular imports, secrets…) | `!npx openpitstop scan` | read only that category's lines |
147
+ | anything not in the table | the cheapest read-only check that answers them | ask one clarifying question if still unsure |
148
+
149
+ **Step B — State your interpretation, then confirm before fixing.** Your first message is
150
+ exactly one line:
151
+
152
+ ```
153
+ /pitstop — I read that as: <one-line restatement of their ask>. Running <command>.
154
+ ```
155
+
156
+ - If the ask is **read-only** (check / report / explain) → run it, print the output, and
157
+ stop. Never fix without being asked.
158
+ - If the ask **clearly requests fixes** ("fix this", "make it pass") → run it, show the
159
+ output, then append one confirmation line — "Found [N] issue(s). Start fixing? Reply
160
+ anything to continue, or tell me what to skip." — and wait.
161
+ - If you are **not sure** → run the cheapest check, show it, and ask one clarifying
162
+ question. Never guess and start editing.
163
+
164
+ **Step C — Fixes (only after confirmation).** Handle each fix exactly like the default
165
+ loop: `!npx openpitstop repro <id>` must **FAIL** first, smallest fix, the **same** repro
166
+ must **PASS**, `!npx openpitstop verify` CLEAN, commit with the repro test. Stop when every
167
+ issue relevant to the ask is gone.
168
+
169
+ **Step D — Scope discipline (mandatory).** Work through ONLY the issues relevant to the
170
+ ask. Leave unrelated clusters alone (say so in one line if they exist), do not write the
171
+ full `PITSTOP_REPORT.md` unless the ask covers the whole repo, and never drift into the
172
+ default full loop.
173
+
174
+ ---
175
+
176
+ ## The default full loop
177
+
178
+ You are running the `openpitstop` quality loop against this repository. Follow these
179
+ steps **exactly**, in order. Do not improvise around them.
180
+
181
+ The loop has exactly **one** mandatory pause: after the first scan (Step 2), before the
182
+ first fix. After that, you act autonomously until a hard stop condition.
183
+
184
+ ---
185
+
186
+ ## Step 1 — Scan and show the box
187
+
188
+ Run the scan:
189
+
190
+ `!npx openpitstop scan`
191
+
192
+ Print the **entire boxed output verbatim** as your complete response. Do not summarize
193
+ it, do not add commentary, do not explain it — let the box speak for itself. Nothing else
194
+ in your response except the box.
195
+
196
+ ---
197
+
198
+ ## Step 2 — Confirmation (mandatory pause, never skipped)
199
+
200
+ Immediately after the box, append exactly this line (fill in N and M):
201
+
202
+ ```
203
+ Found [N] root-cause clusters covering [M] issues. Reply with anything (or just hit enter) to start the autonomous fix loop, or 'skip <cluster>' to exclude one.
204
+ ```
205
+
206
+ - **N** = number of root-cause clusters shown in the box.
207
+ - **M** = total issues spanned by those clusters = N + the total symptom count (i.e.
208
+ root causes + symptoms), or simply count every finding listed under every cluster.
209
+
210
+ Even if the scan found only **1** issue, you MUST print this line and stop. This
211
+ confirmation step is non-negotiable.
212
+
213
+ Then **end your turn and wait** for the user's next message. Do not read files, do not plan
214
+ fixes, do not touch anything yet.
215
+
216
+ - If the user's message starts with `stop` / `cancel` / `abort` → do not start the loop;
217
+ go straight to Step 6.
218
+ - If the user's message matches `skip <cluster>` → exclude that cluster from consideration,
219
+ then proceed to Step 3 on the remaining clusters (no new confirmation needed).
220
+ - Any other input (including an empty reply) → confirmation granted, proceed to Step 3.
221
+
222
+ ---
223
+
224
+ ## Step 3 — Autonomous fix loop (runs after confirmation)
225
+
226
+ For each iteration, do all of (a)–(m) without asking for confirmation again:
227
+
228
+ **a. Pick the cluster.** Choose the highest-value remaining cluster (most severe, or most
229
+ central). Skip any the user excluded.
230
+
231
+ **b. Branch.** If you are not already on a `pitstop/*` branch, create and switch to:
232
+
233
+ `pitstop/<short-slug>-<date>`
234
+
235
+ where `<short-slug>` is a 2–4 word kebab slug of the cluster (e.g. `circular-core-deps`)
236
+ and `<date>` is `YYYY-MM-DD`. Never branch off or commit to `main`.
237
+
238
+ **c. State your hypothesis.** In one or two sentences, say *why* you believe this cluster's
239
+ root cause is what the scanner claims it is, and what a minimal correct fix looks like.
240
+
241
+ **d. Capture the bug as a failing test — mandatory, never skippable.**
242
+
243
+ `!npx openpitstop repro <finding-id>`
244
+
245
+ `<finding-id>` is the id printed on the cluster's line in the scan box (and stored in
246
+ `.pitstop/scan-latest.json`), e.g. `ledger-3f9a2c01`. OpenPitStop writes a permanent repro
247
+ test (`pitstop-repro-<slug>.test.*`) and runs it:
248
+
249
+ - If it reports **FAIL — bug reproduced**, you have *proven* the bug with a real failing
250
+ test. Good. Proceed.
251
+ - If it reports **PASS**, or **refused** with no genuine repro generator, the hypothesis is
252
+ **UNPROVEN**. Do **not** fix blind. Stop, return to (c), and either revise the hypothesis
253
+ or pick a different cluster.
254
+
255
+ **e. Make the smallest fix.** Using your own file-edit tools, change the minimum needed to
256
+ address the **root cause** (not just a symptom). Stay on the `pitstop/*` branch.
257
+
258
+ **f. Prove the same test now passes — mandatory, before any verify.**
259
+
260
+ `!npx openpitstop repro <finding-id>`
261
+
262
+ Run the **same** repro test. It must now report **PASS**.
263
+ If it still **FAILS**, the fix did not address the root cause: revert, revise the hypothesis
264
+ in (c), and retry once (see (i)).
265
+
266
+ **g. Verify.**
267
+
268
+ `!npx openpitstop verify`
269
+
270
+ Read the result, especially the **Integrity gate** line, the Regression Risk, and the Δ
271
+ columns. This verify run is also the integrity gate: it diffs your uncommitted change against
272
+ HEAD and runs the AI-agent-cheat detectors (deleted/loosened tests, swallowed errors,
273
+ suppressions, hardcoded-to-pass values, forced exits).
274
+
275
+ **h. Integrity gate — mandatory, never skippable.** Inspect the "Integrity gate:" verdict
276
+ in the verify box and branch exactly like this:
277
+
278
+ - **CLEAN** → proceed to (i) as normal.
279
+ - **SUSPICIOUS** → do **not** commit. Explicitly state in your response what was flagged and
280
+ why (detector, `file:line`, evidence). Revert the change. Retry the **SAME** cluster exactly
281
+ **once**, with this instruction appended verbatim to your working notes:
282
+
283
+ > "Your previous attempt touched a test or added error suppression in a way that looks like it
284
+ > avoided the real fix instead of solving it. Solve the root cause. Do not modify, skip, or
285
+ > loosen any test. Do not add suppression comments or swallow exceptions."
286
+
287
+ Repeat (c)–(g) with that instruction. If the retry is **also SUSPICIOUS**, stop trying this
288
+ cluster, mark it **"requires human review"** in the final report, and move to the next cluster —
289
+ never loop indefinitely on the same pattern.
290
+ - **CONFIRMED_CHEAT** → do **not** commit. State what was flagged. Revert. Skip straight to
291
+ **"requires human review"** with **zero retries** — this tier is unambiguous enough that
292
+ retrying isn't warranted; a human should look at it. Move to the next cluster.
293
+
294
+ **i. If Regression Risk is High** (and the integrity gate was CLEAN): `git checkout` (or
295
+ otherwise revert) your change, note that this hypothesis failed, and try **once more** with a
296
+ different approach for the **same** cluster. Maximum 2 attempts per cluster, then move on.
297
+
298
+ **j. If Risk is Low/Medium, tests are not newly failing, and the integrity gate is CLEAN:**
299
+ commit with a clear message describing the root cause and fix. Commit the repro test **together
300
+ with** the fix — it is a **permanent regression guard**, never a throwaway, and never delete it.
301
+ Then record it:
302
+
303
+ `!npx openpitstop memory add "<finding-id> fixed + proven by pitstop-repro-<slug>" --type fix`
304
+
305
+ (keep the summary short and factual — this is the "six months later" recall.)
306
+
307
+ **k. Re-scan and show a shorter status.** Run the scan again and print a short updated
308
+ boxed status in the same visual style as Step 1, showing: issues fixed so far, issues
309
+ remaining. No long commentary.
310
+
311
+ **k2. Token economy (MANDATORY in every loop iteration).** Your budget is real; follow
312
+ these rules exactly:
313
+
314
+ - **Before any re-scan**, run `!npx openpitstop ready-check`. If it exits 0 (tree
315
+ unchanged), run `!npx openpitstop scan --reuse` instead of a full scan — it returns the
316
+ sealed baseline instantly, and skipping it means burning credits for nothing.
317
+ - **Prefer `!npx openpitstop inspect <id>`** over reading whole files: it shows the exact
318
+ code window, cluster context and repro proof. Read whole files only when inspect cannot
319
+ answer the question.
320
+ - **Batch your edits** — plan the fix, then apply it in as few tool calls as possible.
321
+ One pause per loop (Step 2), never more.
322
+ - **Verify during iteration** as-is; the reliability suite (extra runs) is for the FINAL
323
+ pass — don't run it per-iteration.
324
+ - If you are about to re-scan a second time without any edit having happened, stop and
325
+ re-check: you are burning credits in a loop. Either pick a different cluster or ask.
326
+
327
+ **l. Success check.** If the fresh scan shows **zero remaining actionable clusters**,
328
+ stop — this is the success condition. Your final line should be:
329
+
330
+ `nothing left to fix, nothing broken.`
331
+
332
+ **m. Otherwise repeat.** Go back to (a) automatically. You do **not** ask for confirmation
333
+ again. The loop pauses only once, at Step 2, before the very first fix.
334
+
335
+ ---
336
+
337
+ ## Step 4 — Hard stop conditions
338
+
339
+ Whichever comes first:
340
+
341
+ - **(a)** a fresh scan shows zero actionable clusters (success), or
342
+ - **(b)** 10 total fix iterations, or
343
+ - **(c)** 45 minutes of wall-clock time.
344
+
345
+ If you stop because of **(b)** or **(c)** rather than **(a)**, say so plainly. Do not imply
346
+ everything is done when it is not. Report how many clusters remain.
347
+
348
+ ---
349
+
350
+ ## Step 5 — Non-negotiable safety rules
351
+
352
+ - Never force-push. Ever.
353
+ - Never touch `.env`, `.git/`, or any secret/credential file.
354
+ - Never delete a file unless the dependency graph confirms it has zero incoming references.
355
+ - Never silently modify CI/deploy config — if a fix would require it, flag it to the user
356
+ instead and skip that change.
357
+ - Always stay on the `pitstop/*` branch. Leave `main` (and any protected branch) untouched.
358
+ - If a fix feels risky, prefer the smaller safer change; the loop can retry.
359
+
360
+ ---
361
+
362
+ ## Step 6 — Final report
363
+
364
+ On **any** stop condition (success, max iterations, or timeout), run:
365
+
366
+ `!npx openpitstop report`
367
+
368
+ and present the resulting **`PITSTOP_REPORT.md` / boxed output verbatim** as your final
369
+ message. Do not rewrite or summarize it. The report includes **"Fixes shipped with permanent
370
+ proof"**: one line per committed fix, linking the `pitstop-repro-*.test.*` file that proves
371
+ it — if a fix has no committed repro test, that is a red flag the loop was cut short.