@cybedefend/vibedefend 1.4.7 → 1.6.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 (246) hide show
  1. package/README.md +77 -2
  2. package/dist/api/gateway-request.js +49 -0
  3. package/dist/api/gateway-request.js.map +1 -0
  4. package/dist/api/projects.js +67 -0
  5. package/dist/api/projects.js.map +1 -1
  6. package/dist/api/repository-link.js +157 -0
  7. package/dist/api/repository-link.js.map +1 -0
  8. package/dist/auth/auth-store.js +107 -25
  9. package/dist/auth/auth-store.js.map +1 -1
  10. package/dist/auth/auth.js +21 -0
  11. package/dist/auth/auth.js.map +1 -1
  12. package/dist/clients/cursor.js +5 -1
  13. package/dist/clients/cursor.js.map +1 -1
  14. package/dist/clients/vscode.js +38 -29
  15. package/dist/clients/vscode.js.map +1 -1
  16. package/dist/commands/mcp/allow.js +219 -0
  17. package/dist/commands/mcp/allow.js.map +1 -0
  18. package/dist/commands/mcp/connect.js +337 -0
  19. package/dist/commands/mcp/connect.js.map +1 -0
  20. package/dist/commands/mcp/index.js +170 -0
  21. package/dist/commands/mcp/index.js.map +1 -0
  22. package/dist/commands/mcp/proxy.js +264 -0
  23. package/dist/commands/mcp/proxy.js.map +1 -0
  24. package/dist/commands/mcp/scan.js +349 -0
  25. package/dist/commands/mcp/scan.js.map +1 -0
  26. package/dist/commands/mcp/sync.js +215 -0
  27. package/dist/commands/mcp/sync.js.map +1 -0
  28. package/dist/config.js +6 -0
  29. package/dist/config.js.map +1 -1
  30. package/dist/diagnostics.js +78 -12
  31. package/dist/diagnostics.js.map +1 -1
  32. package/dist/doctor.js +19 -0
  33. package/dist/doctor.js.map +1 -1
  34. package/dist/guards-evaluator/analysis-types.js +27 -0
  35. package/dist/guards-evaluator/analysis-types.js.map +1 -0
  36. package/dist/guards-evaluator/command-analysis.js +572 -0
  37. package/dist/guards-evaluator/command-analysis.js.map +1 -0
  38. package/dist/guards-evaluator/command-view.js +586 -0
  39. package/dist/guards-evaluator/command-view.js.map +1 -0
  40. package/dist/guards-evaluator/env.js +11 -0
  41. package/dist/guards-evaluator/env.js.map +1 -0
  42. package/dist/guards-evaluator/evaluate.js +91 -41
  43. package/dist/guards-evaluator/evaluate.js.map +1 -1
  44. package/dist/guards-evaluator/index.js +2 -1
  45. package/dist/guards-evaluator/index.js.map +1 -1
  46. package/dist/guards-evaluator/inline-code.js +259 -0
  47. package/dist/guards-evaluator/inline-code.js.map +1 -0
  48. package/dist/guards-evaluator/normalize.js +716 -0
  49. package/dist/guards-evaluator/normalize.js.map +1 -0
  50. package/dist/guards-evaluator/preprocess.js +13 -5
  51. package/dist/guards-evaluator/preprocess.js.map +1 -1
  52. package/dist/guards-evaluator/redact.js +19 -0
  53. package/dist/guards-evaluator/redact.js.map +1 -1
  54. package/dist/guards-evaluator/regex.js +25 -3
  55. package/dist/guards-evaluator/regex.js.map +1 -1
  56. package/dist/guards-evaluator/safe-commands.js +155 -0
  57. package/dist/guards-evaluator/safe-commands.js.map +1 -0
  58. package/dist/guards-evaluator/triage.js +315 -0
  59. package/dist/guards-evaluator/triage.js.map +1 -0
  60. package/dist/hook-runner.js +24873 -5068
  61. package/dist/hooks/install.js +38 -0
  62. package/dist/hooks/install.js.map +1 -1
  63. package/dist/hooks/runtime/config.js +38 -0
  64. package/dist/hooks/runtime/config.js.map +1 -1
  65. package/dist/hooks/runtime/emit.js +126 -53
  66. package/dist/hooks/runtime/emit.js.map +1 -1
  67. package/dist/hooks/runtime/fetch-rules.js +27 -7
  68. package/dist/hooks/runtime/fetch-rules.js.map +1 -1
  69. package/dist/hooks/runtime/gateway-http-error.js +34 -0
  70. package/dist/hooks/runtime/gateway-http-error.js.map +1 -0
  71. package/dist/hooks/runtime/guard-rules-cache.js +139 -17
  72. package/dist/hooks/runtime/guard-rules-cache.js.map +1 -1
  73. package/dist/hooks/runtime/guard-violations-buffer.js +321 -48
  74. package/dist/hooks/runtime/guard-violations-buffer.js.map +1 -1
  75. package/dist/hooks/runtime/judge-cache.js +6 -0
  76. package/dist/hooks/runtime/judge-cache.js.map +1 -1
  77. package/dist/hooks/runtime/judge-triage.js +193 -0
  78. package/dist/hooks/runtime/judge-triage.js.map +1 -0
  79. package/dist/hooks/runtime/judge.js +7 -1
  80. package/dist/hooks/runtime/judge.js.map +1 -1
  81. package/dist/hooks/runtime/pre-compact.js +21 -6
  82. package/dist/hooks/runtime/pre-compact.js.map +1 -1
  83. package/dist/hooks/runtime/resolve.js +108 -17
  84. package/dist/hooks/runtime/resolve.js.map +1 -1
  85. package/dist/hooks/runtime/retry-policy.js +57 -0
  86. package/dist/hooks/runtime/retry-policy.js.map +1 -0
  87. package/dist/hooks/runtime/review-sessions.js +74 -0
  88. package/dist/hooks/runtime/review-sessions.js.map +1 -0
  89. package/dist/hooks/runtime/script-resolve.js +695 -0
  90. package/dist/hooks/runtime/script-resolve.js.map +1 -0
  91. package/dist/hooks/runtime/session-activation.js +226 -0
  92. package/dist/hooks/runtime/session-activation.js.map +1 -0
  93. package/dist/hooks/runtime/session-review.js +174 -46
  94. package/dist/hooks/runtime/session-review.js.map +1 -1
  95. package/dist/hooks/runtime/session-start.js +35 -4
  96. package/dist/hooks/runtime/session-start.js.map +1 -1
  97. package/dist/hooks/runtime/session-writes.js +232 -0
  98. package/dist/hooks/runtime/session-writes.js.map +1 -0
  99. package/dist/hooks/runtime/sniff.js +26 -7
  100. package/dist/hooks/runtime/sniff.js.map +1 -1
  101. package/dist/hooks/runtime/target-resolve.js +336 -0
  102. package/dist/hooks/runtime/target-resolve.js.map +1 -0
  103. package/dist/hooks/runtime/unmapped-tools.js +93 -0
  104. package/dist/hooks/runtime/unmapped-tools.js.map +1 -0
  105. package/dist/hooks/runtime/usage-block.js +4 -0
  106. package/dist/hooks/runtime/usage-block.js.map +1 -1
  107. package/dist/hooks/runtime/user-prompt-submit.js +8 -2
  108. package/dist/hooks/runtime/user-prompt-submit.js.map +1 -1
  109. package/dist/hooks/runtime/wire-text.js +41 -0
  110. package/dist/hooks/runtime/wire-text.js.map +1 -0
  111. package/dist/hooks/runtime/work-dir.js +84 -0
  112. package/dist/hooks/runtime/work-dir.js.map +1 -0
  113. package/dist/index.js +45 -12
  114. package/dist/index.js.map +1 -1
  115. package/dist/install.js +174 -11
  116. package/dist/install.js.map +1 -1
  117. package/dist/link.js +74 -48
  118. package/dist/link.js.map +1 -1
  119. package/dist/login.js +99 -14
  120. package/dist/login.js.map +1 -1
  121. package/dist/mcp/auth/agent-sign-ins.js +174 -0
  122. package/dist/mcp/auth/agent-sign-ins.js.map +1 -0
  123. package/dist/mcp/auth/callback.js +200 -0
  124. package/dist/mcp/auth/callback.js.map +1 -0
  125. package/dist/mcp/auth/connect.js +392 -0
  126. package/dist/mcp/auth/connect.js.map +1 -0
  127. package/dist/mcp/auth/discovery.js +399 -0
  128. package/dist/mcp/auth/discovery.js.map +1 -0
  129. package/dist/mcp/auth/oauth.js +326 -0
  130. package/dist/mcp/auth/oauth.js.map +1 -0
  131. package/dist/mcp/auth/probe.js +128 -0
  132. package/dist/mcp/auth/probe.js.map +1 -0
  133. package/dist/mcp/auth/secrets.js +446 -0
  134. package/dist/mcp/auth/secrets.js.map +1 -0
  135. package/dist/mcp/auth/store.js +260 -0
  136. package/dist/mcp/auth/store.js.map +1 -0
  137. package/dist/mcp/auth/tokenSource.js +55 -0
  138. package/dist/mcp/auth/tokenSource.js.map +1 -0
  139. package/dist/mcp/config/atomicWrite.js +98 -0
  140. package/dist/mcp/config/atomicWrite.js.map +1 -0
  141. package/dist/mcp/config/clients.js +171 -0
  142. package/dist/mcp/config/clients.js.map +1 -0
  143. package/dist/mcp/config/cybedefend-servers.js +48 -0
  144. package/dist/mcp/config/cybedefend-servers.js.map +1 -0
  145. package/dist/mcp/config/discover.js +114 -0
  146. package/dist/mcp/config/discover.js.map +1 -0
  147. package/dist/mcp/config/hook.js +123 -0
  148. package/dist/mcp/config/hook.js.map +1 -0
  149. package/dist/mcp/config/index.js +11 -0
  150. package/dist/mcp/config/index.js.map +1 -0
  151. package/dist/mcp/config/install.js +132 -0
  152. package/dist/mcp/config/install.js.map +1 -0
  153. package/dist/mcp/config/installed.js +37 -0
  154. package/dist/mcp/config/installed.js.map +1 -0
  155. package/dist/mcp/config/jsonEdit.js +119 -0
  156. package/dist/mcp/config/jsonEdit.js.map +1 -0
  157. package/dist/mcp/config/lock.js +102 -0
  158. package/dist/mcp/config/lock.js.map +1 -0
  159. package/dist/mcp/config/proxyBinary.js +211 -0
  160. package/dist/mcp/config/proxyBinary.js.map +1 -0
  161. package/dist/mcp/config/rewrite.js +388 -0
  162. package/dist/mcp/config/rewrite.js.map +1 -0
  163. package/dist/mcp/config/types.js +34 -0
  164. package/dist/mcp/config/types.js.map +1 -0
  165. package/dist/mcp/proxy/audit.js +83 -0
  166. package/dist/mcp/proxy/audit.js.map +1 -0
  167. package/dist/mcp/proxy/authInterceptor.js +119 -0
  168. package/dist/mcp/proxy/authInterceptor.js.map +1 -0
  169. package/dist/mcp/proxy/expand.js +93 -0
  170. package/dist/mcp/proxy/expand.js.map +1 -0
  171. package/dist/mcp/proxy/inject.js +397 -0
  172. package/dist/mcp/proxy/inject.js.map +1 -0
  173. package/dist/mcp/proxy/intercept.js +37 -0
  174. package/dist/mcp/proxy/intercept.js.map +1 -0
  175. package/dist/mcp/proxy/jsonrpc.js +153 -0
  176. package/dist/mcp/proxy/jsonrpc.js.map +1 -0
  177. package/dist/mcp/proxy/log.js +109 -0
  178. package/dist/mcp/proxy/log.js.map +1 -0
  179. package/dist/mcp/proxy/paths.js +53 -0
  180. package/dist/mcp/proxy/paths.js.map +1 -0
  181. package/dist/mcp/proxy/proxy.js +510 -0
  182. package/dist/mcp/proxy/proxy.js.map +1 -0
  183. package/dist/mcp/proxy/spec.js +203 -0
  184. package/dist/mcp/proxy/spec.js.map +1 -0
  185. package/dist/mcp/proxy/sse.js +77 -0
  186. package/dist/mcp/proxy/sse.js.map +1 -0
  187. package/dist/mcp/proxy/upstream.js +2 -0
  188. package/dist/mcp/proxy/upstream.js.map +1 -0
  189. package/dist/mcp/proxy/upstreamHttp.js +499 -0
  190. package/dist/mcp/proxy/upstreamHttp.js.map +1 -0
  191. package/dist/mcp/proxy/upstreamStdio.js +188 -0
  192. package/dist/mcp/proxy/upstreamStdio.js.map +1 -0
  193. package/dist/mcp/proxy/upstreams.js +143 -0
  194. package/dist/mcp/proxy/upstreams.js.map +1 -0
  195. package/dist/mcp/proxy/verifyInterceptor.js +559 -0
  196. package/dist/mcp/proxy/verifyInterceptor.js.map +1 -0
  197. package/dist/mcp/proxy/windowsCommand.js +99 -0
  198. package/dist/mcp/proxy/windowsCommand.js.map +1 -0
  199. package/dist/mcp/scan/args.js +228 -0
  200. package/dist/mcp/scan/args.js.map +1 -0
  201. package/dist/mcp/scan/results.js +253 -0
  202. package/dist/mcp/scan/results.js.map +1 -0
  203. package/dist/mcp/scan/types.js +40 -0
  204. package/dist/mcp/scan/types.js.map +1 -0
  205. package/dist/mcp/verify/api.js +475 -0
  206. package/dist/mcp/verify/api.js.map +1 -0
  207. package/dist/mcp/verify/backend.js +143 -0
  208. package/dist/mcp/verify/backend.js.map +1 -0
  209. package/dist/mcp/verify/cache.js +182 -0
  210. package/dist/mcp/verify/cache.js.map +1 -0
  211. package/dist/mcp/verify/contract-errors.js +198 -0
  212. package/dist/mcp/verify/contract-errors.js.map +1 -0
  213. package/dist/mcp/verify/digest.js +91 -0
  214. package/dist/mcp/verify/digest.js.map +1 -0
  215. package/dist/mcp/verify/factory.js +56 -0
  216. package/dist/mcp/verify/factory.js.map +1 -0
  217. package/dist/mcp/verify/identity.js +173 -0
  218. package/dist/mcp/verify/identity.js.map +1 -0
  219. package/dist/mcp/verify/policy-store.js +63 -0
  220. package/dist/mcp/verify/policy-store.js.map +1 -0
  221. package/dist/mcp/verify/policy.js +158 -0
  222. package/dist/mcp/verify/policy.js.map +1 -0
  223. package/dist/mcp/verify/pool.js +27 -0
  224. package/dist/mcp/verify/pool.js.map +1 -0
  225. package/dist/mcp/verify/token-refresh.js +44 -0
  226. package/dist/mcp/verify/token-refresh.js.map +1 -0
  227. package/dist/mcp/verify/token.js +67 -0
  228. package/dist/mcp/verify/token.js.map +1 -0
  229. package/dist/mcp/verify/verifier.js +1009 -0
  230. package/dist/mcp/verify/verifier.js.map +1 -0
  231. package/dist/org-gate.js +1 -1
  232. package/dist/org-gate.js.map +1 -1
  233. package/dist/org.js +146 -0
  234. package/dist/org.js.map +1 -0
  235. package/dist/project-create.js +129 -0
  236. package/dist/project-create.js.map +1 -0
  237. package/dist/prompts.js +21 -0
  238. package/dist/prompts.js.map +1 -1
  239. package/dist/re2.wasm +0 -0
  240. package/dist/status.js +61 -0
  241. package/dist/status.js.map +1 -1
  242. package/dist/uninstall.js +49 -4
  243. package/dist/uninstall.js.map +1 -1
  244. package/dist/utils.js +62 -6
  245. package/dist/utils.js.map +1 -1
  246. package/package.json +10 -3
