thumbgate 1.30.0 → 1.34.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 (92) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.well-known/mcp/server-card.json +1 -1
  3. package/README.md +54 -16
  4. package/adapters/claude/.mcp.json +2 -2
  5. package/adapters/forge/forge.yaml +3 -3
  6. package/adapters/mcp/server-stdio.js +105 -10
  7. package/adapters/opencode/opencode.json +1 -1
  8. package/bench/observability-eval-suite.json +2 -2
  9. package/bin/cli.js +168 -31
  10. package/config/evals/generation-quality-golden.json +95 -0
  11. package/config/evals/rag-answer-quality-golden.json +91 -0
  12. package/config/evals/retrieval-hybrid-ablation.json +66 -0
  13. package/config/evals/retrieval-ranking-golden.json +522 -0
  14. package/config/gates/claim-verifiers.example.json +42 -0
  15. package/config/gates/claim-verifiers.json +25 -0
  16. package/config/gates/default.json +217 -50
  17. package/config/mcp-allowlists.json +233 -206
  18. package/config/model-tiers.json +7 -2
  19. package/glama.json +6 -0
  20. package/hooks/hooks.json +1 -1
  21. package/package.json +69 -12
  22. package/public/assets/diagrams/before-after.svg +17 -16
  23. package/public/assets/diagrams/hero-thumbs.svg +68 -0
  24. package/public/assets/diagrams/loop.svg +19 -13
  25. package/public/assets/diagrams/self-improving-thumbs-loop.svg +105 -0
  26. package/public/compare.html +1 -0
  27. package/public/dashboard.html +126 -28
  28. package/public/evaluations.html +1 -1
  29. package/public/index.html +142 -13
  30. package/public/numbers.html +3 -2
  31. package/public/pricing.html +143 -30
  32. package/scripts/a-plus-evidence-scorecard.js +303 -0
  33. package/scripts/agent-readiness.js +110 -0
  34. package/scripts/async-eval-observability.js +36 -11
  35. package/scripts/audit-trail.js +37 -1
  36. package/scripts/auto-promote-gates.js +149 -34
  37. package/scripts/auto-wire-hooks.js +20 -8
  38. package/scripts/cli-schema.js +14 -0
  39. package/scripts/colbert-style-maxsim.js +236 -0
  40. package/scripts/cross-encoder-reranker.js +356 -126
  41. package/scripts/dashboard-chat.js +350 -17
  42. package/scripts/document-intake.js +283 -7
  43. package/scripts/eval-quality-suite.js +204 -0
  44. package/scripts/feedback-loop.js +115 -7
  45. package/scripts/feedback-paths.js +32 -13
  46. package/scripts/feedback-quality.js +53 -0
  47. package/scripts/feedback-schema.js +3 -0
  48. package/scripts/file-ledger-lock.js +130 -0
  49. package/scripts/filesystem-search.js +17 -7
  50. package/scripts/financial-control-plane.js +1514 -0
  51. package/scripts/gates-engine.js +202 -7
  52. package/scripts/gemini-embedding-policy.js +1 -0
  53. package/scripts/harness-tool-names.js +70 -0
  54. package/scripts/hook-runtime.js +15 -3
  55. package/scripts/hook-stop-anti-claim.js +63 -3
  56. package/scripts/human-escalation.js +353 -41
  57. package/scripts/lesson-db.js +16 -5
  58. package/scripts/lesson-embedding-index.js +67 -20
  59. package/scripts/lesson-embedding-maintenance.js +177 -0
  60. package/scripts/lesson-reranker.js +55 -9
  61. package/scripts/lesson-retrieval.js +305 -29
  62. package/scripts/lesson-search.js +22 -8
  63. package/scripts/llm-client.js +304 -15
  64. package/scripts/model-tier-router.js +593 -0
  65. package/scripts/pragmatic-hybrid-search.js +379 -0
  66. package/scripts/provider-action-normalizer.js +11 -4
  67. package/scripts/rag-document-pipeline.js +461 -0
  68. package/scripts/rag-structured-output.js +441 -0
  69. package/scripts/ragas-style-metrics.js +351 -0
  70. package/scripts/request-envelope.js +178 -0
  71. package/scripts/rerank-pipeline.js +370 -0
  72. package/scripts/rerank-quality-eval.js +155 -0
  73. package/scripts/retrieval-hybrid-ablation.js +120 -0
  74. package/scripts/retrieval-quality-tier.js +118 -0
  75. package/scripts/secret-scanner.js +395 -4
  76. package/scripts/self-distill-agent.js +7 -1
  77. package/scripts/self-healing-check.js +25 -0
  78. package/scripts/skill-packs.js +183 -0
  79. package/scripts/slow-loop.js +72 -0
  80. package/scripts/statusline-links.js +1 -1
  81. package/scripts/statusline.sh +8 -1
  82. package/scripts/telemetry-analytics.js +13 -1
  83. package/scripts/thumbgate-search.js +98 -6
  84. package/scripts/tier-budget-guard.js +186 -0
  85. package/scripts/tool-registry.js +141 -5
  86. package/scripts/universal-claim-evaluator.js +767 -0
  87. package/scripts/vector-store.js +154 -17
  88. package/scripts/verify-marketing-pages-deployed.js +85 -3
  89. package/scripts/workflow-sentinel.js +77 -11
  90. package/server.json +44 -0
  91. package/smithery.yaml +17 -0
  92. package/src/api/server.js +196 -13
