thumbgate 1.27.16 → 1.27.18

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 (165) hide show
  1. package/.claude-plugin/marketplace.json +85 -0
  2. package/.claude-plugin/plugin.json +3 -4
  3. package/.well-known/llms.txt +12 -33
  4. package/.well-known/mcp/server-card.json +8 -8
  5. package/README.md +30 -215
  6. package/adapters/chatgpt/openapi.yaml +1695 -0
  7. package/adapters/claude/.mcp.json +2 -2
  8. package/adapters/gemini/function-declarations.json +0 -1
  9. package/adapters/mcp/server-stdio.js +11 -263
  10. package/adapters/opencode/opencode.json +1 -1
  11. package/bench/thumbgate-bench.json +2 -2
  12. package/bin/cli.js +122 -1421
  13. package/bin/postinstall.js +27 -11
  14. package/config/gate-templates.json +0 -216
  15. package/config/gates/claim-verification.json +0 -12
  16. package/config/gates/default.json +2 -31
  17. package/config/github-about.json +2 -2
  18. package/config/mcp-allowlists.json +13 -23
  19. package/config/merge-quality-checks.json +1 -0
  20. package/config/model-candidates.json +6 -121
  21. package/openapi/openapi.yaml +0 -12
  22. package/package.json +98 -228
  23. package/public/blog.html +4 -4
  24. package/public/codex-plugin.html +20 -72
  25. package/public/compare.html +8 -31
  26. package/public/dashboard.html +166 -930
  27. package/public/federal.html +2 -2
  28. package/public/guide.html +9 -33
  29. package/public/index.html +116 -495
  30. package/public/learn.html +18 -191
  31. package/public/lessons.html +10 -168
  32. package/public/numbers.html +7 -7
  33. package/public/pro.html +11 -34
  34. package/scripts/agent-memory-lifecycle.js +0 -211
  35. package/scripts/agent-readiness.js +3 -167
  36. package/scripts/agent-reward-model.js +1 -53
  37. package/scripts/auto-promote-gates.js +10 -82
  38. package/scripts/auto-wire-hooks.js +0 -14
  39. package/scripts/billing.js +1 -93
  40. package/scripts/build-metadata.js +10 -50
  41. package/scripts/cli-feedback.js +6 -18
  42. package/scripts/cli-schema.js +0 -90
  43. package/scripts/cli-telemetry.js +1 -6
  44. package/scripts/commercial-offer.js +2 -82
  45. package/scripts/context-manager.js +6 -74
  46. package/scripts/dashboard.js +2 -68
  47. package/scripts/durability/step.js +3 -3
  48. package/scripts/export-databricks-bundle.js +1 -5
  49. package/scripts/export-dpo-pairs.js +2 -7
  50. package/scripts/feedback-loop.js +1 -123
  51. package/scripts/feedback-quality.js +0 -87
  52. package/scripts/filesystem-search.js +10 -35
  53. package/scripts/gate-stats.js +0 -89
  54. package/scripts/gates-engine.js +85 -1105
  55. package/scripts/gemini-embedding-policy.js +1 -2
  56. package/scripts/hook-runtime.js +14 -20
  57. package/scripts/hook-thumbgate-cache-updater.js +2 -18
  58. package/scripts/hybrid-feedback-context.js +7 -142
  59. package/scripts/lesson-inference.js +3 -8
  60. package/scripts/lesson-search.js +1 -17
  61. package/scripts/license.js +1 -0
  62. package/scripts/llm-client.js +9 -390
  63. package/scripts/local-model-profile.js +8 -15
  64. package/scripts/memory-scope-readiness.js +0 -159
  65. package/scripts/meta-agent-loop.js +0 -36
  66. package/scripts/operational-integrity.js +5 -39
  67. package/scripts/oss-pr-opportunity-scout.js +5 -35
  68. package/scripts/plausible-server-events.js +6 -9
  69. package/scripts/pro-local-dashboard.js +4 -4
  70. package/scripts/proxy-pointer-rag-guardrails.js +1 -42
  71. package/scripts/rate-limiter.js +13 -64
  72. package/scripts/secret-scanner.js +5 -44
  73. package/scripts/security-scanner.js +10 -260
  74. package/scripts/self-distill-agent.js +1 -3
  75. package/scripts/seo-gsd.js +2 -916
  76. package/scripts/statusline-cache-path.js +2 -17
  77. package/scripts/statusline-local-stats.js +1 -9
  78. package/scripts/statusline-meta.js +2 -28
  79. package/scripts/statusline.sh +4 -20
  80. package/scripts/telemetry-analytics.js +0 -357
  81. package/scripts/thompson-sampling.js +10 -31
  82. package/scripts/thumbgate-bench.js +1 -16
  83. package/scripts/thumbgate-search.js +19 -85
  84. package/scripts/tool-registry.js +1 -169
  85. package/scripts/vector-store.js +0 -45
  86. package/scripts/workflow-sentinel.js +53 -286
  87. package/scripts/workspace-evolver.js +2 -62
  88. package/src/api/server.js +290 -2578
  89. package/.claude/commands/dashboard.md +0 -15
  90. package/.claude/commands/thumbgate-blocked.md +0 -27
  91. package/.claude/commands/thumbgate-dashboard.md +0 -15
  92. package/.claude/commands/thumbgate-doctor.md +0 -30
  93. package/.claude/commands/thumbgate-guard.md +0 -36
  94. package/.claude/commands/thumbgate-protect.md +0 -30
  95. package/.claude/commands/thumbgate-rules.md +0 -30
  96. package/.well-known/agentic-verify.txt +0 -1
  97. package/adapters/gcp/dfcx-webhook-gate.js +0 -295
  98. package/adapters/letta/README.md +0 -41
  99. package/adapters/letta/thumbgate-letta-adapter.js +0 -133
  100. package/adapters/policy-engine/ethicore-guardian-client.js +0 -68
  101. package/adapters/policy-engine/thumbgate-policy-engine-adapter.js +0 -260
  102. package/bench/observability-eval-suite.json +0 -26
  103. package/bin/dashboard-cli.js +0 -7
  104. package/commands/dashboard.md +0 -15
  105. package/commands/thumbgate-dashboard.md +0 -15
  106. package/config/builtin-lessons.json +0 -23
  107. package/config/gate-classifier-routing.json +0 -98
  108. package/config/post-deploy-marketing-pages.json +0 -61
  109. package/public/about.html +0 -162
  110. package/public/agent-manager.html +0 -179
  111. package/public/agents-cost-savings.html +0 -153
  112. package/public/ai-malpractice-prevention.html +0 -818
  113. package/public/assets/brand/github-social-preview.png +0 -0
  114. package/public/assets/brand/thumbgate-icon-512.png +0 -0
  115. package/public/assets/brand/thumbgate-icon-pro-512.png +0 -0
  116. package/public/assets/brand/thumbgate-icon-team-512.png +0 -0
  117. package/public/assets/brand/thumbgate-logo-1200x360.png +0 -0
  118. package/public/assets/brand/thumbgate-logo-transparent.svg +0 -22
  119. package/public/assets/brand/thumbgate-mark-inline-v3.svg +0 -19
  120. package/public/assets/brand/thumbgate-mark-pro.svg +0 -23
  121. package/public/assets/brand/thumbgate-mark-team.svg +0 -26
  122. package/public/assets/brand/thumbgate-mark.svg +0 -21
  123. package/public/assets/brand/thumbgate-wordmark.svg +0 -20
  124. package/public/assets/claude-thumbgate-statusbar.svg +0 -8
  125. package/public/assets/codex-thumbgate-statusbar-test.svg +0 -9
  126. package/public/assets/legal-intake-control-flow.svg +0 -66
  127. package/public/brand/thumbgate-mark.svg +0 -19
  128. package/public/brand/thumbgate-og.svg +0 -16
  129. package/public/chatgpt-app.html +0 -330
  130. package/public/codex-enterprise.html +0 -123
  131. package/public/js/buyer-intent.js +0 -672
  132. package/public/pricing.html +0 -399
  133. package/scripts/action-receipts.js +0 -324
  134. package/scripts/activation-quickstart.js +0 -187
  135. package/scripts/agent-operations-planner.js +0 -621
  136. package/scripts/ai-component-inventory.js +0 -367
  137. package/scripts/async-eval-observability.js +0 -236
  138. package/scripts/audit.js +0 -65
  139. package/scripts/aws-blocks-guardrails.js +0 -228
  140. package/scripts/classifier-routing.js +0 -130
  141. package/scripts/dashboard-chat.js +0 -332
  142. package/scripts/feedback-aggregate.js +0 -281
  143. package/scripts/feedback-sanitizer.js +0 -105
  144. package/scripts/hob-pack.js +0 -591
  145. package/scripts/hook-stop-anti-claim.js +0 -301
  146. package/scripts/install-shim.js +0 -87
  147. package/scripts/mcp-oauth.js +0 -293
  148. package/scripts/noop-detect.js +0 -285
  149. package/scripts/omlx-smoke.js +0 -192
  150. package/scripts/parallel-workflow-orchestrator.js +0 -293
  151. package/scripts/plan-gate.js +0 -243
  152. package/scripts/plausible-domain-config.js +0 -99
  153. package/scripts/qa-scenario-planner.js +0 -136
  154. package/scripts/repeat-metric.js +0 -137
  155. package/scripts/secret-fixture-tokens.js +0 -61
  156. package/scripts/secret-redaction.js +0 -166
  157. package/scripts/self-harness-optimizer.js +0 -141
  158. package/scripts/self-healing-check.js +0 -193
  159. package/scripts/silent-failure-cluster.js +0 -531
  160. package/scripts/statusline-cache-read.js +0 -57
  161. package/scripts/sync-telemetry-from-prod.js +0 -374
  162. package/scripts/tool-contract-validator.js +0 -76
  163. package/scripts/trajectory-scorer.js +0 -63
  164. package/scripts/verify-marketing-pages-deployed.js +0 -195
  165. package/scripts/visitor-journey.js +0 -172