@@ -0,0 +1,193 @@
1
+ /**
2
+ * Level 2 — local judge-routing gate (BACK-74 hardening).
3
+ *
4
+ * A PURE decision function that the PreToolUse hook integrator calls to decide
5
+ * WHETHER and HOW to consult the cloud LLM judge. It does NOT call the judge,
6
+ * touch the network, read the disk, or read the clock — it only maps a bundle
7
+ * of already-computed local signals to a route + an advisory model tier.
8
+ *
9
+ * It replaces the ad-hoc gating currently spread across guard-check.ts:
10
+ * - `runJudgeStep` decides confirm (overturn a regex `deny`), gated by
11
+ * a matched `llmJudgeEnabled` deny rule and the org hint.
12
+ * - `runCatchJudgeStep` decides catch (recover a regex `allow`), gated by a
13
+ * deterministic near-miss pre-filter, the org hint, and
14
+ * a hard `severity !== 'critical'` exclusion.
15
+ *
16
+ * The new coverage this gate adds (per the hardening SPEC): the catch phase no
17
+ * longer fires only on a near-miss. A triage verdict of `suspect`/`dangerous`
18
+ * or an incompletely-parsed command (`NormalizeResult.incomplete`) is enough to
19
+ * escalate an `allow`/`warn` to the judge — that is where the measured false
20
+ * negatives (`/bin/rm -rf ~`, `find ~ -delete`, `echo <b64> | base64 -d | sh`,
21
+ * a written-then-executed script) get a second look. Critical rules stay OUT of
22
+ * catch by default (`catchIncludesCritical` opts them in) to preserve today's
23
+ * product default, while still surfacing a slug so the suppression is countable.
24
+ *
25
+ * Design rules (shared with the rest of the Level 0–2 work):
26
+ * - PURE: no I/O, no network, no clock.
27
+ * - NEVER THROWS: every input is guarded; a malformed field degrades toward
28
+ * "look closer" / `small`, never toward a crash.
29
+ * - DETERMINISTIC: the same input always yields the same decision and the
30
+ * same ordered `reasons`.
31
+ * - ADVISORY TIER: `tier` only hints which server model to use; the default
32
+ * stays `small` so cost/latency are unchanged for the common case.
33
+ */
34
+ /**
35
+ * Action-summary length (characters) above which we request the `large` model.
36
+ * A long action is harder to adjudicate on a glance and more likely to hide a
37
+ * dangerous tail past a benign head. Strict `>`: exactly the threshold stays
38
+ * `small`. Exported so tests pin the boundary against the constant, not a
39
+ * magic number.
40
+ */
41
+ export const LARGE_ACTION_LENGTH = 400;
42
+ /**
43
+ * Triage reason slugs that always justify the `large` model when the judge is
44
+ * consulted. These are the "high-stakes" families from the hardening SPEC:
45
+ * - indirect-executable — the executable came via `$X` / `$(which rm)`.
46
+ * - encoded-pipe-to-shell — `echo <b64> | base64 -d | sh` and kin.
47
+ * - read-then-exfil — a secret read chained into an outbound send.
48
+ * Kept as its own set so adding a family is a one-line change with a test.
49
+ */
50
+ export const HIGH_STAKES_TRIAGE_SLUGS = new Set([
51
+ 'indirect-executable',
52
+ 'encoded-pipe-to-shell',
53
+ 'read-then-exfil',
54
+ ]);
55
+ /**
56
+ * Compute the advisory model tier for a route that WILL consult the judge, and
57
+ * append the tier reason slugs to `reasons` (in a stable order). Never called
58
+ * for a `none` route, so `none` decisions never carry tier reasons and always
59
+ * report `small`.
60
+ *
61
+ * `large` when ANY of:
62
+ * - the command could not be fully parsed (blindness → look harder),
63
+ * - the aggregate severity is critical or high,
64
+ * - the action summary is longer than `LARGE_ACTION_LENGTH`,
65
+ * - a high-stakes triage slug is present.
66
+ * Otherwise `small` (the default that keeps the common case cheap).
67
+ */
68
+ function computeTier(input, reasons) {
69
+ let large = false;
70
+ if (input.normalizeIncomplete) {
71
+ large = true;
72
+ reasons.push('tier-normalize-incomplete');
73
+ }
74
+ if (input.maxSeverity === 'critical' || input.maxSeverity === 'high') {
75
+ large = true;
76
+ reasons.push(`tier-severity-${input.maxSeverity}`);
77
+ }
78
+ // Guard a non-finite length defensively (contract says number; never throw).
79
+ const len = typeof input.actionLength === 'number' && Number.isFinite(input.actionLength)
80
+ ? input.actionLength
81
+ : 0;
82
+ if (len > LARGE_ACTION_LENGTH) {
83
+ large = true;
84
+ reasons.push('tier-action-length');
85
+ }
86
+ const triageReasons = Array.isArray(input.triageReasons)
87
+ ? input.triageReasons
88
+ : [];
89
+ for (const slug of triageReasons) {
90
+ if (HIGH_STAKES_TRIAGE_SLUGS.has(slug)) {
91
+ large = true;
92
+ reasons.push(`tier-high-stakes:${slug}`);
93
+ }
94
+ }
95
+ return large ? 'large' : 'small';
96
+ }
97
+ /**
98
+ * Decide whether and how to consult the cloud judge for one action.
99
+ *
100
+ * Branches, in evaluation order (each surfaced with a stable reason slug):
101
+ *
102
+ * 1. ORG HINT OFF (`org-judge-disabled`) → `none`.
103
+ * Highest precedence, every verdict and every signal. The org opted out of
104
+ * the judge entirely; nothing below can re-enable it. Mirrors the
105
+ * `llmJudgeHint?.enabled === false` early return in BOTH guard-check steps.
106
+ *
107
+ * 2. VERDICT `deny` → the confirm (overturn-a-false-positive) path:
108
+ * a. `hasJudgeEligibleDenyRule` → `confirm` (`deny-judge-eligible`).
109
+ * Unchanged from today. Note it is NOT gated by severity (BACK-150
110
+ * removed the critical gate for confirm — severity decides what the
111
+ * CALLER does with an overturn, not whether the judge is consulted) nor
112
+ * by the triage class: a regex `deny` that triage would call benign is a
113
+ * disagreement for the judge to resolve, i.e. a prime false-positive to
114
+ * overturn, so the triage-safe skip (branch 4) is deliberately NOT
115
+ * applied here.
116
+ * b. otherwise → `none` (`deny-no-eligible-rule`). The judge is only ever
117
+ * shown deny rules that opted into it (`runJudgeStep`:
118
+ * `if (llmRules.length === 0) return undefined`); with no such rule there
119
+ * is nothing it could overturn, so we never pay for the call.
120
+ *
121
+ * 3. VERDICT `allow`/`warn` → the catch (recover-a-false-negative) path.
122
+ * Collect escalation signals: triage `dangerous`/`suspect`, a near-miss,
123
+ * or an incomplete parse. This is the NEW coverage — today catch fires only
124
+ * on a near-miss; a `suspect`/`dangerous` triage or a parse the normalizer
125
+ * could not finish now suffices.
126
+ *
127
+ * 4. NO ESCALATION SIGNAL (`triage-safe`) → `none`.
128
+ * Reached only when the triage class is `safe` (the sole remaining class)
129
+ * AND there is no near-miss and no incomplete parse. `safe` means
130
+ * "known-benign; skip the network entirely" — we trust it here. Crucially,
131
+ * a near-miss or an incomplete parse OVERRIDES a `safe` triage (they make
132
+ * `signals` non-empty), because those are exactly the false negatives a
133
+ * naive-verdict could hide and the SPEC's whole reason for this gate; a
134
+ * `safe` verdict that nonetheless almost matched a deny rule, or came from a
135
+ * command we could not fully read, is not trustworthy enough to skip.
136
+ *
137
+ * 5. CRITICAL SUPPRESSION (catch only). When the catch would fire on a
138
+ * critical-severity action (`maxSeverity === 'critical'` — the only
139
+ * severity signal this pure function has, standing in for today's
140
+ * per-candidate `severity !== 'critical'` exclusion):
141
+ * - flag off → `none`, but still surface `catch-critical-suppressed` so
142
+ * the integrator can log/measure what the current product default drops.
143
+ * - flag on → `catch` (`catch-critical-included`).
144
+ * The escalation signals are already in `reasons` either way, so a
145
+ * suppressed decision records what WOULD have fired.
146
+ *
147
+ * 6. Otherwise → `catch`.
148
+ */
149
+ export function decideJudgeRoute(input) {
150
+ const reasons = [];
151
+ // 1. Org hint off → never judge (overrides every verdict and signal).
152
+ if (!input.orgJudgeEnabled) {
153
+ reasons.push('org-judge-disabled');
154
+ return { route: 'none', tier: 'small', reasons };
155
+ }
156
+ // 2. Deny → confirm (overturn a false positive). Triage/severity do not gate
157
+ // this; only a judge-eligible deny rule does.
158
+ if (input.verdict === 'deny') {
159
+ if (input.hasJudgeEligibleDenyRule) {
160
+ reasons.push('deny-judge-eligible');
161
+ return { route: 'confirm', tier: computeTier(input, reasons), reasons };
162
+ }
163
+ reasons.push('deny-no-eligible-rule');
164
+ return { route: 'none', tier: 'small', reasons };
165
+ }
166
+ // 3. Allow / warn → catch. Collect escalation signals.
167
+ const signals = [];
168
+ if (input.triageClass === 'dangerous')
169
+ signals.push('triage-dangerous');
170
+ if (input.triageClass === 'suspect')
171
+ signals.push('triage-suspect');
172
+ if (input.hasCatchNearMiss)
173
+ signals.push('catch-near-miss');
174
+ if (input.normalizeIncomplete)
175
+ signals.push('normalize-incomplete');
176
+ // 4. No escalation signal → trust a `safe` triage and skip the network.
177
+ if (signals.length === 0) {
178
+ reasons.push('triage-safe');
179
+ return { route: 'none', tier: 'small', reasons };
180
+ }
181
+ reasons.push(...signals);
182
+ // 5. Critical suppression (catch only).
183
+ if (input.maxSeverity === 'critical') {
184
+ if (!input.catchIncludesCritical) {
185
+ reasons.push('catch-critical-suppressed');
186
+ return { route: 'none', tier: 'small', reasons };
187
+ }
188
+ reasons.push('catch-critical-included');
189
+ }
190
+ // 6. Catch it.
191
+ return { route: 'catch', tier: computeTier(input, reasons), reasons };
192
+ }
193
+ //# sourceMappingURL=judge-triage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"judge-triage.js","sourceRoot":"","sources":["../../../src/hooks/runtime/judge-triage.ts"],"names":[],"mappings":"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"}
@@ -5,7 +5,9 @@ export function isJudgeBlocked(res) {
5
5
  const DEFAULT_TIMEOUT_MS = 1_500;
6
6
  export async function callJudge(input, opts = {}) {
7
7
  const f = opts.fetchImpl ?? globalThis.fetch;
8
- const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
8
+ // Precedence: an explicit opts.timeoutMs (tests) wins; else the caller's
9
+ // per-call `budgetMs` (Level 3 deep confirm uses a larger one); else default.
10
+ const timeoutMs = opts.timeoutMs ?? input.budgetMs ?? DEFAULT_TIMEOUT_MS;
9
11
  const url = `${input.apiBaseResolved}/project/${encodeURIComponent(input.projectId)}/action-guards/judge`;
10
12
  try {
11
13
  const res = await f(url, {
@@ -22,6 +24,8 @@ export async function callJudge(input, opts = {}) {
22
24
  action_summary: input.actionSummary,
23
25
  action_hash: input.actionHash,
24
26
  rules: input.rules,
27
+ ...(input.tier ? { tier: input.tier } : {}),
28
+ ...(input.scripts && input.scripts.length > 0 ? { scripts: input.scripts } : {}),
25
29
  }),
26
30
  signal: AbortSignal.timeout(timeoutMs),
27
31
  });
@@ -43,6 +47,8 @@ export async function callJudge(input, opts = {}) {
43
47
  ? data['quota_remaining']
44
48
  : -1,
45
49
  quotaExceeded: Boolean(data['quota_exceeded']),
50
+ ...(typeof data['rule_id'] === 'string' && data['rule_id'] ? { ruleId: data['rule_id'] } : {}),
51
+ ...(data['fallback'] === true ? { fallback: true } : {}),
46
52
  ...(usageWarning ? { usageWarning } : {}),
47
53
  };
48
54
  }
@@ -1 +1 @@
1
- {"version":3,"file":"judge.js","sourceRoot":"","sources":["../../../src/hooks/runtime/judge.ts"],"names":[],"mappings":"AAYA,OAAO,EACL,gBAAgB,EAChB,mBAAmB,GAGpB,MAAM,kBAAkB,CAAC;AAiD1B,MAAM,UAAU,cAAc,CAC5B,GAAsC;IAEtC,OAAO,GAAG,KAAK,IAAI,IAAI,SAAS,IAAI,GAAG,CAAC;AAC1C,CAAC;AAED,MAAM,kBAAkB,GAAG,KAAK,CAAC;AAEjC,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,KAAiB,EACjB,OAAoE,EAAE;IAEtE,MAAM,CAAC,GAAG,IAAI,CAAC,SAAS,IAAI,UAAU,CAAC,KAAK,CAAC;IAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,kBAAkB,CAAC;IACvD,MAAM,GAAG,GAAG,GAAG,KAAK,CAAC,eAAe,YAAY,kBAAkB,CAAC,KAAK,CAAC,SAAS,CAAC,sBAAsB,CAAC;IAE1G,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,GAAG,EAAE;YACvB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,KAAK,CAAC,KAAK,EAAE;gBACtC,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,UAAU,EAAE,KAAK,CAAC,SAAS;gBAC3B,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,SAAS;gBAC/B,cAAc,EAAE,KAAK,CAAC,aAAa;gBACnC,WAAW,EAAE,KAAK,CAAC,UAAU;gBAC7B,KAAK,EAAE,KAAK,CAAC,KAAK;aACnB,CAAC;YACF,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC;SACvC,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC,GAAG,CAAC,CAAC;YAC/C,OAAO,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACtC,CAAC;QACD,MAAM,YAAY,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;QAE3C,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA4B,CAAC;QAC3D,MAAM,IAAI,GAAI,IAAI,CAAC,IAAgC,IAAI,IAAI,CAAC;QAC5D,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;QAClC,IAAI,QAAQ,KAAK,OAAO,IAAI,QAAQ,KAAK,OAAO;YAAE,OAAO,IAAI,CAAC;QAE9D,OAAO;YACL,QAAQ;YACR,MAAM,EACJ,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAE,IAAI,CAAC,QAAQ,CAAY,CAAC,CAAC,CAAC,EAAE;YACtE,KAAK,EAAE,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAE,IAAI,CAAC,OAAO,CAAY,CAAC,CAAC,CAAC,EAAE;YACzE,cAAc,EACZ,OAAO,IAAI,CAAC,iBAAiB,CAAC,KAAK,QAAQ;gBACzC,CAAC,CAAE,IAAI,CAAC,iBAAiB,CAAY;gBACrC,CAAC,CAAC,CAAC,CAAC;YACR,aAAa,EAAE,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YAC9C,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC1C,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"judge.js","sourceRoot":"","sources":["../../../src/hooks/runtime/judge.ts"],"names":[],"mappings":"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"}
@@ -3,25 +3,38 @@
3
3
  * before Claude Code summarises the conversation context. Catches long
4
4
  * sessions where the user keeps replying and Stop never fires.
5
5
  *
6
- * Only Claude Code, Cursor, and VS Code Copilot expose this event;
7
- * Windsurf and Codex don't have an equivalent (those clients' adapters
8
- * simply don't wire this subcommand).
6
+ * Claude Code, Cursor and VS Code Copilot wire this subcommand. Cursor and
7
+ * VS Code read no model-facing field on PreCompact, so it stops early there
8
+ * (see `hasModelChannel` in emit.ts).
9
9
  */
10
10
  import { sniff } from './sniff.js';
11
- import { emit } from './emit.js';
11
+ import { emit, hasModelChannel } from './emit.js';
12
12
  import { loadRuntimeConfig, readStdinJson } from './config.js';
13
13
  import { DIRECT_PROPOSE_DIRECTIVES, resolveProposalMode, } from './proposal-mode.js';
14
+ import { resolveProjectIdWithApi } from './resolve.js';
15
+ import { isSessionInactive, sessionFolderOf, } from './session-activation.js';
14
16
  export async function preCompactHook(deps = {}) {
15
17
  const readStdin = deps.readStdin ?? readStdinJson;
16
18
  const loadConfig = deps.loadConfig ?? loadRuntimeConfig;
17
19
  const emitFn = deps.emitFn ?? emit;
18
20
  const stdin = await readStdin();
19
21
  const event = sniff(stdin);
22
+ // Cursor and VS Code read no model-facing field on PreCompact (see emit.ts):
23
+ // stop before the project lookup instead of writing text nobody reads.
24
+ if (!hasModelChannel(event.client, 'PreCompact'))
25
+ return;
20
26
  const config = loadConfig();
21
27
  if (!config)
22
28
  return;
23
29
  if (!config.hooks.enableSessionReview)
24
30
  return;
31
+ // Only in a folder that maps to a CybeDefend project (machine-wide hooks).
32
+ const folder = sessionFolderOf(stdin, event.client);
33
+ if (isSessionInactive(stdin, { store: deps.sessionStore, cwd: folder }))
34
+ return;
35
+ const { projectId } = await (deps.resolveProject ?? resolveProjectIdWithApi)(folder);
36
+ if (!projectId)
37
+ return;
25
38
  if (process.env.CYBEDEFEND_DRY_RUN === '1') {
26
39
  emitFn(`## 🛡️ CybeDefend PreCompact (dry-run, client=${event.client})\n`, event.client);
27
40
  return;
@@ -29,8 +42,10 @@ export async function preCompactHook(deps = {}) {
29
42
  const proposalMode = resolveProposalMode(config);
30
43
  const proposeStep = proposalMode === 'ask'
31
44
  ? [
32
- '3. For uncovered concerns, ask the user via AskUserQuestion whether to propose;',
33
- ' on "yes", call `cybe_rules_report_missing` with confirmed_by_user: true.',
45
+ '3. Only if one durable, reusable rule is missing,',
46
+ ' ask the user via AskUserQuestion whether to propose it; on "yes", call',
47
+ ' `cybe_rules_report_missing` with confirmed_by_user: true. If none is',
48
+ ' missing, do not ask.',
34
49
  ]
35
50
  : [`3. ${DIRECT_PROPOSE_DIRECTIVES[proposalMode]}`];
36
51
  const body = [
@@ -1 +1 @@
1
- {"version":3,"file":"pre-compact.js","sourceRoot":"","sources":["../../../src/hooks/runtime/pre-compact.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EACL,yBAAyB,EACzB,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAQ5B,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAuB,EAAE;IAC5D,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,aAAa,CAAC;IAClD,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,iBAAiB,CAAC;IACxD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC;IAEnC,MAAM,KAAK,GAAG,MAAM,SAAS,EAAE,CAAC;IAChC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IAE3B,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,IAAI,CAAC,MAAM;QAAE,OAAO;IACpB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB;QAAE,OAAO;IAE9C,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,GAAG,EAAE,CAAC;QAC3C,MAAM,CACJ,iDAAiD,KAAK,CAAC,MAAM,KAAK,EAClE,KAAK,CAAC,MAAM,CACb,CAAC;QACF,OAAO;IACT,CAAC;IAED,MAAM,YAAY,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;IACjD,MAAM,WAAW,GACf,YAAY,KAAK,KAAK;QACpB,CAAC,CAAC;YACE,iFAAiF;YACjF,6EAA6E;SAC9E;QACH,CAAC,CAAC,CAAC,MAAM,yBAAyB,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;IACxD,MAAM,IAAI,GAAG;QACX,2CAA2C;QAC3C,EAAE;QACF,uEAAuE;QACvE,8EAA8E;QAC9E,+DAA+D;QAC/D,2DAA2D;QAC3D,GAAG,WAAW;QACd,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACb,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;AAC7B,CAAC"}
1
+ {"version":3,"file":"pre-compact.js","sourceRoot":"","sources":["../../../src/hooks/runtime/pre-compact.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EACL,yBAAyB,EACzB,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,uBAAuB,EAA0B,MAAM,cAAc,CAAC;AAC/E,OAAO,EACL,iBAAiB,EACjB,eAAe,GAEhB,MAAM,yBAAyB,CAAC;AAYjC,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAuB,EAAE;IAC5D,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,aAAa,CAAC;IAClD,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,iBAAiB,CAAC;IACxD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC;IAEnC,MAAM,KAAK,GAAG,MAAM,SAAS,EAAE,CAAC;IAChC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IAC3B,6EAA6E;IAC7E,uEAAuE;IACvE,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,MAAM,EAAE,YAAY,CAAC;QAAE,OAAO;IAEzD,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,IAAI,CAAC,MAAM;QAAE,OAAO;IACpB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB;QAAE,OAAO;IAE9C,2EAA2E;IAC3E,MAAM,MAAM,GAAG,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACpD,IAAI,iBAAiB,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;QAAE,OAAO;IAChF,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,IAAI,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC;IACrF,IAAI,CAAC,SAAS;QAAE,OAAO;IAEvB,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,GAAG,EAAE,CAAC;QAC3C,MAAM,CACJ,iDAAiD,KAAK,CAAC,MAAM,KAAK,EAClE,KAAK,CAAC,MAAM,CACb,CAAC;QACF,OAAO;IACT,CAAC;IAED,MAAM,YAAY,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;IACjD,MAAM,WAAW,GACf,YAAY,KAAK,KAAK;QACpB,CAAC,CAAC;YACE,mDAAmD;YACnD,2EAA2E;YAC3E,yEAAyE;YACzE,yBAAyB;SAC1B;QACH,CAAC,CAAC,CAAC,MAAM,yBAAyB,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;IACxD,MAAM,IAAI,GAAG;QACX,2CAA2C;QAC3C,EAAE;QACF,uEAAuE;QACvE,8EAA8E;QAC9E,+DAA+D;QAC/D,2DAA2D;QAC3D,GAAG,WAAW;QACd,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACb,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;AAC7B,CAAC"}
@@ -88,6 +88,11 @@ export function resolveProjectId(cwd = process.cwd(), deps = {}) {
88
88
  *
89
89
  * Windows: env var or login bundle only. Future improvement: `cmdkey /list`
90
90
  * → parse, or via a small PowerShell snippet.
91
+ *
92
+ * A keychain token whose recorded expiry is past is skipped (BACK-240 L2):
93
+ * handing it out only bought a 401 from the gateway on every hook call. A
94
+ * token that records no usable expiry (raw blob, field absent or 0) is
95
+ * still returned, as before (BACK-124).
91
96
  */
92
97
  export function resolveToken(mcpName, opts = {}) {
93
98
  const envToken = process.env.CYBEDEFEND_TOKEN;
@@ -100,8 +105,9 @@ export function resolveToken(mcpName, opts = {}) {
100
105
  const platform = opts.platform ?? process.platform;
101
106
  const readKeychain = opts.readKeychain ?? readMacOSKeychain;
102
107
  if (platform === 'darwin') {
103
- return (resolveTokenMacOS(mcpName, opts.mcpUrl, readKeychain) ??
104
- resolveTokenCodexMacOS(mcpName, opts.mcpUrl, readKeychain));
108
+ const now = (opts.now ?? Date.now)();
109
+ return (resolveTokenMacOS(mcpName, opts.mcpUrl, readKeychain, now) ??
110
+ resolveTokenCodexMacOS(mcpName, opts.mcpUrl, readKeychain, now));
105
111
  }
106
112
  if (platform === 'linux')
107
113
  return resolveTokenLinux(mcpName);
@@ -118,6 +124,19 @@ export function codexCredentialAccount(mcpName, mcpUrl) {
118
124
  .digest('hex');
119
125
  return `${mcpName}|${digest.slice(0, 16)}`;
120
126
  }
127
+ /**
128
+ * Whether a keychain credential's recorded expiry is past. Claude Code and
129
+ * Codex record it in epoch milliseconds; a value below 1e11 can only be
130
+ * seconds (as milliseconds it would be 1973) and is read as such. Anything
131
+ * that is not a positive number records no expiry: never expired.
132
+ */
133
+ function isExpired(expiresAt, now) {
134
+ if (typeof expiresAt !== 'number' || !Number.isFinite(expiresAt) || expiresAt <= 0) {
135
+ return false;
136
+ }
137
+ const expiresAtMs = expiresAt < 1e11 ? expiresAt * 1000 : expiresAt;
138
+ return now >= expiresAtMs;
139
+ }
121
140
  function readMacOSKeychain(service, account) {
122
141
  try {
123
142
  const blob = execFileSync('security', [
@@ -137,7 +156,7 @@ function readMacOSKeychain(service, account) {
137
156
  return null;
138
157
  }
139
158
  }
140
- function resolveTokenMacOS(mcpName, mcpUrl, readKeychain) {
159
+ function resolveTokenMacOS(mcpName, mcpUrl, readKeychain, now) {
141
160
  const blob = readKeychain('Claude Code-credentials');
142
161
  if (!blob)
143
162
  return null;
@@ -152,6 +171,10 @@ function resolveTokenMacOS(mcpName, mcpUrl, readKeychain) {
152
171
  if (mcpUrl && typeof entry.serverUrl === 'string' && entry.serverUrl !== mcpUrl) {
153
172
  continue;
154
173
  }
174
+ // An expired token is no token: sent, it only earns a 401.
175
+ if (isExpired(entry.expiresAt, now)) {
176
+ continue;
177
+ }
155
178
  return entry.accessToken;
156
179
  }
157
180
  }
@@ -173,7 +196,7 @@ function resolveTokenMacOS(mcpName, mcpUrl, readKeychain) {
173
196
  * (`-s` without `-a`) returns whichever entry comes first, i.e. possibly
174
197
  * another server's token.
175
198
  */
176
- function resolveTokenCodexMacOS(mcpName, mcpUrl, readKeychain) {
199
+ function resolveTokenCodexMacOS(mcpName, mcpUrl, readKeychain, now) {
177
200
  const accounts = mcpUrl
178
201
  ? [codexCredentialAccount(mcpName, mcpUrl), mcpName]
179
202
  : [mcpName];
@@ -181,15 +204,17 @@ function resolveTokenCodexMacOS(mcpName, mcpUrl, readKeychain) {
181
204
  const blob = readKeychain('Codex MCP Credentials', account);
182
205
  if (!blob)
183
206
  continue;
184
- const token = parseCodexCredential(blob);
207
+ const token = parseCodexCredential(blob, now);
185
208
  if (token)
186
209
  return token;
187
210
  }
188
211
  return null;
189
212
  }
190
- function parseCodexCredential(blob) {
213
+ function parseCodexCredential(blob, now) {
191
214
  try {
192
215
  const data = JSON.parse(blob);
216
+ if (isExpired(data.expires_at ?? data.expiresAt, now))
217
+ return null;
193
218
  return (data.token_response?.access_token ??
194
219
  data.access_token ??
195
220
  data.accessToken ??
@@ -235,6 +260,29 @@ function resolveTokenLinux(mcpName) {
235
260
  * Never throws — all errors are converted to null so hook callers remain
236
261
  * fail-open.
237
262
  */
263
+ /**
264
+ * Is this JWT past its `exp`?
265
+ *
266
+ * Unverified on purpose: we are not authenticating anything here, we are
267
+ * deciding whether it is worth SENDING. A token whose own claim says it died
268
+ * cannot be made alive by checking its signature.
269
+ *
270
+ * Anything unparseable answers `false` — an opaque token is not evidence of
271
+ * expiry, and refusing it would break every non-JWT credential.
272
+ */
273
+ function isExpiredJwt(token) {
274
+ const payload = token.split('.')[1];
275
+ if (!payload)
276
+ return false;
277
+ try {
278
+ const json = Buffer.from(payload, 'base64url').toString('utf8');
279
+ const exp = JSON.parse(json).exp;
280
+ return typeof exp === 'number' && exp * 1000 <= Date.now();
281
+ }
282
+ catch {
283
+ return false;
284
+ }
285
+ }
238
286
  export async function resolveTokenWithRefresh(mcpName, deps = {},
239
287
  /** The region's MCP URL, handed to the legacy lookup (Codex account). */
240
288
  opts = {}) {
@@ -268,9 +316,35 @@ opts = {}) {
268
316
  // so a stale-but-unexpired legacy token can still be used.
269
317
  }
270
318
  // 3. Fall back to the synchronous legacy keychain lookup (pre-PKCE tokens).
271
- return resolveTokenFn(mcpName, opts);
319
+ //
320
+ // ⚠️ An EXPIRED legacy token is treated as absent. Returning it produced the
321
+ // worst possible outcome: the caller sent it, got a bare `401 Token
322
+ // expired` from somewhere deep in a request chain, retried once with the
323
+ // same dead token, and reported a mysterious auth failure. The legacy slot
324
+ // has no refresh token, so nothing downstream could ever fix it — the only
325
+ // remedy is a fresh `vibedefend login`, and the user has to be told that
326
+ // rather than left to read a 401.
327
+ const legacy = resolveTokenFn(mcpName, opts);
328
+ if (legacy && isExpiredJwt(legacy)) {
329
+ process.stderr.write(`[vibedefend] the stored credential for "${mcpName}" has expired and cannot be ` +
330
+ 'refreshed (no refresh token in the legacy store). Run `vibedefend login`.\n');
331
+ return null;
332
+ }
333
+ return legacy;
272
334
  }
273
335
  const RESOLVE_API_TIMEOUT_MS = 4_000;
336
+ /**
337
+ * BACK-174 — effective activation mode: `CYBEDEFEND_ACTIVATION` (per shell)
338
+ * wins over the persisted `hooks.activation`; anything else is `auto`, which
339
+ * is also what a config written before this shipped means.
340
+ */
341
+ export function resolveActivationMode(config) {
342
+ const env = process.env.CYBEDEFEND_ACTIVATION;
343
+ if (env === 'opt-in' || env === 'auto')
344
+ return env;
345
+ const hooks = config?.hooks;
346
+ return hooks?.activation === 'opt-in' ? 'opt-in' : 'auto';
347
+ }
274
348
  /**
275
349
  * Async superset of {@link resolveProjectId} that adds a gateway
276
350
  * auto-discovery step for repos that haven't been `link`-ed yet.
@@ -297,15 +371,33 @@ export async function resolveProjectIdWithApi(cwd = process.cwd(), deps = {}) {
297
371
  // 1. env var / config.json projectId always wins — no git, no network.
298
372
  if (base.projectId)
299
373
  return base;
374
+ let repository;
375
+ const none = (inactiveReason) => ({
376
+ ...base,
377
+ inactiveReason,
378
+ ...(repository ? { repository } : {}),
379
+ });
380
+ // BACK-174 — opt-in mode: the explicit sources above are the ONLY sources.
381
+ // No origin lookup, and no repo-link cache either — the cache is a product
382
+ // of auto-discovery, so honouring it here would resurrect a repo the user
383
+ // stopped linking. Every hook goes through this function, so this one gate
384
+ // is what makes an un-linked repo a no-op end to end.
385
+ const config = (deps.loadConfig ?? loadRuntimeConfig)();
386
+ if (resolveActivationMode(config) === 'opt-in') {
387
+ return none('opt-in-not-linked');
388
+ }
300
389
  try {
301
390
  // 2. Need a parseable origin to build the cache key + query.
302
391
  const getOrigin = deps.getOrigin ?? getOriginRemote;
303
392
  const originUrl = getOrigin(cwd);
304
393
  if (!originUrl)
305
- return base;
394
+ return none('no-git-origin');
306
395
  const remote = parseRemoteUrl(originUrl);
307
- if (!remote || remote.provider === null)
308
- return base;
396
+ if (!remote)
397
+ return none('unsupported-remote');
398
+ repository = `${remote.host}/${remote.slug}`;
399
+ if (remote.provider === null)
400
+ return none('unsupported-remote');
309
401
  const key = `${remote.provider}:${remote.host}:${remote.slug}`;
310
402
  // 3. Cache — fresh positive short-circuits, fresh negative suppresses.
311
403
  const cached = getCachedRepoLink(key, deps.cacheDeps);
@@ -313,23 +405,22 @@ export async function resolveProjectIdWithApi(cwd = process.cwd(), deps = {}) {
313
405
  return { projectId: cached.projectId, apiBase: base.apiBase };
314
406
  }
315
407
  if (cached.kind === 'negative') {
316
- return base;
408
+ return none('no-linked-project');
317
409
  }
318
410
  // 4. Need config (apiBase + mcpName) and a token before we call out.
319
- const config = (deps.loadConfig ?? loadRuntimeConfig)();
320
411
  if (!config)
321
- return base;
412
+ return none('lookup-failed');
322
413
  const apiBase = base.apiBase ?? config.region.apiBase;
323
414
  const resolveTokenFn = deps.resolveTokenFn ?? resolveTokenWithRefresh;
324
415
  const token = await resolveTokenFn(config.region.mcpName);
325
416
  if (!token)
326
- return base;
417
+ return none('not-signed-in');
327
418
  // 5. Gateway lookup (bounded).
328
419
  const resolveByRepo = deps.resolveByRepo ?? resolveProjectByRepository;
329
420
  const matches = await resolveByRepo(apiBase, token, { provider: remote.provider, slug: remote.slug, host: remote.host }, { timeoutMs: deps.timeoutMs ?? RESOLVE_API_TIMEOUT_MS });
330
421
  // Network / API error → null, WITHOUT caching (transient; retry next time).
331
422
  if (matches === null)
332
- return base;
423
+ return none('lookup-failed');
333
424
  // 6. Exactly one enabled match is usable → positive cache (24h).
334
425
  if (matches.length === 1 && matches[0].vibedefendEnabled !== false) {
335
426
  const m = matches[0];
@@ -338,11 +429,11 @@ export async function resolveProjectIdWithApi(cwd = process.cwd(), deps = {}) {
338
429
  }
339
430
  // 0 / ≥2 matches, or a disabled project → negative cache (15m).
340
431
  writeCachedRepoLink(key, { negative: true }, deps.cacheDeps);
341
- return base;
432
+ return none('no-linked-project');
342
433
  }
343
434
  catch {
344
435
  // Fail-open: any unexpected error yields no projectId, never throws.
345
- return base;
436
+ return none('lookup-failed');
346
437
  }
347
438
  }
348
439
  //# sourceMappingURL=resolve.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../../src/hooks/runtime/resolve.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../../src/hooks/runtime/resolve.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * When the hook may ask the gateway again after it said no (BACK-240 L2).
3
+ *
4
+ * A 401 means the token is rejected: asking again with the same token gets
5
+ * the same answer, so the hook waits 1, then 5, then 15 minutes between
6
+ * attempts. A new token (a refresh, a new login) is tried at once, which is
7
+ * why a failure records the fingerprint of the token that failed.
8
+ *
9
+ * Any other failure (5xx, 429, a timeout, no network) waits
10
+ * `TRANSIENT_RETRY_MS`, or the response's `Retry-After` when it asks for
11
+ * longer (at most `MAX_RETRY_AFTER_MS`): retrying on every tool call during
12
+ * an outage only adds load, and starts a process per call.
13
+ */
14
+ import { createHash } from 'node:crypto';
15
+ /** Wait after the 1st, 2nd, then 3rd and later consecutive 401. */
16
+ export const UNAUTHORIZED_BACKOFF_MS = [
17
+ 60_000,
18
+ 5 * 60_000,
19
+ 15 * 60_000,
20
+ ];
21
+ /** Wait after a transient failure (same as the rules cache's `staleSec`). */
22
+ export const TRANSIENT_RETRY_MS = 60_000;
23
+ /** A `Retry-After` longer than this is capped. */
24
+ export const MAX_RETRY_AFTER_MS = 60 * 60_000;
25
+ /** Wait after a transient failure whose response asked for `retryAfterMs`. */
26
+ export function transientRetryMs(retryAfterMs) {
27
+ if (retryAfterMs === undefined || !Number.isFinite(retryAfterMs)) {
28
+ return TRANSIENT_RETRY_MS;
29
+ }
30
+ return Math.min(Math.max(retryAfterMs, TRANSIENT_RETRY_MS), MAX_RETRY_AFTER_MS);
31
+ }
32
+ /**
33
+ * Read a `Retry-After` header (delay in seconds, or an HTTP date) as
34
+ * milliseconds from `now`. Undefined when absent or unreadable.
35
+ */
36
+ export function parseRetryAfter(value, now = Date.now()) {
37
+ if (!value)
38
+ return undefined;
39
+ const trimmed = value.trim();
40
+ if (/^\d+$/.test(trimmed))
41
+ return Number(trimmed) * 1000;
42
+ const at = Date.parse(trimmed);
43
+ return Number.isFinite(at) ? Math.max(0, at - now) : undefined;
44
+ }
45
+ /** Wait before asking again after `consecutive` 401s in a row (1-based). */
46
+ export function unauthorizedBackoffMs(consecutive) {
47
+ const index = Math.min(Math.max(consecutive, 1), UNAUTHORIZED_BACKOFF_MS.length) - 1;
48
+ return UNAUTHORIZED_BACKOFF_MS[index];
49
+ }
50
+ /**
51
+ * A short, one-way fingerprint of a bearer token: enough to tell the token
52
+ * that was refused from a new one, without writing the token to disk.
53
+ */
54
+ export function tokenFingerprint(token) {
55
+ return createHash('sha256').update(token).digest('hex').slice(0, 16);
56
+ }
57
+ //# sourceMappingURL=retry-policy.js.map