@@ -248,6 +248,20 @@ const TOOLS = [
248
248
  scope: MEMORY_SCOPE_SCHEMA,
249
249
  requireScope: { type: 'boolean', description: 'Fail closed unless a complete four-field scope is supplied.' },
250
250
  includeShared: { type: 'boolean', description: 'Include explicitly shared memories with scoped results. Defaults true.' },
251
+ filters: {
252
+ type: 'object',
253
+ description: 'Pre-filter the candidate corpus before lexical or vector ranking.',
254
+ properties: {
255
+ domain: { type: ['string', 'array'], items: { type: 'string' } },
256
+ signal: { type: ['string', 'array'], items: { type: 'string' } },
257
+ source: { type: ['string', 'array'], items: { type: 'string' } },
258
+ toolsUsed: { type: ['string', 'array'], items: { type: 'string' } },
259
+ tags: { type: 'array', items: { type: 'string' } },
260
+ requireAllTags: { type: 'boolean' },
261
+ },
262
+ },
263
+ queryRewrite: { type: 'boolean', description: 'Enable bounded deterministic synonym expansion when the original lexical match is weak. Defaults true.' },
264
+ includeRetrievalMeta: { type: 'boolean', description: 'Include path provenance such as lexical/dense pools and query variants.' },
251
265
  },
252
266
  required: ['toolName'],
253
267
  },
@@ -276,6 +290,17 @@ const TOOLS = [
276
290
  limit: { type: 'number', description: 'Maximum results to return (default 10)' },
277
291
  source: { type: 'string', enum: ['all', 'feedback', 'context', 'rules', 'documents'], description: 'Restrict search to a single ThumbGate source.' },
278
292
  signal: { type: 'string', enum: ['up', 'down', 'positive', 'negative'], description: 'Optional feedback-signal filter when searching feedback data.' },
293
+ filters: {
294
+ type: 'object',
295
+ description: 'Pre-filter imported documents before chunk ranking.',
296
+ properties: {
297
+ tags: { type: 'array', items: { type: 'string' } },
298
+ requireAllTags: { type: 'boolean' },
299
+ sourceFormat: { type: 'string' },
300
+ sourceType: { type: 'string' },
301
+ },
302
+ },
303
+ queryRewrite: { type: 'boolean', description: 'Enable bounded deterministic synonym expansion. Defaults true.' },
279
304
  },
280
305
  },
281
306
  }),
@@ -1160,14 +1185,91 @@ const TOOLS = [
1160
1185
  },
1161
1186
  },
1162
1187
  }),