@@ -122,7 +122,7 @@ function resolveGeminiEmbeddingConfig(env = process.env) {
122
122
 
123
123
  return {
124
124
  enabled,
125
- provider: provider === 'coreai' ? 'coreai' : (enabled ? 'gemini' : 'local'),
125
+ provider: enabled ? 'gemini' : 'local',
126
126
  model: String(env.THUMBGATE_GEMINI_EMBED_MODEL || GEMINI_EMBEDDING_2_MODEL).trim() || GEMINI_EMBEDDING_2_MODEL,
127
127
  apiKey,
128
128
  apiBaseUrl: trimTrailingSlashes(env.THUMBGATE_GEMINI_API_BASE_URL || 'https://generativelanguage.googleapis.com/v1beta'),
@@ -171,7 +171,6 @@ function buildGeminiEmbeddingRolloutPlan(args = {}) {
171
171
  },
172
172
  rolloutSteps: [
173
173
  'Keep local embeddings as the default offline path.',
174
- 'For Apple Silicon developers, route local queries through Core AI (AOT compiled models) to bypass CPU overhead.',
175
174
  'Enable Gemini Embedding 2 only when a Gemini API key is present.',
176
175
  'Use task-specific query/document prefixes at index and retrieval time.',
177
176
  'Start at 768 dimensions, then benchmark 1536 only if recall misses show up.',
@@ -7,7 +7,6 @@ const {
7
7
  publishedCliAvailable,
8
8
  } = require('./mcp-config');
9
9
  const { publishedCliShellCommand } = require('./published-cli');
10
- const { shimInstalled, shimPath } = require('./install-shim');
11
10
 
12
11
  const PKG_ROOT = path.join(__dirname, '..');
13
12
  const featureSupportCache = new Map();
@@ -34,39 +33,34 @@ function publishedHookCommandsAvailable(version) {
34
33
  return available;
35
34
  }
36
35
 
37
- function resolveCliCommand(subcommand) {
38
- // Source checkout: always use direct node command for development
39
- if (isSourceCheckout(PKG_ROOT)) {
40
- return `node ${shellQuote(path.join(PKG_ROOT, 'bin', 'cli.js'))} ${subcommand}`;
41
- }
42
- // Prefer stable shim — always resolves @latest, survives version bumps
43
- if (shimInstalled()) {
44
- return `${shellQuote(shimPath())} ${subcommand}`;
45
- }
36
+ function resolveCliBaseCommand() {
46
37
  const version = packageVersion();
47
38
  if (publishedHookCommandsAvailable(version)) {
48
- return publishedCliShellCommand(version, [subcommand]);
39
+ return publishedCliShellCommand(version);
40
+ }
41
+ if (isSourceCheckout(PKG_ROOT)) {
42
+ return `node ${shellQuote(path.join(PKG_ROOT, 'bin', 'cli.js'))}`;
49
43
  }
50
- return publishedCliShellCommand(version, [subcommand]);
44
+ return publishedCliShellCommand(version);
51
45
  }
52
46
 
53
- function resolveCodexCliCommand(subcommand) {
47
+ function resolveCodexCliBaseCommand() {
54
48
  const version = packageVersion();
55
49
  if (publishedHookCommandsAvailable(version)) {
56
- return publishedCliShellCommand('latest', [subcommand], { preferInstalled: false });
50
+ return publishedCliShellCommand('latest', [], { preferInstalled: false });
57
51
  }
58
52
  if (isSourceCheckout(PKG_ROOT)) {
59
- return `node ${shellQuote(path.join(PKG_ROOT, 'bin', 'cli.js'))} ${subcommand}`;
53
+ return `node ${shellQuote(path.join(PKG_ROOT, 'bin', 'cli.js'))}`;
60
54
  }
61
- return publishedCliShellCommand('latest', [subcommand], { preferInstalled: false });
55
+ return publishedCliShellCommand('latest', [], { preferInstalled: false });
62
56
  }
63
57
 
64
58
  function buildPortableHookCommand(subcommand) {
65
- return resolveCliCommand(subcommand);
59
+ return `${resolveCliBaseCommand()} ${subcommand}`;
66
60
  }
67
61
 
68
62
  function buildCodexPortableHookCommand(subcommand) {
69
- return resolveCodexCliCommand(subcommand);
63
+ return `${resolveCodexCliBaseCommand()} ${subcommand}`;
70
64
  }
71
65
 
72
66
  function preToolHookCommand() {
@@ -121,8 +115,8 @@ module.exports = {
121
115
  packageVersion,
122
116
  publishedHookCommandsAvailable,
123
117
  preToolHookCommand,
124
- resolveCodexCliCommand,
125
- resolveCliCommand,
118
+ resolveCodexCliBaseCommand,
119
+ resolveCliBaseCommand,
126
120
  sessionStartHookCommand,
127
121
  statuslineCommand,
128
122
  userPromptHookCommand,
@@ -6,27 +6,11 @@
6
6
  * Also used directly by the CLI to refresh statusline counters after feedback capture.
7
7
  */
8
8
 
9
- const fs = require('node:fs');
10
- const os = require('node:os');
11
- const path = require('node:path');
9
+ const fs = require('fs');
10
+ const path = require('path');
12
11
  const { resolveFeedbackDir } = require('./feedback-paths');
13
- const {
14
- getAggregateStatuslineCachePath,
15
- shouldAggregateFeedback,
16
- } = require('./feedback-aggregate');
17
12
 
18
13
  function getCachePath() {
19
- const explicitFeedbackDir = process.env.THUMBGATE_FEEDBACK_DIR;
20
- if (shouldAggregateFeedback() && explicitFeedbackDir) {
21
- try {
22
- if (path.resolve(explicitFeedbackDir).startsWith(path.resolve(os.tmpdir()) + path.sep)) {
23
- return path.join(resolveFeedbackDir(), 'statusline_cache.json');
24
- }
25
- } catch {
26
- return path.join(resolveFeedbackDir(), 'statusline_cache.json');
27
- }
28
- }
29
- if (shouldAggregateFeedback()) return getAggregateStatuslineCachePath();
30
14
  return path.join(resolveFeedbackDir(), 'statusline_cache.json');
31
15
  }
32
16
 
@@ -18,11 +18,6 @@ const fs = require('fs');
18
18
  const path = require('path');
19
19
  const { resolveFeedbackDir } = require('./feedback-paths');
20
20
  const { readJsonl } = require('./fs-utils');
21
- const {
22
- TRANSPORT_WORDS,
23
- sanitizeFeedbackText,
24
- transportWordsOnly,
25
- } = require('./feedback-sanitizer');
26
21
 
27
22
  // ---------------------------------------------------------------------------
28
23
  // Paths
@@ -56,7 +51,6 @@ const STOPWORDS = new Set([
56
51
  'has', 'had', 'not', 'but', 'they', 'you', 'can', 'will', 'all', 'any',
57
52
  'one', 'its', 'our', 'also', 'more', 'very', 'just', 'into', 'been',
58
53
  'bash', 'edit', 'write', 'tool', 'hook', 'clear',
59
- ...TRANSPORT_WORDS,
60
54
  ]);
61
55
 
62
56
  const NEG = new Set([
@@ -80,7 +74,7 @@ const HYBRID_JSONL_READ_LIMIT = 400;
80
74
  */
81
75
  function normalize(text) {
82
76
  if (!text || typeof text !== 'string') return '';
83
- return sanitizeFeedbackText(text)
77
+ return text
84
78
  .replace(/\/Users\/[^\s/]+/g, '/Users/redacted')
85
79
  .replace(/:\d{4,5}\b/g, ':PORT')
86
80
  .toLowerCase()
@@ -103,9 +97,7 @@ function stripFeedbackPrefix(text) {
103
97
  * Compose normalize + stripFeedbackPrefix.
104
98
  */
105
99
  function normalizePatternText(text) {
106
- const normalized = normalize(stripFeedbackPrefix(text));
107
- if (transportWordsOnly(normalized)) return '';
108
- return normalized;
100
+ return normalize(stripFeedbackPrefix(text));
109
101
  }
110
102
 
111
103
  /**
@@ -133,104 +125,6 @@ function classify(entry) {
133
125
  return 'neutral';
134
126
  }
135
127
 
136
- function isHookPromptEnvelope(context) {
137
- if (!context || typeof context !== 'string') return false;
138
- try {
139
- const parsed = JSON.parse(context);
140
- if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return false;
141
- return Boolean(
142
- parsed.prompt &&
143
- (
144
- parsed.hookEventName ||
145
- parsed.hook_event_name ||
146
- parsed.workspaceRoot ||
147
- parsed.workspace_root ||
148
- parsed.session_id ||
149
- parsed.sessionId ||
150
- parsed.transcript_path ||
151
- parsed.transcriptPath
152
- )
153
- );
154
- } catch (_) {
155
- return false;
156
- }
157
- }
158
-
159
- function patternContext(entry) {
160
- const context = entry && entry.context ? String(entry.context) : '';
161
- if (!context) return '';
162
- const hasExplicitFeedback = Boolean(
163
- entry.whatWentWrong ||
164
- entry.what_went_wrong ||
165
- entry.whatToChange ||
166
- entry.what_to_change ||
167
- entry.failureType ||
168
- (Array.isArray(entry.tags) && entry.tags.length > 0) ||
169
- entry.structuredRule
170
- );
171
- if (isHookPromptEnvelope(context) && !hasExplicitFeedback) return '';
172
- if (isHookPromptEnvelope(context) && hasExplicitFeedback) {
173
- return '';
174
- }
175
- return context;
176
- }
177
-
178
- /**
179
- * Check if the feedback entry is an automated enforcement log (e.g. from gates engine)
180
- * rather than real developer/user feedback.
181
- */
182
- function isAutomatedFeedback(entry) {
183
- const tags = entry.tags || [];
184
- if (tags.includes('auto-capture') || tags.includes('gates-engine') || tags.includes('audit-trail')) {
185
- return true;
186
- }
187
- const context = String(entry.context || entry.whatWentWrong || '').toLowerCase();
188
- return context.includes('gate "') || context.includes('blocked tool') || context.includes('warned tool');
189
- }
190
-
191
-
192
- function isHookPromptEnvelope(context) {
193
- if (!context || typeof context !== 'string') return false;
194
- try {
195
- const parsed = JSON.parse(context);
196
- if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return false;
197
- return Boolean(
198
- parsed.prompt &&
199
- (
200
- parsed.hookEventName ||
201
- parsed.hook_event_name ||
202
- parsed.workspaceRoot ||
203
- parsed.workspace_root ||
204
- parsed.session_id ||
205
- parsed.sessionId ||
206
- parsed.transcript_path ||
207
- parsed.transcriptPath
208
- )
209
- );
210
- } catch (_) {
211
- return false;
212
- }
213
- }
214
-
215
- function patternContext(entry) {
216
- const context = entry && entry.context ? String(entry.context) : '';
217
- if (!context) return '';
218
- const hasExplicitFeedback = Boolean(
219
- entry.whatWentWrong ||
220
- entry.what_went_wrong ||
221
- entry.whatToChange ||
222
- entry.what_to_change ||
223
- entry.failureType ||
224
- (Array.isArray(entry.tags) && entry.tags.length > 0) ||
225
- entry.structuredRule
226
- );
227
- if (isHookPromptEnvelope(context) && !hasExplicitFeedback) return '';
228
- if (isHookPromptEnvelope(context) && hasExplicitFeedback) {
229
- return '';
230
- }
231
- return context;
232
- }
233
-
234
128
  /**
235
129
  * Extract ms from a timestamp value. Returns 0 on failure.
236
130
  */
@@ -318,15 +212,13 @@ function buildHybridState(opts) {
318
212
  if (cls === 'positive') positive++;
319
213
  if (cls === 'negative') {
320
214
  negative++;
321
- // Track tool-level negative counts (exclude automated gate logs)
322
- if (!isAutomatedFeedback(entry)) {
323
- const toolName = inferToolName(entry.toolName || entry.tool_name || 'unknown', entry.context || '');
324
- toolNegatives[toolName] = (toolNegatives[toolName] || 0) + 1;
325
- }
215
+ // Track tool-level negative counts
216
+ const toolName = inferToolName(entry.toolName || entry.tool_name || 'unknown', entry.context || '');
217
+ toolNegatives[toolName] = (toolNegatives[toolName] || 0) + 1;
326
218
 
327
219
  // Build pattern from context / whatWentWrong / what_went_wrong
328
220
  const rawText = [
329
- patternContext(entry),
221
+ entry.context || '',
330
222
  entry.whatWentWrong || entry.what_went_wrong || '',
331
223
  entry.whatToChange || entry.what_to_change || '',
332
224
  entry.failureType || '',
@@ -362,13 +254,11 @@ function buildHybridState(opts) {
362
254
 
363
255
  // Process attributed feedback separately to track attributed tool counts
364
256
  for (const entry of attributedEntries) {
365
- if (classify(entry) !== 'negative') continue; // skip pruned/positive
366
- if (isAutomatedFeedback(entry)) continue; // skip automated gate blocks
367
257
  const toolName = inferToolName(entry.toolName || entry.tool_name || entry.attributed_tool || 'unknown', entry.context || '');
368
258
  toolNegativesAttributed[toolName] = (toolNegativesAttributed[toolName] || 0) + 1;
369
259
 
370
260
  const rawText = [
371
- patternContext(entry),
261
+ entry.context || '',
372
262
  entry.whatWentWrong || entry.what_went_wrong || '',
373
263
  ...(Array.isArray(entry.tags) ? entry.tags : []),
374
264
  ...(entry.richContext && Array.isArray(entry.richContext.filePaths) ? entry.richContext.filePaths : []),
@@ -730,36 +620,12 @@ function evaluatePretool(toolName, toolInput, opts) {
730
620
 
731
621
  // Slow path: build live state (also used when compiled guards are stale)
732
622
  const state = buildHybridState({
733
- feedbackDir: o.feedbackDir,
734
623
  feedbackLogPath: o.feedbackLogPath,
735
624
  attributedFeedbackPath: o.attributedFeedbackPath,
736
625
  });
737
626
  return evaluatePretoolFromState(state, toolName, toolInput);
738
627
  }
739
628
 
740
- // Claw-style agent support (high-ROI for EnterpriseClaw / OpenShell agents from Automation Anywhere / Nvidia)
741
- // Extends hybrid context for claw_action_type (file, screen, dynamic-tool, orchestration), agent_identity, hybrid_route.
742
- // Use in evaluatePretool calls from claw-aware MCP/hooks: pass {clawContext: {actionType: 'dynamic-tool-creation', agentId: '...', route: 'local/cloud'}} in opts.
743
- function evaluateClawPretool(toolName, toolInput, clawContext, opts) {
744
- const o = opts || {};
745
- const claw = clawContext || {};
746
- // Merge claw metadata into toolInput for gate evaluation (so templates like block-dynamic-tool-creation can match)
747
- const enrichedInput = {
748
- ...(typeof toolInput === 'object' ? toolInput : { raw: toolInput }),
749
- _claw: {
750
- actionType: claw.actionType || 'unknown',
751
- agentId: claw.agentId || 'unknown',
752
- hybridRoute: claw.hybridRoute || 'unknown',
753
- screenInteraction: !!claw.screenInteraction,
754
- fileAccess: !!claw.fileAccess,
755
- }
756
- };
757
- const result = evaluatePretool(toolName, JSON.stringify(enrichedInput), o);
758
- // Tag result with claw metadata for logging/feedback
759
- result.clawContext = claw;
760
- return result;
761
- }
762
-
763
629
  // ---------------------------------------------------------------------------
764
630
  // CLI main()
765
631
  // ---------------------------------------------------------------------------
@@ -808,7 +674,6 @@ function main() {
808
674
  module.exports = {
809
675
  buildHybridState,
810
676
  evaluatePretool,
811
- evaluateClawPretool,
812
677
  compileGuardArtifact,
813
678
  writeGuardArtifact,
814
679
  readGuardArtifact,
@@ -18,7 +18,6 @@ const fs = require('fs');
18
18
  const path = require('path');
19
19
  const { resolveFeedbackDir } = require('./feedback-paths');
20
20
  const { ensureParentDir, readJsonl } = require('./fs-utils');
21
- const { redactSecretsDeep } = require('./secret-redaction');
22
21
  const {
23
22
  buildStableId,
24
23
  extractFilePaths,
@@ -138,19 +137,15 @@ function createLesson({ feedbackId, signal, inferredLesson, triggerMessage, prio
138
137
  // Stable link: dashboard deep-link to this lesson
139
138
  lesson.link = `${getLessonBaseUrl()}/lessons#${lesson.id}`;
140
139
 
141
- // Redact secrets before persisting — lesson text is derived from conversation content that may
142
- // have captured a pasted credential. See scripts/secret-redaction.js.
143
- const redactedLesson = redactSecretsDeep(lesson);
144
-
145
140
  const lessonsPath = getLessonsPath();
146
141
  ensureParentDir(lessonsPath);
147
- fs.appendFileSync(lessonsPath, JSON.stringify(redactedLesson) + '\n');
142
+ fs.appendFileSync(lessonsPath, JSON.stringify(lesson) + '\n');
148
143
 
149
144
  // Update recent lesson for statusbar
150
145
  const recentPath = getRecentLessonPath();
151
- fs.writeFileSync(recentPath, JSON.stringify(redactedLesson, null, 2) + '\n');
146
+ fs.writeFileSync(recentPath, JSON.stringify(lesson, null, 2) + '\n');
152
147
 
153
- return redactedLesson;
148
+ return lesson;
154
149
  }
155
150
 
156
151
  /**
@@ -2,7 +2,6 @@
2
2
 
3
3
  const path = require('node:path');
4
4
  const { readJSONL, getFeedbackPaths } = require('./feedback-loop');
5
- const { buildMemoryLifecycleView, scoreHybridMemoryMatch } = require('./agent-memory-lifecycle');
6
5
  const { loadOptionalModule } = require('./private-core-boundary');
7
6
 
8
7
  const HIGH_RISK_TAGS = new Set([
@@ -412,8 +411,7 @@ function scoreLesson(queryText, memory, parsed, sourceFeedback) {
412
411
  const score = jaccardSimilarity(queryTokens, lessonTokens)
413
412
  + substringBoost(queryText, lessonText)
414
413
  + recencyScore(memory.timestamp)
415
- + (memory.category === 'error' ? 0.05 : 0)
416
- + Math.min(0.2, scoreHybridMemoryMatch(queryText, memory).score * 0.1);
414
+ + (memory.category === 'error' ? 0.05 : 0);
417
415
 
418
416
  return {
419
417
  score,
@@ -429,7 +427,6 @@ function buildLessonResult(memory, sourceFeedback, options = {}) {
429
427
  const { score, matchedTokens } = scoreLesson(options.query || '', memory, parsed, sourceFeedback);
430
428
  const harnessRecommendations = buildHarnessRecommendations(memory, parsed, sourceFeedback, ruleMatches, gateMatches);
431
429
  const lifecycle = buildLifecycle(memory, parsed, sourceFeedback, ruleMatches, gateMatches, harnessRecommendations);
432
- const memoryLifecycle = buildMemoryLifecycleView(memory, { query: options.query || '' });
433
430
 
434
431
  return {
435
432
  id: memory.id,
@@ -455,7 +452,6 @@ function buildLessonResult(memory, sourceFeedback, options = {}) {
455
452
  systemResponse: {
456
453
  promotedToMemory: true,
457
454
  lifecycle,
458
- memoryLifecycle,
459
455
  diagnosis: memory.diagnosis || null,
460
456
  sourceFeedback: sourceFeedback
461
457
  ? {
@@ -593,14 +589,6 @@ function tryFts5Search(query, options) {
593
589
  tags: row.tags,
594
590
  importance: row.importance,
595
591
  timestamp: row.timestamp,
596
- memoryLifecycle: buildMemoryLifecycleView({
597
- title: row.context,
598
- content: [row.whatWentWrong, row.whatToChange, row.whatWorked].filter(Boolean).join('\n'),
599
- domain: row.domain,
600
- tags: row.tags,
601
- importance: row.importance,
602
- timestamp: row.timestamp,
603
- }, { query: query || '' }),
604
592
  })),
605
593
  backend: 'sqlite-fts5',
606
594
  };
@@ -630,10 +618,6 @@ function formatLessonSearchResults(payload) {
630
618
  payload.results.forEach((result, index) => {
631
619
  lines.push(`${index + 1}. ${result.title}`);
632
620
  lines.push(` Category: ${result.category} | Tags: ${result.tags.join(', ') || 'none'} | Score: ${result.score}`);
633
- if (result.systemResponse.memoryLifecycle) {
634
- const memoryLifecycle = result.systemResponse.memoryLifecycle;
635
- lines.push(` Memory: scope=${memoryLifecycle.scope} | decay=${memoryLifecycle.decay.state} | hybrid=${memoryLifecycle.retrievalHints.hybridScore}`);
636
- }
637
621
  if (result.lesson.summary) {
638
622
  lines.push(` Lesson: ${result.lesson.summary}`);
639
623
  }
@@ -80,6 +80,7 @@ module.exports = {
80
80
  verifyLicense,
81
81
  isProLicensed,
82
82
  activateLicense,
83
+ generateLicenseKey,
83
84
  isValidKey,
84
85
  VALID_PREFIXES,
85
86
  LICENSE_PATH,