thumbgate 1.34.3 → 1.37.1

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 (200) hide show
  1. package/.agents/skills/cyberstrike-compare-not-clone/SKILL.md +36 -0
  2. package/.agents/skills/gitlab-sandbox-allowlist-not-trust/SKILL.md +77 -0
  3. package/.agents/skills/jit-harness-compare-not-clone/SKILL.md +34 -0
  4. package/.agents/skills/openui-catalog-compose-honesty/SKILL.md +64 -0
  5. package/.agents/skills/zvec-grep-compare-not-clone/SKILL.md +34 -0
  6. package/.claude-plugin/plugin.json +1 -1
  7. package/.well-known/llms.txt +1 -0
  8. package/.well-known/mcp/server-card.json +1 -1
  9. package/CONTRIBUTING.md +95 -0
  10. package/README.md +195 -632
  11. package/THIRD_PARTY_NOTICES.md +89 -0
  12. package/adapters/claude/.mcp.json +2 -2
  13. package/adapters/forge/forge.yaml +3 -3
  14. package/adapters/future-agi/.mcp.json +8 -0
  15. package/adapters/future-agi/FUTURE_AGI.md +23 -0
  16. package/adapters/future-agi/config.toml +3 -0
  17. package/adapters/future-agi/future-agi-bridge.js +9 -0
  18. package/adapters/future-agi/opencode.json +8 -0
  19. package/adapters/herdr/herdr-plugin.toml +18 -0
  20. package/adapters/mcp/server-stdio.js +238 -25
  21. package/adapters/opencode/opencode.json +1 -1
  22. package/adapters/workos/WORKOS.md +52 -0
  23. package/bin/cli.js +373 -5
  24. package/bin/futureagi-bridge +9 -0
  25. package/config/gate-templates.json +653 -4
  26. package/config/gates/actor-critic-audit.json +34 -0
  27. package/config/gates/default.json +21 -2
  28. package/config/gates/five-walls-governance.json +34 -0
  29. package/config/gates/future-agi-guardrails.json +34 -0
  30. package/config/gates/radware-threat-defense-2026.json +61 -0
  31. package/config/gates/simatree-data-governance.json +33 -0
  32. package/config/mcp-allowlists.json +4 -0
  33. package/config/merge-quality-checks.json +10 -1
  34. package/config/model-candidates.json +382 -24
  35. package/config/model-tiers.json +18 -0
  36. package/config/post-deploy-marketing-pages.json +10 -0
  37. package/config/progressive/01-wire-only.json +11 -0
  38. package/config/progressive/02-dashboard-empty-ok.json +10 -0
  39. package/config/progressive/03-one-lesson.json +10 -0
  40. package/config/progressive/04-warn-fires.json +11 -0
  41. package/config/progressive/05-strict-optional.json +11 -0
  42. package/config/progressive/README.md +15 -0
  43. package/config/schemas/broker-execution-receipt.schema.json +139 -0
  44. package/config/schemas/provider-execution-attestation-v1.schema.json +58 -0
  45. package/conformance/provider-attestation/vectors.json +320 -0
  46. package/docs/specs/provider-execution-attestation-v1.md +69 -0
  47. package/openapi/openapi.yaml +15 -0
  48. package/package.json +401 -147
  49. package/public/about.html +2 -2
  50. package/public/ai-malpractice-prevention.html +7 -7
  51. package/public/blog/a-10-dollar-vps-is-not-a-computer.html +143 -0
  52. package/public/blog/a-receipt-is-not-world-state.html +388 -0
  53. package/public/blog/git-at-agent-scale.html +374 -0
  54. package/public/blog/no-llm-in-the-gate.html +133 -0
  55. package/public/blog.html +80 -0
  56. package/public/case-studies.html +16 -1
  57. package/public/compare.html +28 -0
  58. package/public/diagnostic.html +216 -7
  59. package/public/docs/connectors.html +39 -0
  60. package/public/federal.html +2 -2
  61. package/public/founders.html +639 -0
  62. package/public/index.html +87 -9
  63. package/public/install.html +8 -8
  64. package/public/learn.html +39 -0
  65. package/public/numbers.html +2 -2
  66. package/public/peter.html +310 -0
  67. package/public/platform-partners.html +119 -0
  68. package/public/pricing.html +24 -3
  69. package/public/privacy.html +117 -0
  70. package/public/pro.html +17 -0
  71. package/public/support.html +62 -0
  72. package/public/terms.html +130 -0
  73. package/public/third-party-notices.html +95 -0
  74. package/public/yt.html +351 -0
  75. package/scripts/action-receipts.js +133 -3
  76. package/scripts/adaptive-governance-arena.js +349 -0
  77. package/scripts/admin-override.js +205 -0
  78. package/scripts/agent-action-inventory.js +869 -0
  79. package/scripts/agent-audit-trace.js +42 -2
  80. package/scripts/agent-egress-policy.js +1117 -0
  81. package/scripts/agent-memory-lifecycle.js +141 -2
  82. package/scripts/agent-operations-planner.js +441 -1
  83. package/scripts/agent-readiness.js +68 -0
  84. package/scripts/agent-security-central.js +647 -0
  85. package/scripts/allowlist-bridge-honesty.js +417 -0
  86. package/scripts/async-job-runner.js +102 -11
  87. package/scripts/audit-trail.js +212 -0
  88. package/scripts/auto-promote-gates.js +178 -27
  89. package/scripts/billing.js +1 -1
  90. package/scripts/broker-execution-receipts.js +719 -0
  91. package/scripts/budget-aware-gates-proof.js +423 -0
  92. package/scripts/claude-feedback-sync.js +29 -3
  93. package/scripts/claw-harness-production.js +237 -0
  94. package/scripts/cli-progress.js +111 -0
  95. package/scripts/cli-schema.js +163 -1
  96. package/scripts/codex-runbook-flywheel.js +318 -0
  97. package/scripts/context-footprint.js +186 -0
  98. package/scripts/contextfs.js +143 -61
  99. package/scripts/dashboard-limits.js +27 -0
  100. package/scripts/dashboard.js +279 -9
  101. package/scripts/deepseek-v4-runtime-guardrails.js +72 -6
  102. package/scripts/docker-sandbox-planner.js +18 -0
  103. package/scripts/double-blind-eval-protocol.js +252 -0
  104. package/scripts/edotenv-rl-gateway.js +259 -0
  105. package/scripts/ensure-production-search-corpus.js +162 -0
  106. package/scripts/eval-holdout.js +311 -0
  107. package/scripts/feedback-aggregate.js +21 -2
  108. package/scripts/feedback-loop.js +87 -5
  109. package/scripts/feedback-quality.js +9 -0
  110. package/scripts/file-ledger-lock.js +4 -1
  111. package/scripts/financial-control-plane.js +41 -1
  112. package/scripts/find-dormant-requires.js +118 -0
  113. package/scripts/fs-utils.js +84 -8
  114. package/scripts/gate-stats.js +2 -2
  115. package/scripts/gates-engine.js +859 -58
  116. package/scripts/generate-case-study-outreach.js +24 -15
  117. package/scripts/git-at-scale.js +628 -0
  118. package/scripts/governance-conflict-audit.js +1650 -0
  119. package/scripts/governance-difficulty-curriculum.js +328 -0
  120. package/scripts/graphrag-retrieval.js +275 -0
  121. package/scripts/gurobi-optimizer.js +324 -0
  122. package/scripts/gurobi_optimizer.py +485 -0
  123. package/scripts/harness-selector.js +82 -1
  124. package/scripts/hidden-entry-points.js +284 -0
  125. package/scripts/human-escalation.js +199 -1
  126. package/scripts/hybrid-feedback-context.js +152 -19
  127. package/scripts/intent-governed-execution.js +602 -0
  128. package/scripts/intervention-policy.js +123 -20
  129. package/scripts/jit-harness-compose.js +628 -0
  130. package/scripts/jsonl-watcher.js +10 -0
  131. package/scripts/lesson-embedding-index.js +95 -12
  132. package/scripts/lesson-retrieval.js +105 -19
  133. package/scripts/local-model-profile.js +19 -2
  134. package/scripts/mailer/resend-mailer.js +1 -1
  135. package/scripts/matryoshka-embedding.js +235 -0
  136. package/scripts/mcp-oauth.js +42 -4
  137. package/scripts/mcp-session-handles.js +1016 -0
  138. package/scripts/mcp-wiring-doctor.js +314 -0
  139. package/scripts/memory-firewall.js +115 -2
  140. package/scripts/memory-scope-readiness.js +299 -0
  141. package/scripts/memory-vs-rag-route.js +161 -0
  142. package/scripts/model-tier-router.js +148 -21
  143. package/scripts/nvidia-specdecode-al-doctor.js +536 -0
  144. package/scripts/openui-catalog-compose-honesty.js +593 -0
  145. package/scripts/operational-integrity.js +19 -1
  146. package/scripts/override-audit.js +213 -0
  147. package/scripts/package-manager-honesty-doctor.js +458 -0
  148. package/scripts/pr-manager.js +63 -1
  149. package/scripts/prove-herdr-adapter.js +52 -0
  150. package/scripts/prove-memory-pyramid-and-symbolic-canvas.js +95 -0
  151. package/scripts/prove-workos.js +73 -0
  152. package/scripts/provider-attestation-conformance.js +192 -0
  153. package/scripts/provider-receipt-contract.js +136 -0
  154. package/scripts/qwen38-max-cost-optimizer.js +401 -0
  155. package/scripts/radware-threat-defense.js +280 -0
  156. package/scripts/rag-embedding-identity.js +221 -0
  157. package/scripts/rag-precision-guardrails.js +112 -2
  158. package/scripts/remote-feedback-capture.js +159 -0
  159. package/scripts/research-agent-harness.js +256 -0
  160. package/scripts/rsi-safety-hillclimb.js +200 -0
  161. package/scripts/rule-sprawl.js +188 -0
  162. package/scripts/schedule-manager.js +147 -0
  163. package/scripts/self-heal.js +8 -0
  164. package/scripts/session-lease.js +415 -0
  165. package/scripts/simatree-data-governance.js +347 -0
  166. package/scripts/slo-alert-engine.js +172 -7
  167. package/scripts/solver-parity.js +539 -0
  168. package/scripts/stealth-memory-injection-gate.js +333 -0
  169. package/scripts/switchyard-router.js +366 -0
  170. package/scripts/telemetry-analytics.js +84 -27
  171. package/scripts/temporal-decay-weighting.js +138 -0
  172. package/scripts/test-all.js +165 -0
  173. package/scripts/token-savings.js +42 -0
  174. package/scripts/tool-kpi-tracker.js +108 -5
  175. package/scripts/tool-registry.js +193 -5
  176. package/scripts/universal-claim-evaluator.js +14 -2
  177. package/scripts/vector-store.js +279 -9
  178. package/scripts/workflow-notebook.js +391 -0
  179. package/scripts/workflow-sentinel.js +111 -12
  180. package/scripts/workos-production-guard.js +260 -0
  181. package/scripts/workspace-search-route.js +515 -0
  182. package/server.json +2 -2
  183. package/src/agent-identity-boundary.js +76 -0
  184. package/src/agent-retrieval-cache.js +155 -0
  185. package/src/alert-noise-ledger.js +502 -0
  186. package/src/api/server.js +802 -185
  187. package/src/git-fast-cache.js +220 -0
  188. package/src/git-wal-sync.js +156 -0
  189. package/src/hash-anchored-edit.js +82 -0
  190. package/src/hermes-platform-protocol.js +475 -0
  191. package/src/hermes-sync-plane.js +241 -0
  192. package/src/index.js +30 -1
  193. package/src/iso42001-compliance-guard.js +97 -0
  194. package/src/latency-budget.js +244 -0
  195. package/src/mcp-writeguard.js +316 -0
  196. package/src/miminions-adapter.js +106 -0
  197. package/src/pipeline-compass.js +104 -0
  198. package/src/ppl-alert-pipeline.js +284 -0
  199. package/src/rendezvous-router.js +90 -0
  200. package/src/security-questionnaire.js +195 -0