1188
+ destructiveTool({
1189
+ name: 'create_purchase_requisition',
1190
+ description: 'Create an append-only purchase requisition and independent human-escalation request. This does not authorize spending.',
1191
+ inputSchema: {
1192
+ type: 'object',
1193
+ additionalProperties: false,
1194
+ required: ['taskId', 'vendor', 'amountUsd', 'purpose', 'sourceMessageId', 'evidence', 'toolName', 'toolInput'],
1195
+ properties: {
1196
+ taskId: { type: 'string', minLength: 1 },
1197
+ vendor: { type: 'string', minLength: 1 },
1198
+ amountUsd: { type: 'number', exclusiveMinimum: 0 },
1199
+ purpose: { type: 'string', minLength: 1 },
1200
+ sourceMessageId: { type: 'string', minLength: 1, description: 'Stable identifier for the exact user message authorizing the request.' },
1201
+ toolName: { type: 'string', minLength: 1, description: 'Exact future economic tool name. The human-approved requisition is cryptographically bound to it.' },
1202
+ toolInput: { type: 'object', minProperties: 1, description: 'Exact future economic tool input before financialControl metadata is attached. Stored only as a fingerprint.' },
1203
+ evidence: { type: 'array', minItems: 1, items: { type: 'string', minLength: 1 } },
1204
+ ttlMs: { type: 'number', minimum: 1 },
1205
+ idempotencyKey: { type: 'string', minLength: 1 },
1206
+ },
1207
+ },
1208
+ }),
1209
+ readOnlyTool({
1210
+ name: 'list_purchase_requisitions',
1211
+ description: 'List projected purchase-requisition states from the append-only financial ledger and human-review queue.',
1212
+ inputSchema: {
1213
+ type: 'object',
1214
+ additionalProperties: false,
1215
+ properties: {
1216
+ status: { type: 'string' },
1217
+ limit: { type: 'integer', minimum: 1, maximum: 100 },
1218
+ },
1219
+ },
1220
+ }),
1221
+ destructiveTool({
1222
+ name: 'reserve_purchase_requisition',
1223
+ description: 'Reserve a single-use amount from an independently approved purchase requisition. Approval is unavailable from the agent tool surface.',
1224
+ inputSchema: {
1225
+ type: 'object',
1226
+ additionalProperties: false,
1227
+ required: ['requisitionId', 'amountUsd', 'vendor', 'purpose', 'sourceMessageId'],
1228
+ properties: {
1229
+ requisitionId: { type: 'string', minLength: 1 },
1230
+ amountUsd: { type: 'number', exclusiveMinimum: 0 },
1231
+ vendor: { type: 'string', minLength: 1 },
1232
+ purpose: { type: 'string', minLength: 1 },
1233
+ sourceMessageId: { type: 'string', minLength: 1 },
1234
+ ttlMs: { type: 'number', minimum: 1 },
1235
+ idempotencyKey: { type: 'string', minLength: 1 },
1236
+ },
1237
+ },
1238
+ }),
1239
+ destructiveTool({
1240
+ name: 'settle_purchase_requisition',
1241
+ description: 'Commit actual spend with receipt evidence or release an unused reservation. Events are append-only.',
1242
+ inputSchema: {
1243
+ type: 'object',
1244
+ additionalProperties: false,
1245
+ required: ['requisitionId', 'reservationId', 'status'],
1246
+ properties: {
1247
+ requisitionId: { type: 'string', minLength: 1 },
1248
+ reservationId: { type: 'string', minLength: 1 },
1249
+ status: { type: 'string', enum: ['committed', 'released'] },
1250
+ actualAmountUsd: { type: 'number', minimum: 0 },
1251
+ evidence: { type: 'array', items: { type: 'string', minLength: 1 } },
1252
+ reason: { type: 'string' },
1253
+ },
1254
+ },
1255
+ }),
1256
+ readOnlyTool({
1257
+ name: 'reconcile_purchase_ledger',
1258
+ description: 'Reconcile the append-only financial ledger, including totals, stale reservations, status counts, and tamper-evident event hashes.',
1259
+ inputSchema: {
1260
+ type: 'object',
1261
+ additionalProperties: false,
1262
+ properties: {},
1263
+ },
1264
+ }),
1163
1265
  readOnlyTool({
1164
1266
  name: 'verify_claim',
1165
- description: 'Check whether a claim has enough tracked evidence before the agent asserts it.',
1267
+ description: 'Check whether a claim has enough tracked evidence and, for parseable factual claims (row counts, file lines/bytes/existence, versions), recheck configured SQLite/filesystem/JSON verifiers before the agent asserts it.',
1166
1268
  inputSchema: {
1167
1269
  type: 'object',
1168
1270
  required: ['claim'],
1169
1271
  properties: {
1170
- claim: { type: 'string', description: 'The claim text to verify' },
1272
+ claim: { type: 'string', description: 'The claim text to verify (e.g. "the row count is 1,284" or "all tests pass")' },
1171
1273
  goalContract: GOAL_CONTRACT_SCHEMA,
1172
1274
  },
1173
1275
  },
@@ -1223,6 +1325,19 @@ const TOOLS = [
1223
1325
  additionalProperties: true,
1224
1326
  description: 'Optional per-action budget controls: maxTokensPerAction, remainingTokens, maxCostUsdPerAction, remainingCostUsd, maxParallelBranches',
1225
1327
  },
1328
+ financialControl: {
1329
+ type: 'object',
1330
+ additionalProperties: false,
1331
+ description: 'Single-use purchase authorization scope from the append-only financial ledger.',
1332
+ properties: {
1333
+ requisitionId: { type: 'string' },
1334
+ reservationId: { type: 'string' },
1335
+ actionId: { type: 'string' },
1336
+ vendor: { type: 'string' },
1337
+ purpose: { type: 'string' },
1338
+ sourceMessageId: { type: 'string' },
1339
+ },
1340
+ },
1226
1341
  workflowPattern: {
1227
1342
  type: 'string',
1228
1343
  enum: ['single_action', 'chaining', 'routing', 'parallelization', 'evaluator-optimizer', 'agent'],
@@ -1285,6 +1400,27 @@ const TOOLS = [
1285
1400
  },
1286
1401
  },
1287
1402
  }),
