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,136 @@
1
+ import { Command } from "commander";
2
+ import chalk from "chalk";
3
+ import boxen from "boxen";
4
+ import path from "node:path";
5
+ import { runVerify } from "./verify.js";
6
+ /**
7
+ * `pitstop gate` — the agentless, CI-usable gate. One command answers "is this
8
+ * change safe to commit?" with a plain exit code:
9
+ *
10
+ * exit 0 PASS — score >= threshold, integrity clean, evidence chain intact
11
+ * exit 1 FAIL — score below threshold, High regression risk, SUSPICIOUS
12
+ * integrity, or tampered evidence
13
+ * exit 2 FAIL-HARD — CONFIRMED_CHEAT integrity violation
14
+ *
15
+ * No AI tool, no `/pitstop` loop, no config: scan (or try) once for the
16
+ * baseline, then `pitstop gate` every step of a fix loop — also usable as a
17
+ * pre-commit hook or the last line of a CI job.
18
+ */
19
+ function gateOutcome(o, threshold) {
20
+ if (o.missingBaseline) {
21
+ return {
22
+ pass: false,
23
+ exitCode: 1,
24
+ reasons: ["no baseline — run `pitstop scan` (or `pitstop try`) once to create one"],
25
+ };
26
+ }
27
+ const reasons = [];
28
+ let exitCode = 0;
29
+ if (o.blocked) {
30
+ if (o.integrity.verdict === "CONFIRMED_CHEAT") {
31
+ reasons.push(`integrity gate CONFIRMED_CHEAT (${o.integrity.summary.confirmed} confirmed findings)`);
32
+ exitCode = 2;
33
+ }
34
+ else {
35
+ reasons.push(`integrity gate ${o.integrity.verdict} — needs human review before committing`);
36
+ exitCode = 1;
37
+ }
38
+ }
39
+ if (o.evidence?.status === "tampered") {
40
+ reasons.push("evidence chain broken — baseline was edited after OpenPitStop signed it; re-run `pitstop scan`");
41
+ exitCode = Math.max(exitCode, 1);
42
+ }
43
+ if (o.risk === "High") {
44
+ reasons.push("regression risk High — suite or perf regressed vs baseline");
45
+ exitCode = Math.max(exitCode, 1);
46
+ }
47
+ if (o.currentScore.score < threshold) {
48
+ reasons.push(`OpenPitStop Score ${o.currentScore.score}/100 is below the ${threshold}/100 gate`);
49
+ exitCode = Math.max(exitCode, 1);
50
+ }
51
+ if (o.stale) {
52
+ reasons.push(`⚠ ${o.staleNote}`);
53
+ }
54
+ return { pass: exitCode === 0, exitCode, reasons };
55
+ }
56
+ function renderGateBox(o, gate, threshold) {
57
+ const score = o.currentScore;
58
+ const scorePaint = score.score >= threshold ? chalk.greenBright : chalk.red;
59
+ const lines = [];
60
+ lines.push(`${chalk.bold("OpenPitStop Score")}: ${scorePaint.bold(`${score.score}/100 (${score.grade})`)} — gate at ${threshold}/100`);
61
+ lines.push(`${chalk.bold("Integrity")}: ${o.blocked
62
+ ? chalk.red(o.integrity.verdict)
63
+ : chalk.green(o.integrity.verdict)} · ${o.integrity.summary.total} finding(s)`);
64
+ lines.push(`${chalk.bold("Evidence")}: ${o.evidence?.status === "verified"
65
+ ? chalk.green(`verified ${o.evidence.digest.slice(0, 12)}…`)
66
+ : o.evidence?.status === "tampered"
67
+ ? chalk.red("TAMPERED")
68
+ : chalk.yellow("untracked (pre-0.6.0 baseline)")}`);
69
+ lines.push(`${chalk.bold("Risk")}: ${o.risk === "High" ? chalk.red("HIGH") : o.risk === "Medium" ? chalk.yellow("MEDIUM") : chalk.green("LOW")}`);
70
+ if (gate.reasons.length > 0) {
71
+ lines.push("");
72
+ for (const r of gate.reasons)
73
+ lines.push(r.startsWith("⚠") ? chalk.yellow(r) : chalk.red(`✗ ${r}`));
74
+ }
75
+ if (gate.pass) {
76
+ lines.push("");
77
+ lines.push(chalk.green("PASS — safe to commit."));
78
+ }
79
+ else {
80
+ lines.push("");
81
+ lines.push(chalk.red("FAIL — do not commit this state."));
82
+ }
83
+ return boxen(lines.join("\n"), {
84
+ title: ` PITSTOP — GATE ${gate.pass ? "PASS" : "FAIL"} `,
85
+ titleAlignment: "center",
86
+ borderStyle: gate.pass ? "round" : "double",
87
+ padding: 1,
88
+ borderColor: gate.pass ? "green" : exitCodeColor(gate.exitCode),
89
+ });
90
+ }
91
+ function exitCodeColor(code) {
92
+ return code >= 2 ? "red" : "yellow";
93
+ }
94
+ export const gate = new Command("gate")
95
+ .description("Agentless commit gate: verifies score vs threshold, regression risk, integrity diff and " +
96
+ "the baseline evidence signature — exit 0=PASS, 1=FAIL, 2=CONFIRMED_CHEAT. CI and " +
97
+ "pre-commit ready; no AI tool required.")
98
+ .argument("[repo]", "path to the repo to gate (default: current dir)", ".")
99
+ .option("--score <n>", "minimum OpenPitStop Score required to pass (default 60; 0 disables the score check)", "60")
100
+ .option("--json", "print a machine-readable gate result")
101
+ .action(async (repoArg, options) => {
102
+ const repo = path.resolve(repoArg);
103
+ const threshold = Math.max(0, Math.min(100, Math.floor(Number(options.score) || 60)));
104
+ if (!options.json) {
105
+ console.log(chalk.cyan(`\nGating ${repo} (score >= ${threshold}/100) ...\n`));
106
+ }
107
+ const outcome = await runVerify(repo);
108
+ const gateResult = gateOutcome(outcome, threshold);
109
+ if (options.json) {
110
+ console.log(JSON.stringify({
111
+ repo,
112
+ pass: gateResult.pass,
113
+ exitCode: gateResult.exitCode,
114
+ reasons: gateResult.reasons,
115
+ threshold,
116
+ score: outcome.missingBaseline ? null : outcome.currentScore.score,
117
+ grade: outcome.missingBaseline ? null : outcome.currentScore.grade,
118
+ risk: outcome.missingBaseline ? null : outcome.risk,
119
+ integrity: outcome.missingBaseline ? null : outcome.integrity.verdict,
120
+ evidence: outcome.evidence?.status ?? "missing",
121
+ stale: outcome.stale,
122
+ baselineTimestamp: outcome.baselineTimestamp ?? null,
123
+ }, null, 2));
124
+ }
125
+ else if (outcome.missingBaseline) {
126
+ console.log(chalk.red(`no baseline found — run \`pitstop scan\` (or \`pitstop try\`) once to create one`));
127
+ }
128
+ else {
129
+ console.log(renderGateBox(outcome, gateResult, threshold));
130
+ if (outcome.file) {
131
+ console.log(chalk.dim(`\nVerify report written to ${outcome.file}\n`));
132
+ }
133
+ }
134
+ process.exitCode = gateResult.exitCode;
135
+ });
136
+ //# sourceMappingURL=gate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate.js","sourceRoot":"","sources":["../../src/commands/gate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare const honesty: Command;
@@ -0,0 +1,182 @@
1
+ import { Command } from "commander";
2
+ import chalk from "chalk";
3
+ import boxen from "boxen";
4
+ import path from "node:path";
5
+ import fs from "node:fs";
6
+ import { buildModel, escapeHtml, loadHistory, loadProofs } from "../report/format.js";
7
+ import { computeScore, gradeHex } from "../report/score.js";
8
+ import { checkEvidence } from "../evidence.js";
9
+ import { enumerateFindings } from "../repro/ids.js";
10
+ /**
11
+ * `pitstop honesty` — the proof that the AI agent did honest work.
12
+ *
13
+ * Combines the evidence chain (signed baselines), the integrity gate history
14
+ * (cheat attempts caught + self-corrected), the verify delta, and the
15
+ * committed repro tests — and states, plainly, whether the recorded work is
16
+ * trustworthy. `--html` writes a self-contained shareable certificate.
17
+ */
18
+ function honestyVerdict(args) {
19
+ const reasons = [];
20
+ if (args.confirmedCheats > 0) {
21
+ reasons.push("a CONFIRMED_CHEAT integrity violation is on record");
22
+ return { label: "UNDER REVIEW — cheating attempted", color: "red", reasons };
23
+ }
24
+ if (args.evidence === "tampered") {
25
+ reasons.push("the baseline evidence chain is broken — reports were edited after OpenPitStop signed them");
26
+ return { label: "SUSPICIOUS — evidence edited", color: "red", reasons };
27
+ }
28
+ if (args.latestVerify?.risk === "High") {
29
+ reasons.push("latest verify shows High regression risk");
30
+ return { label: "HONEST BUT RISKY", color: "yellow", reasons };
31
+ }
32
+ if (args.integrityChecks > 0 && args.integrityCatches > 0) {
33
+ reasons.push(`${args.integrityCatches} attempted cheat(s) caught and blocked — the gate worked`);
34
+ }
35
+ if (args.evidence === "untracked") {
36
+ reasons.push("baseline predates evidence signing (pre-0.6.0) — re-scan for a signed chain");
37
+ return { label: "HONEST (unsigned evidence)", color: "yellow", reasons };
38
+ }
39
+ if (args.proofs === 0) {
40
+ reasons.push("no committed repro tests — fixes were not captured as failing-then-passing proof");
41
+ }
42
+ reasons.push("all checks passed: evidence verified, integrity clean, no regressions");
43
+ return { label: "HONEST ✓", color: "green", reasons };
44
+ }
45
+ export const honesty = new Command("honesty")
46
+ .description("The AI-honesty proof report: evidence chain + integrity gate history + verify delta + committed " +
47
+ "repro tests, distilled into one verdict. --html writes a self-contained shareable certificate.")
48
+ .argument("[repo]", "path to the repo (default: current dir)", ".")
49
+ .option("--html", "also write a self-contained PITSTOP_HONESTY.html certificate")
50
+ .action((repoArg, options) => {
51
+ const repo = path.resolve(repoArg);
52
+ const model = buildModel(repo);
53
+ const hist = loadHistory(repo);
54
+ if (!model.latestScan) {
55
+ console.log(chalk.yellow(`no scan history in ${path.join(repo, ".pitstop")} — run \`pitstop scan\` first.`));
56
+ return;
57
+ }
58
+ const sc = computeScore(model.latestScan);
59
+ const ev = checkEvidence(model.latestScan);
60
+ const proofs = loadProofs(repo);
61
+ // Which committed repro tests are still needed? A finding that no longer
62
+ // appears in the latest scan is permanently proven fixed; one that still
63
+ // appears means the proof exists but the fix is not in yet.
64
+ const liveIds = new Set(enumerateFindings(model.latestScan).map((f) => f.id));
65
+ const proved = proofs.filter((p) => p.findingId && !liveIds.has(p.findingId));
66
+ const pending = proofs.filter((p) => p.findingId && liveIds.has(p.findingId));
67
+ const integ = model.integrity;
68
+ const confirmedCheats = integ?.events.filter((e) => e.verdict === "CONFIRMED_CHEAT").length ?? 0;
69
+ const verdict = honestyVerdict({
70
+ evidence: ev.status,
71
+ latestVerify: model.latestVerify,
72
+ integrityChecks: integ?.checks ?? 0,
73
+ integrityCatches: integ?.catches ?? 0,
74
+ confirmedCheats,
75
+ proofs: proofs.length,
76
+ });
77
+ const vpaint = verdict.color === "green" ? chalk.green : verdict.color === "yellow" ? chalk.yellow : chalk.red;
78
+ const lines = [];
79
+ lines.push(`${chalk.bold("Verdict")}: ${vpaint.bold(verdict.label)}`);
80
+ lines.push("");
81
+ lines.push(`${chalk.bold("Evidence chain")}: ${ev.status === "verified" ? chalk.green(`verified — ${ev.digest.slice(0, 16)}…`) : ev.status === "tampered" ? chalk.red("TAMPERED") : chalk.yellow("untracked")}`);
82
+ lines.push(`${chalk.bold("Integrity gate")}: ${integ
83
+ ? `${integ.checks} check(s) · ${integ.catches} catch(es) · ${chalk.green(`${integ.selfCorrected} self-corrected`)}${confirmedCheats > 0 ? ` · ${chalk.red(`${confirmedCheats} CONFIRMED_CHEAT`)}` : ""}`
84
+ : chalk.dim("no checks recorded")}`);
85
+ lines.push(`${chalk.bold("Score")}: ${vpaint(`${sc.score}/100 (${sc.grade})`)}${model.latestVerify?.score
86
+ ? ` · verify delta ${model.latestVerify.score.delta > 0 ? "+" : ""}${model.latestVerify.score.delta} pts · risk ${model.latestVerify.risk}`
87
+ : ""}`);
88
+ lines.push(`${chalk.bold("Permanent proof")}: ${proved.length > 0
89
+ ? chalk.green(`${proved.length} finding(s) proven fixed (repro test committed, finding gone)`)
90
+ : chalk.yellow("none proven fixed yet")}${pending.length > 0 ? chalk.dim(` · ${pending.length} repro test(s) with the finding still open`) : ""}`);
91
+ lines.push("");
92
+ lines.push(chalk.bold("Why:"));
93
+ for (const r of verdict.reasons)
94
+ lines.push(` · ${r.startsWith("all checks") ? chalk.green(r) : chalk.yellow(r)}`);
95
+ lines.push("");
96
+ lines.push(chalk.dim("every figure is read from .pitstop/scan-*.json, verify-*.json and the committed pitstop-repro-*.test.* files"));
97
+ const color = verdict.color === "green" ? "green" : "yellow";
98
+ console.log(boxen(lines.join("\n"), {
99
+ title: ` PITSTOP — Honesty ${verdict.label.split(" ")[0]} `,
100
+ titleAlignment: "center",
101
+ borderStyle: verdict.color === "green" ? "round" : "double",
102
+ padding: 1,
103
+ borderColor: verdict.color === "red" ? "red" : color,
104
+ }));
105
+ if (options.html) {
106
+ const accent = gradeHex(sc.grade);
107
+ const badge = `background:${accent};color:#0d1117;font-weight:800;font-size:56px;padding:18px 30px;border-radius:16px`;
108
+ const html = `<!DOCTYPE html>
109
+ <html lang="en">
110
+ <head>
111
+ <meta charset="utf-8"/>
112
+ <meta name="viewport" content="width=device-width, initial-scale=1"/>
113
+ <title>PITSTOP — Honesty report for ${escapeHtml(repo)}</title>
114
+ <style>
115
+ :root{color-scheme:dark}
116
+ *{box-sizing:border-box;margin:0;padding:0}
117
+ body{background:#0d1117;color:#e6edf3;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;padding:48px 24px}
118
+ .wrap{max-width:760px;margin:0 auto}
119
+ h1{font-size:22px;margin-bottom:4px}
120
+ .sub{color:#8b949e;font-size:13px;margin-bottom:28px}
121
+ .card{background:#161b22;border:1px solid #30363d;border-radius:14px;padding:24px;margin-bottom:18px}
122
+ .verdict{font-size:28px;font-weight:800;color:${verdict.color === "green" ? "#3fb950" : verdict.color === "yellow" ? "#d29922" : "#f85149"};margin-bottom:10px}
123
+ .scoreline{display:flex;align-items:center;gap:22px;flex-wrap:wrap}
124
+ .score{${badge}}
125
+ .meta{color:#8b949e;font-size:14px;line-height:1.7}
126
+ .meta b{color:#e6edf3}
127
+ table{width:100%;border-collapse:collapse;font-size:14px}
128
+ th,td{text-align:left;padding:9px 12px;border-bottom:1px solid #21262d}
129
+ th{color:#8b949e;font-weight:600;font-size:12px;text-transform:uppercase;letter-spacing:0.4px}
130
+ .ok{color:#3fb950;font-weight:600}
131
+ .warn{color:#d29922;font-weight:600}
132
+ .bad{color:#f85149;font-weight:600}
133
+ ul{list-style:none;padding:0}
134
+ li{padding:7px 0;border-bottom:1px solid #21262d;font-size:14px}
135
+ li:last-child{border-bottom:none}
136
+ .footer{color:#8b949e;font-size:12px;margin-top:28px;text-align:center}
137
+ code{background:#21262d;padding:1px 6px;border-radius:5px;font-size:12px}
138
+ </style>
139
+ </head>
140
+ <body><div class="wrap">
141
+ <h1>PITSTOP — AI Honesty Report</h1>
142
+ <p class="sub">${escapeHtml(repo)} · generated ${escapeHtml(model.generatedAt.slice(0, 19).replace("T", " "))} · ${hist.scans.length} scan(s), ${hist.verifies.length} verify(ies)</p>
143
+
144
+ <div class="card">
145
+ <div class="verdict">${escapeHtml(verdict.label)}</div>
146
+ <div class="scoreline">
147
+ <div class="score">${sc.score}/100</div>
148
+ <div class="meta">
149
+ <div>grade <b>${sc.grade}</b></div>
150
+ ${model.latestVerify?.score ? `<div>verify delta <b>${model.latestVerify.score.delta > 0 ? "+" : ""}${model.latestVerify.score.delta} pts</b> · risk <b>${model.latestVerify.risk}</b></div>` : ""}
151
+ <div>evidence chain: <b>${ev.status === "verified" ? "verified" : ev.status}</b></div>
152
+ </div>
153
+ </div>
154
+ </div>
155
+
156
+ <div class="card">
157
+ <table>
158
+ <thead><tr><th>Check</th><th>Result</th></tr></thead>
159
+ <tbody>
160
+ <tr><td>Evidence signature</td><td class="${ev.status === "verified" ? "ok" : ev.status === "tampered" ? "bad" : "warn"}">${ev.status === "verified" ? "✓ verified — " + ev.digest.slice(0, 12) + "…" : ev.status === "tampered" ? "✗ TAMPERED" : "untracked (pre-0.6.0)"}</td></tr>
161
+ <tr><td>Integrity gate checks</td><td>${integ?.checks ?? 0}</td></tr>
162
+ <tr><td>Cheat attempts caught</td><td class="${confirmedCheats > 0 ? "bad" : integ && integ.catches > 0 ? "warn" : "ok"}">${integ?.catches ?? 0}${confirmedCheats > 0 ? " · CONFIRMED_CHEAT on record" : ""}</td></tr>
163
+ <tr><td>Self-corrected by the loop</td><td class="ok">${integ?.selfCorrected ?? 0}</td></tr>
164
+ <tr><td>Findings proven fixed</td><td class="${proved.length > 0 ? "ok" : "warn"}">${proved.length}${pending.length > 0 ? ` · ${pending.length} repro test(s) with finding still open` : ""}</td></tr>
165
+ <tr><td>Committed repro tests</td><td>${proofs.length}</td></tr>
166
+ </tbody>
167
+ </table>
168
+ </div>
169
+
170
+ <div class="card">
171
+ <h2 style="font-size:15px;margin-bottom:10px">Why this verdict</h2>
172
+ <ul>${verdict.reasons.map((r) => `<li>${escapeHtml(r)}</li>`).join("")}</ul>
173
+ </div>
174
+
175
+ <div class="footer">Every figure read from .pitstop/scan-*.json, .pitstop/verify-*.json and the committed pitstop-repro-*.test.* files · sealed with pitstop-sha256-canonical-v1</div>
176
+ </div></body></html>`;
177
+ const out = path.join(repo, "PITSTOP_HONESTY.html");
178
+ fs.writeFileSync(out, html);
179
+ console.log(chalk.dim(`\nCertificate written to ${out}\n`));
180
+ }
181
+ });
182
+ //# sourceMappingURL=honesty.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"honesty.js","sourceRoot":"","sources":["../../src/commands/honesty.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtF,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEpD;;;;;;;GAOG;AACH,SAAS,cAAc,CAAC,IAOvB;IACC,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,IAAI,IAAI,CAAC,eAAe,GAAG,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC;QACnE,OAAO,EAAE,KAAK,EAAE,mCAAmC,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IAC/E,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,KAAK,UAAU,EAAE,CAAC;QACjC,OAAO,CAAC,IAAI,CAAC,2FAA2F,CAAC,CAAC;QAC1G,OAAO,EAAE,KAAK,EAAE,8BAA8B,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IAC1E,CAAC;IACD,IAAI,IAAI,CAAC,YAAY,EAAE,IAAI,KAAK,MAAM,EAAE,CAAC;QACvC,OAAO,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;QACzD,OAAO,EAAE,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;IACjE,CAAC;IACD,IAAI,IAAI,CAAC,eAAe,GAAG,CAAC,IAAI,IAAI,CAAC,gBAAgB,GAAG,CAAC,EAAE,CAAC;QAC1D,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,gBAAgB,0DAA0D,CAAC,CAAC;IACnG,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;QAClC,OAAO,CAAC,IAAI,CAAC,6EAA6E,CAAC,CAAC;QAC5F,OAAO,EAAE,KAAK,EAAE,4BAA4B,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;IAC3E,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,IAAI,CAAC,kFAAkF,CAAC,CAAC;IACnG,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,uEAAuE,CAAC,CAAC;IACtF,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AACxD,CAAC;AAED,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,SAAS,CAAC;KAC1C,WAAW,CACV,kGAAkG;IAChG,gGAAgG,CACnG;KACA,QAAQ,CAAC,QAAQ,EAAE,yCAAyC,EAAE,GAAG,CAAC;KAClE,MAAM,CAAC,QAAQ,EAAE,8DAA8D,CAAC;KAChF,MAAM,CAAC,CAAC,OAAe,EAAE,OAA2B,EAAE,EAAE;IACvD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IAE/B,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,MAAM,CAAC,sBAAsB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,gCAAgC,CAAC,CAChG,CAAC;QACF,OAAO;IACT,CAAC;IAED,MAAM,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAC1C,MAAM,EAAE,GAAG,aAAa,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAEhC,yEAAyE;IACzE,yEAAyE;IACzE,4DAA4D;IAC5D,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,iBAAiB,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9E,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAC9E,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAE9E,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC;IAC9B,MAAM,eAAe,GACnB,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,iBAAiB,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC;IAC3E,MAAM,OAAO,GAAG,cAAc,CAAC;QAC7B,QAAQ,EAAE,EAAE,CAAC,MAAM;QACnB,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,eAAe,EAAE,KAAK,EAAE,MAAM,IAAI,CAAC;QACnC,gBAAgB,EAAE,KAAK,EAAE,OAAO,IAAI,CAAC;QACrC,eAAe;QACf,MAAM,EAAE,MAAM,CAAC,MAAM;KACtB,CAAC,CAAC;IAEH,MAAM,MAAM,GACV,OAAO,CAAC,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;IAElG,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACtE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IACjN,KAAK,CAAC,IAAI,CACR,GAAG,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAC7B,KAAK;QACH,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,eAAe,KAAK,CAAC,OAAO,gBAAgB,KAAK,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,aAAa,iBAAiB,CAAC,GAAG,eAAe,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,eAAe,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE;QACxM,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,oBAAoB,CACpC,EAAE,CACH,CAAC;IACF,KAAK,CAAC,IAAI,CACR,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,MAAM,CAAC,GAAG,EAAE,CAAC,KAAK,SAAS,EAAE,CAAC,KAAK,GAAG,CAAC,GAChE,KAAK,CAAC,YAAY,EAAE,KAAK;QACvB,CAAC,CAAC,mBAAmB,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,eAAe,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE;QAC3I,CAAC,CAAC,EACN,EAAE,CACH,CAAC;IACF,KAAK,CAAC,IAAI,CACR,GAAG,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,KAC9B,MAAM,CAAC,MAAM,GAAG,CAAC;QACf,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,MAAM,+DAA+D,CAAC;QAC9F,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,uBAAuB,CAC1C,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,OAAO,CAAC,MAAM,4CAA4C,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAC3G,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/B,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,OAAO;QAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACpH,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,8GAA8G,CAAC,CAAC,CAAC;IAEtI,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;IAE7D,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QACtB,KAAK,EAAE,sBAAsB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG;QAC3D,cAAc,EAAE,QAAQ;QACxB,WAAW,EAAE,OAAO,CAAC,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ;QAC3D,OAAO,EAAE,CAAC;QACV,WAAW,EAAE,OAAO,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK;KACrD,CAAC,CACH,CAAC;IAEF,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,MAAM,MAAM,GAAG,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;QAClC,MAAM,KAAK,GAAG,cAAc,MAAM,oFAAoF,CAAC;QACvH,MAAM,IAAI,GAAG;;;;;sCAKmB,UAAU,CAAC,IAAI,CAAC;;;;;;;;;kDASJ,OAAO,CAAC,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;;WAEjI,KAAK;;;;;;;;;;;;;;;;;;mBAkBG,UAAU,CAAC,IAAI,CAAC,gBAAgB,UAAU,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,aAAa,IAAI,CAAC,QAAQ,CAAC,MAAM;;;2BAG5I,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC;;2BAEzB,EAAE,CAAC,KAAK;;wBAEX,EAAE,CAAC,KAAK;UACtB,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,CAAC,wBAAwB,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,sBAAsB,KAAK,CAAC,YAAY,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,EAAE;kCACxK,EAAE,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM;;;;;;;;;oDAS/B,EAAE,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,KAAK,EAAE,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,eAAe,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,uBAAuB;gDACjO,KAAK,EAAE,MAAM,IAAI,CAAC;uDACX,eAAe,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,EAAE,OAAO,IAAI,CAAC,GAAG,eAAe,GAAG,CAAC,CAAC,CAAC,CAAC,8BAA8B,CAAC,CAAC,CAAC,EAAE;gEACnJ,KAAK,EAAE,aAAa,IAAI,CAAC;uDAClC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,MAAM,wCAAwC,CAAC,CAAC,CAAC,EAAE;gDACnJ,MAAM,CAAC,MAAM;;;;;;;UAOnD,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;;;;qBAIrD,CAAC;QAChB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,sBAAsB,CAAC,CAAC;QACpD,EAAE,CAAC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,4BAA4B,GAAG,IAAI,CAAC,CAAC,CAAC;IAC9D,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare const inspect: Command;
@@ -0,0 +1,244 @@
1
+ import { Command } from "commander";
2
+ import chalk from "chalk";
3
+ import boxen from "boxen";
4
+ import path from "node:path";
5
+ import fs from "node:fs";
6
+ import { resolveFinding } from "../repro/ids.js";
7
+ import { loadProofs } from "../report/format.js";
8
+ import { relevantEntriesForFiles } from "../memory/store.js";
9
+ import { loadPenLatest, resolvePenFinding } from "../pen/store.js";
10
+ /**
11
+ * `pitstop inspect <finding-id>` — deep dive on a single finding.
12
+ *
13
+ * Shows the exact code, the cluster it belongs to, whether a permanent repro
14
+ * test exists, and the memory OpenPitStop has about the files involved. One
15
+ * command from the scan box to a fully actionable picture.
16
+ */
17
+ function latestScan(repo) {
18
+ const p = path.join(repo, ".pitstop", "scan-latest.json");
19
+ if (!fs.existsSync(p))
20
+ return null;
21
+ try {
22
+ return JSON.parse(fs.readFileSync(p, "utf8"));
23
+ }
24
+ catch {
25
+ return null;
26
+ }
27
+ }
28
+ function severityPaint(sev) {
29
+ switch (sev) {
30
+ case "critical":
31
+ case "high":
32
+ return chalk.red;
33
+ case "medium":
34
+ return chalk.yellow;
35
+ default:
36
+ return chalk.dim;
37
+ }
38
+ }
39
+ function rel(repo, p) {
40
+ if (!p)
41
+ return "";
42
+ // Cluster files are stored relative to the repo; issue files are absolute.
43
+ if (!path.isAbsolute(p))
44
+ return p.replace(/\\/g, "/");
45
+ try {
46
+ return path.relative(repo, p).replace(/\\/g, "/");
47
+ }
48
+ catch {
49
+ return p;
50
+ }
51
+ }
52
+ function resolve(repo, p) {
53
+ if (!p)
54
+ return null;
55
+ return path.isAbsolute(p) ? p : path.resolve(repo, p);
56
+ }
57
+ /** ±6 lines around the finding, target line highlighted. */
58
+ function codeSnippet(repo, f) {
59
+ const abs = resolve(repo, f.file);
60
+ if (!abs || !fs.existsSync(abs))
61
+ return [];
62
+ let content;
63
+ try {
64
+ content = fs.readFileSync(abs, "utf8");
65
+ }
66
+ catch {
67
+ return [];
68
+ }
69
+ const lines = content.split(/\r?\n/);
70
+ const hasLine = f.line != null;
71
+ const target = f.line ?? 1;
72
+ const start = Math.max(1, target - 6);
73
+ const end = Math.min(lines.length, target + 6);
74
+ const width = String(end).length;
75
+ const out = [];
76
+ for (let i = start; i <= end; i++) {
77
+ const gut = String(i).padStart(width);
78
+ const raw = lines[i - 1] ?? "";
79
+ const body = raw.length > 100 ? raw.slice(0, 100) + " …" : raw;
80
+ const isTarget = hasLine && i === target;
81
+ out.push(isTarget
82
+ ? `${chalk.dim(gut + " │")} ${chalk.bgRed(chalk.black("►"))} ${chalk.bold(body)}`
83
+ : `${chalk.dim(gut + " │")} ${chalk.dim(body)}`);
84
+ }
85
+ return out;
86
+ }
87
+ function clusterOf(r, id) {
88
+ for (const c of r.clusters ?? []) {
89
+ const ids = [c.rootCause.id, ...c.symptoms.map((s) => s.id)].filter(Boolean);
90
+ if (ids.includes(id))
91
+ return c;
92
+ }
93
+ return null;
94
+ }
95
+ function memoryLines(repo, f, c) {
96
+ const files = c ? c.sharedFiles : f.file ? [f.file] : [];
97
+ if (files.length === 0)
98
+ return [];
99
+ const entries = relevantEntriesForFiles(repo, files);
100
+ if (entries.length === 0)
101
+ return [];
102
+ const typeColor = (e) => {
103
+ switch (e.type) {
104
+ case "decision": return chalk.cyan;
105
+ case "fix": return chalk.green;
106
+ case "rejection": return chalk.red;
107
+ }
108
+ };
109
+ const out = [chalk.bold("OpenPitStop memory:")];
110
+ for (const e of entries.slice(0, 5)) {
111
+ out.push(` ${typeColor(e)(e.type.toUpperCase().padEnd(9))} ${e.summary}`);
112
+ if (e.context)
113
+ out.push(` ${chalk.dim("why: " + e.context)}`);
114
+ }
115
+ return out;
116
+ }
117
+ /** Pen-finding deep dive: attack, response, sandbox evidence, fix. */
118
+ function renderPenInspect(repo, f) {
119
+ const paint = severityPaint(f.severity);
120
+ const lines = [];
121
+ lines.push(`${chalk.bold("Finding")}: ${paint(f.severity.toUpperCase())} ${chalk.bold(f.type)} · ${chalk.bold(f.confidence.toUpperCase())} · ${chalk.dim(f.id)}`);
122
+ const where = f.file
123
+ ? `${rel(repo, f.file)}${f.line ? ":" + f.line : ""}`
124
+ : f.route
125
+ ? `${f.route} [${f.method ?? ""}]`
126
+ : "no location";
127
+ lines.push(`${chalk.bold("Location")}: ${chalk.cyan(where)}`);
128
+ lines.push("");
129
+ lines.push(f.title);
130
+ lines.push("");
131
+ lines.push(f.description);
132
+ lines.push("");
133
+ if (f.attack) {
134
+ lines.push(chalk.bold("Attack fired:"), ` ${chalk.cyan(`${f.attack.method} ${f.attack.path}`)}`, f.attack.payload !== undefined ? ` payload: ${chalk.dim(JSON.stringify(f.attack.payload).slice(0, 200))}` : "");
135
+ }
136
+ if (f.response) {
137
+ lines.push(chalk.bold("Observed response:"), ` HTTP ${f.response.status ?? "—"}${f.response.snippet ? ` — ${f.response.snippet}` : ""}`);
138
+ }
139
+ if (f.outbound?.length) {
140
+ lines.push(chalk.bold("Sandbox evidence:"), ...f.outbound.map((e) => ` ${chalk.red(e)}`));
141
+ }
142
+ if (f.repro) {
143
+ lines.push("", chalk.bold("Reproduce by hand:"), ` ${chalk.dim(f.repro)}`);
144
+ }
145
+ lines.push("");
146
+ if (f.fix) {
147
+ lines.push(chalk.bold("Fix:"), ` ${f.fix}`);
148
+ }
149
+ lines.push("");
150
+ lines.push(chalk.dim(`next: ${chalk.cyan(`pitstop repro ${f.id}`)} captures this as a permanent failing-then-passing test`));
151
+ console.log(boxen(lines.join("\n"), {
152
+ title: ` PITSTOP — Inspect ${f.id} `,
153
+ titleAlignment: "center",
154
+ borderStyle: "round",
155
+ padding: 1,
156
+ borderColor: paint === chalk.red ? "red" : paint === chalk.yellow ? "yellow" : "cyan",
157
+ }));
158
+ }
159
+ export const inspect = new Command("inspect")
160
+ .description("Deep-dive on a single finding id: code location, cluster context, repro proof, and OpenPitStop's memory of the files.")
161
+ .argument("<id>", "finding id from a scan box or .pitstop/scan-latest.json (e.g. security-19c390c6)")
162
+ .option("--repo <path>", "repo to inspect (defaults to cwd)", ".")
163
+ .action((idArg, options) => {
164
+ const repo = path.resolve(options.repo);
165
+ const id = (idArg.match(/[A-Za-z0-9]+-[A-Za-z0-9]{6,}/)?.[0] ?? idArg).trim();
166
+ if (!id) {
167
+ console.log(chalk.red(`could not parse a finding id from "${idArg}"`));
168
+ return;
169
+ }
170
+ const result = latestScan(repo);
171
+ const penResult = loadPenLatest(repo);
172
+ if (!result && !penResult) {
173
+ console.log(chalk.red(`no scan found — run \`pitstop scan\` first to create .pitstop/scan-latest.json`));
174
+ return;
175
+ }
176
+ const f = result ? resolveFinding(result, id) : null;
177
+ if (!f && penResult) {
178
+ const pf = resolvePenFinding(penResult, id);
179
+ if (pf) {
180
+ renderPenInspect(repo, pf);
181
+ return;
182
+ }
183
+ }
184
+ if (!f) {
185
+ console.log(chalk.red(`finding "${id}" not found in scan-latest.json or pen-latest.json\n`) +
186
+ chalk.dim(`hint: ids look like ${chalk.cyan("security-19c390c6")}; run \`pitstop scan\` to refresh.`));
187
+ return;
188
+ }
189
+ const c = result ? clusterOf(result, id) : null;
190
+ const paint = severityPaint(f.severity);
191
+ const loc = f.file ? `${rel(repo, f.file)}${f.line ? ":" + f.line : ""}` : "no file location";
192
+ const reproCapable = ["security", "a11y", "reliability", "devex", "ledger", "perf", "graph"].includes(f.source);
193
+ const proofs = loadProofs(repo).filter((p) => p.findingId === id);
194
+ const proofLines = proofs.length > 0
195
+ ? [
196
+ chalk.bold("Permanent proof:"),
197
+ ...proofs.map((p) => ` ${chalk.green("✓")} committed repro test: ${chalk.cyan(p.file)}`),
198
+ ]
199
+ : [
200
+ `${chalk.bold("Permanent proof:")} ${chalk.yellow("none committed yet")} — run \`pitstop repro ${id}\` to capture a failing-then-passing regression test.`,
201
+ ];
202
+ const lines = [];
203
+ lines.push(`${chalk.bold("Finding")}: ${paint(f.severity.toUpperCase())} ${chalk.bold(f.type)}`);
204
+ lines.push(`${chalk.bold("Location")}: ${chalk.cyan(loc)}`);
205
+ lines.push("");
206
+ lines.push(f.description);
207
+ lines.push("");
208
+ const snip = codeSnippet(repo, f);
209
+ if (snip.length > 0) {
210
+ lines.push(chalk.bold("Code:"), ...snip, "");
211
+ }
212
+ if (c) {
213
+ const isRoot = c.rootCause.id === id;
214
+ lines.push(chalk.bold("Cluster context:"), isRoot
215
+ ? ` this is the ROOT CAUSE → ${c.symptoms.length} symptom(s) across ${c.sharedFiles.length} shared file(s)`
216
+ : ` symptom of → ${chalk.red(c.rootCause.severity.toUpperCase() + " " + c.rootCause.type)}: ${c.rootCause.description}`, ` shared: ${chalk.dim(c.sharedFiles.map((x) => rel(repo, x)).join(", "))}`, "");
217
+ }
218
+ if (f.source === "ledger" && f.data) {
219
+ const ev = f.data;
220
+ lines.push(chalk.bold("Ledger evidence:"), ` scenario: ${ev.scenario ?? "?"} · order: ${ev.orderId ?? "?"} · key: ${ev.idempotencyKey ?? "?"} · double-charged: ${ev.doubleCharged ? chalk.red("YES") : chalk.green("no")}`, ` gateway calls: ${ev.chargeCalls?.length ?? 0}`, "");
221
+ }
222
+ if (f.source === "perf" && f.data) {
223
+ const p = f.data;
224
+ lines.push(chalk.bold("Performance baseline:"), ` build: ${p.buildTimeMs != null ? p.buildTimeMs + " ms" : "—"} · bundle: ${p.bundleSizeBytes != null ? (p.bundleSizeBytes / 1024).toFixed(1) + " KB" : "—"}`, "");
225
+ }
226
+ lines.push(...proofLines, "");
227
+ const mem = memoryLines(repo, f, c);
228
+ if (mem.length > 0)
229
+ lines.push(...mem, "");
230
+ if (reproCapable) {
231
+ lines.push(chalk.dim(`next: ${chalk.cyan(`pitstop repro ${id}`)} captures this as a permanent failing-then-passing test`));
232
+ }
233
+ else {
234
+ lines.push(chalk.dim("this finding type is diagnostic-only (no repro generator)."));
235
+ }
236
+ console.log(boxen(lines.join("\n"), {
237
+ title: ` PITSTOP — Inspect ${id} `,
238
+ titleAlignment: "center",
239
+ borderStyle: "round",
240
+ padding: 1,
241
+ borderColor: paint === chalk.red ? "red" : paint === chalk.yellow ? "yellow" : "cyan",
242
+ }));
243
+ });
244
+ //# sourceMappingURL=inspect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect.js","sourceRoot":"","sources":["../../src/commands/inspect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare const install: Command;