@@ -6,15 +6,32 @@ const path = require('path');
6
6
  const { resolveFeedbackDir } = require('./feedback-paths');
7
7
  const { getDecisionLogPath, readDecisionLog, collapseDecisionTimeline } = require('./decision-journal');
8
8
  const { requireLearnedModelsEntitlement } = require('./entitlement');
9
+ const {
10
+ readTextTail,
11
+ DEFAULT_JSONL_TAIL_BYTES,
12
+ DEFAULT_JSONL_TAIL_ENTRIES,
13
+ } = require('./fs-utils');
9
14
 
10
15
  const LABELS = ['allow', 'recall', 'verify', 'warn', 'deny'];
11
16
  const DAY_MS = 24 * 60 * 60 * 1000;
12
17
  const DEFAULT_HOLDOUT_RATIO = 0.2;
13
18
  const MIN_HOLDOUT_EXAMPLES = 5;
19
+ const MIN_HOLDOUT_ACCURACY = 0.5;
14
20
  const MIN_TRAINING_EXAMPLES = 8;
15
21
  const MAX_TEXT_TOKENS = 24;
16
22
  const MODEL_FILENAME = 'intervention-policy.json';
17
23
 
24
+ // Training reads a much larger window than the dashboard.
25
+ //
26
+ // WHY: the dashboard default is a 4 MiB tail (DEFAULT_JSONL_TAIL_BYTES) so
27
+ // generateDashboard() stays inside its assembly budget. Reusing that tail for
28
+ // trainAndPersistInterventionPolicy() would silently retrain — and overwrite
29
+ // the persisted model — on only the newest 4 MiB of history. Training gets its
30
+ // own, far larger, still-bounded budget, and records what it actually saw so a
31
+ // bounded retrain is visible in the model instead of silent.
32
+ const TRAINING_TAIL_BYTES = 64 * 1024 * 1024;
33
+ const TRAINING_TAIL_ENTRIES = 500_000;
34
+
18
35
  const SURFACE_RULES = [
19
36
  { key: 'policy', pattern: /^(?:AGENTS\.md|CLAUDE(?:\.local)?\.md|GEMINI\.md|config\/gates\/|config\/mcp-allowlists\.json|scripts\/tool-registry\.js)/i },
20
37
  { key: 'release', pattern: /^(?:package\.json|package-lock\.json|server\.json|\.github\/workflows\/|scripts\/publish-decision\.js|scripts\/pr-manager\.js)/i },
@@ -36,20 +53,50 @@ function modelPathFor(feedbackDir) {
36
53
  return path.join(resolveFeedbackDir({ feedbackDir }), MODEL_FILENAME);
37
54
  }
38
55
 
39
- function readJSONL(filePath) {
40
- if (!fs.existsSync(filePath)) return [];
41
- const raw = fs.readFileSync(filePath, 'utf8').trim();
42
- if (!raw) return [];
43
- return raw
44
- .split('\n')
45
- .map((line) => {
46
- try {
47
- return JSON.parse(line);
48
- } catch {
49
- return null;
50
- }
51
- })
52
- .filter(Boolean);
56
+ // Bounded JSONL read.
57
+ //
58
+ // WHY: this used to be an unbounded fs.readFileSync(). getInterventionPolicySummary()
59
+ // is called from generateDashboard(), so once production feedback-log.jsonl passed
60
+ // V8's max string length the read threw
61
+ // "Cannot create a string longer than 0x1fffffe8 characters"
62
+ // which escaped assembly and 503'd /v1/dashboard ("Dashboard data too large").
63
+ // scripts/dashboard.js already tail-capped its own readers; this sibling reader on
64
+ // the same call path was missed. Bound it AND never let one bad log throw.
65
+ function readJSONLBounded(filePath, options = {}) {
66
+ const empty = { entries: [], truncated: false, size: 0 };
67
+ if (!fs.existsSync(filePath)) return empty;
68
+ const requestedBytes = Number(options.maxBytes);
69
+ const requestedEntries = Number(options.maxEntries);
70
+ const maxBytes = requestedBytes > 0 ? requestedBytes : DEFAULT_JSONL_TAIL_BYTES;
71
+ const maxEntries = requestedEntries > 0 ? requestedEntries : DEFAULT_JSONL_TAIL_ENTRIES;
72
+ let tail;
73
+ try {
74
+ tail = readTextTail(filePath, maxBytes);
75
+ } catch {
76
+ return empty;
77
+ }
78
+ const raw = tail.text;
79
+ if (!raw?.trim()) return { entries: [], truncated: Boolean(tail.truncated), size: tail.size || 0 };
80
+ const lines = raw.trim().split('\n');
81
+ const start = Math.max(0, lines.length - maxEntries);
82
+ const entries = [];
83
+ for (let i = start; i < lines.length; i += 1) {
84
+ if (!lines[i]) continue;
85
+ try {
86
+ const parsed = JSON.parse(lines[i]);
87
+ if (parsed) entries.push(parsed);
88
+ } catch { /* skip malformed line */ }
89
+ }
90
+ return {
91
+ entries,
92
+ // Truncated by the byte tail, or by the per-file entry cap.
93
+ truncated: Boolean(tail.truncated) || start > 0,
94
+ size: tail.size || 0,
95
+ };
96
+ }
97
+
98
+ function readJSONL(filePath, options = {}) {
99
+ return readJSONLBounded(filePath, options).entries;
53
100
  }
54
101
 
55
102
  function safeRate(numerator, denominator) {
@@ -373,11 +420,33 @@ function buildDecisionExample(action) {
373
420
  };
374
421
  }
375
422
 
376
- function buildExamplesFromFeedbackDir(feedbackDir) {
423
+ function buildExamplesFromFeedbackDir(feedbackDir, options = {}) {
377
424
  const resolvedDir = resolveFeedbackDir({ feedbackDir });
378
- const feedbackEntries = readJSONL(path.join(resolvedDir, 'feedback-log.jsonl'));
379
- const auditEntries = readJSONL(path.join(resolvedDir, 'audit-trail.jsonl'));
380
- const diagnosticEntries = readJSONL(path.join(resolvedDir, 'diagnostic-log.jsonl'));
425
+ // Callers pick their budget explicitly. The dashboard keeps the cheap default
426
+ // tail; training passes TRAINING_TAIL_* so a retrain is not restricted to the
427
+ // dashboard's 4 MiB view of history.
428
+ const readOptions = {
429
+ maxBytes: Number(options.maxBytes) > 0 ? Number(options.maxBytes) : DEFAULT_JSONL_TAIL_BYTES,
430
+ maxEntries: Number(options.maxEntries) > 0 ? Number(options.maxEntries) : DEFAULT_JSONL_TAIL_ENTRIES,
431
+ };
432
+ const feedbackRead = readJSONLBounded(path.join(resolvedDir, 'feedback-log.jsonl'), readOptions);
433
+ const auditRead = readJSONLBounded(path.join(resolvedDir, 'audit-trail.jsonl'), readOptions);
434
+ const diagnosticRead = readJSONLBounded(path.join(resolvedDir, 'diagnostic-log.jsonl'), readOptions);
435
+ const feedbackEntries = feedbackRead.entries;
436
+ const auditEntries = auditRead.entries;
437
+ const diagnosticEntries = diagnosticRead.entries;
438
+ const truncatedSources = [
439
+ feedbackRead.truncated ? 'feedback' : null,
440
+ auditRead.truncated ? 'audit' : null,
441
+ diagnosticRead.truncated ? 'diagnostic' : null,
442
+ ].filter(Boolean);
443
+ const readWindow = {
444
+ bounded: true,
445
+ maxBytes: readOptions.maxBytes,
446
+ maxEntries: readOptions.maxEntries,
447
+ truncatedSources,
448
+ complete: truncatedSources.length === 0,
449
+ };
381
450
  const decisionEntries = readDecisionLog(getDecisionLogPath(resolvedDir));
382
451
  const decisions = collapseDecisionTimeline(decisionEntries);
383
452
 
@@ -416,6 +485,7 @@ function buildExamplesFromFeedbackDir(feedbackDir) {
416
485
  return {
417
486
  examples,
418
487
  sourceCounts,
488
+ readWindow,
419
489
  };
420
490
  }
421
491
 
@@ -590,15 +660,23 @@ function loadInterventionPolicy(feedbackDir) {
590
660
 
591
661
  function trainAndPersistInterventionPolicy(feedbackDir, options = {}) {
592
662
  const resolvedDir = resolveFeedbackDir({ feedbackDir });
593
- const { examples, sourceCounts } = buildExamplesFromFeedbackDir(resolvedDir);
663
+ // Retraining overwrites the persisted model, so it must not inherit the
664
+ // dashboard's 4 MiB tail. Read the far larger (still bounded) training window
665
+ // and persist what was actually observed.
666
+ const { examples, sourceCounts, readWindow } = buildExamplesFromFeedbackDir(resolvedDir, {
667
+ maxBytes: Number(options.maxBytes) > 0 ? Number(options.maxBytes) : TRAINING_TAIL_BYTES,
668
+ maxEntries: Number(options.maxEntries) > 0 ? Number(options.maxEntries) : TRAINING_TAIL_ENTRIES,
669
+ });
594
670
  const model = trainInterventionPolicy(examples, options);
595
671
  model.sourceCounts = sourceCounts;
672
+ model.trainingWindow = readWindow;
596
673
  const modelPath = saveInterventionPolicy(model, resolvedDir);
597
674
  return {
598
675
  model,
599
676
  modelPath,
600
677
  examples,
601
678
  sourceCounts,
679
+ readWindow,
602
680
  };
603
681
  }
604
682
 
@@ -661,6 +739,21 @@ function getInterventionRecommendation(params = {}, options = {}) {
661
739
  };
662
740
  }
663
741
 
742
+ if (
743
+ model.metrics &&
744
+ Number(model.metrics.holdoutSize || 0) >= MIN_HOLDOUT_EXAMPLES &&
745
+ Number(model.metrics.holdoutAccuracy || 0) < MIN_HOLDOUT_ACCURACY
746
+ ) {
747
+ return {
748
+ enabled: false,
749
+ reason: 'degenerate_holdout_accuracy',
750
+ holdoutAccuracy: Number(model.metrics.holdoutAccuracy || 0),
751
+ holdoutSize: Number(model.metrics.holdoutSize || 0),
752
+ exampleCount: Number(model.exampleCount || 0),
753
+ candidate,
754
+ };
755
+ }
756
+
664
757
  const prediction = scoreExample(model, candidate.tokens);
665
758
  return {
666
759
  enabled: true,
@@ -707,7 +800,9 @@ function getInterventionPolicySummary(feedbackDir, options = {}) {
707
800
  label: 'intervention-policy summary',
708
801
  });
709
802
  const resolvedDir = resolveFeedbackDir({ feedbackDir });
710
- const { examples, sourceCounts } = buildExamplesFromFeedbackDir(resolvedDir);
803
+ // Dashboard path: keep the cheap default tail so generateDashboard() stays
804
+ // inside its assembly budget.
805
+ const { examples, sourceCounts, readWindow } = buildExamplesFromFeedbackDir(resolvedDir);
711
806
  const model = loadInterventionPolicy(resolvedDir) || trainInterventionPolicy(examples);
712
807
  const labelCounts = Object.assign({}, model.labelCounts || {});
713
808
  const daily = computeDailySeries(examples, options.dayCount || 14);
@@ -727,6 +822,11 @@ function getInterventionPolicySummary(feedbackDir, options = {}) {
727
822
  labelCounts,
728
823
  metrics: model.metrics || {},
729
824
  sourceCounts,
825
+ // Bounded-read provenance. `readWindow` describes what THIS summary read
826
+ // (dashboard tail); `trainingWindow` describes what the persisted model was
827
+ // actually trained on. Neither is a lifetime read.
828
+ readWindow,
829
+ trainingWindow: model.trainingWindow || null,
730
830
  topTokens: model.topTokens || {},
731
831
  daily,
732
832
  recent,
@@ -740,6 +840,8 @@ function getInterventionPolicySummary(feedbackDir, options = {}) {
740
840
  module.exports = {
741
841
  LABELS,
742
842
  MIN_TRAINING_EXAMPLES,
843
+ TRAINING_TAIL_BYTES,
844
+ TRAINING_TAIL_ENTRIES,
743
845
  buildExamplesFromFeedbackDir,
744
846
  buildRuntimeCandidate,
745
847
  createEmptyModel,
@@ -749,6 +851,7 @@ module.exports = {
749
851
  modelPathFor,
750
852
  predictIntervention: scoreExample,
751
853
  readJSONL,
854
+ readJSONLBounded,
752
855
  saveInterventionPolicy,
753
856
  trainAndPersistInterventionPolicy,
754
857
  trainInterventionPolicy,