1403
+ readOnlyTool({
1404
+ name: 'gate_check',
1405
+ // Harnesses with a native pre-tool hook (Claude Code, Codex, Gemini, Forge) get hard
1406
+ // enforcement and never need this. MCP-only harnesses (Cline, Cursor, OpenCode) have no
1407
+ // interception point, so this exposes the SAME gates engine as a tool the agent calls
1408
+ // before acting. adapters/cline/.clinerules has instructed agents to call
1409
+ // `thumbgate.gate_check` since the adapter shipped — but the tool did not exist, so
1410
+ // that enforcement was inert. This makes the documented contract real.
1411
+ description: 'Evaluate a proposed tool call against ThumbGate policy BEFORE executing it. Returns decision "block" (do not run the action; surface the reason) or "allow". Use this when about to run a shell command, write/edit a file, or take any irreversible action.',
1412
+ inputSchema: {
1413
+ type: 'object',
1414
+ required: ['tool_name'],
1415
+ properties: {
1416
+ tool_name: { type: 'string', description: 'The tool about to be invoked (e.g. Bash, Write, Edit)' },
1417
+ tool_input: {
1418
+ type: 'object',
1419
+ description: 'The proposed arguments, e.g. { "command": "rm -rf /" } for Bash or { "file_path": "..." } for Write',
1420
+ },
1421
+ },
1422
+ },
1423
+ }),
1288
1424
  readOnlyTool({
1289
1425
  name: 'gate_stats',
1290
1426
  description: 'Get gate enforcement statistics -- blocked count, warned count, top gates',
@@ -1609,13 +1745,13 @@ const TOOLS = [
1609
1745
  }),
1610
1746
  readOnlyTool({
1611
1747
  name: 'require_evidence_for_claim',
1612
- description: 'Leader-Agent completion gate. Before any agent declares done/fixed/shipped/resolved, require tracked evidence. Blocking response when evidence missing; callers honor the blocking flag to stop completion claims.',
1748
+ description: 'Leader-Agent completion gate. Before any agent declares done/fixed/shipped/resolved, require tracked session evidence AND recheck parseable factual claims (row counts, file metrics, versions) against configured verifiers. Blocking response when evidence is missing or a factual claim mismatches; callers honor the blocking flag to stop completion claims.',
1613
1749
  inputSchema: {
1614
1750
  type: 'object',
1615
1751
  required: ['claim'],
1616
1752
  properties: {
1617
- claim: { type: 'string', description: 'The completion claim text to verify (e.g. "Fix shipped", "Tests passing")' },
1618
- mode: { type: 'string', enum: ['blocking', 'advisory'], description: 'blocking (default) returns blocking=true when evidence missing; advisory returns blocking=false' },
1753
+ claim: { type: 'string', description: 'The completion claim text to verify (e.g. "Fix shipped", "the row count is 1,284")' },
1754
+ mode: { type: 'string', enum: ['blocking', 'advisory'], description: 'blocking (default) returns blocking=true when evidence missing or factual claim mismatches; advisory returns blocking=false' },
1619
1755
  sessionId: { type: 'string', description: 'Optional session id to associate with the gate decision' },
1620
1756
  goalContract: GOAL_CONTRACT_SCHEMA,
1621
1757
  },