thumbgate 1.35.0 → 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 (196) 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 +336 -3
  24. package/bin/futureagi-bridge +9 -0
  25. package/config/gate-templates.json +581 -4
  26. package/config/gates/actor-critic-audit.json +34 -0
  27. package/config/gates/default.json +9 -3
  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 +6 -0
  34. package/config/model-candidates.json +312 -29
  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 +390 -148
  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/billing.js +1 -1
  89. package/scripts/broker-execution-receipts.js +719 -0
  90. package/scripts/budget-aware-gates-proof.js +423 -0
  91. package/scripts/claude-feedback-sync.js +29 -3
  92. package/scripts/claw-harness-production.js +237 -0
  93. package/scripts/cli-schema.js +163 -1
  94. package/scripts/codex-runbook-flywheel.js +318 -0
  95. package/scripts/context-footprint.js +186 -0
  96. package/scripts/contextfs.js +143 -61
  97. package/scripts/dashboard.js +251 -32
  98. package/scripts/deepseek-v4-runtime-guardrails.js +72 -6
  99. package/scripts/docker-sandbox-planner.js +18 -0
  100. package/scripts/double-blind-eval-protocol.js +252 -0
  101. package/scripts/edotenv-rl-gateway.js +259 -0
  102. package/scripts/ensure-production-search-corpus.js +162 -0
  103. package/scripts/eval-holdout.js +311 -0
  104. package/scripts/feedback-aggregate.js +21 -2
  105. package/scripts/feedback-loop.js +87 -5
  106. package/scripts/feedback-quality.js +9 -0
  107. package/scripts/file-ledger-lock.js +4 -1
  108. package/scripts/financial-control-plane.js +41 -1
  109. package/scripts/find-dormant-requires.js +118 -0
  110. package/scripts/fs-utils.js +84 -8
  111. package/scripts/gates-engine.js +810 -63
  112. package/scripts/generate-case-study-outreach.js +24 -15
  113. package/scripts/git-at-scale.js +628 -0
  114. package/scripts/governance-conflict-audit.js +1650 -0
  115. package/scripts/governance-difficulty-curriculum.js +328 -0
  116. package/scripts/graphrag-retrieval.js +275 -0
  117. package/scripts/gurobi-optimizer.js +324 -0
  118. package/scripts/gurobi_optimizer.py +485 -0
  119. package/scripts/harness-selector.js +82 -1
  120. package/scripts/hidden-entry-points.js +284 -0
  121. package/scripts/human-escalation.js +199 -1
  122. package/scripts/hybrid-feedback-context.js +152 -19
  123. package/scripts/intent-governed-execution.js +602 -0
  124. package/scripts/intervention-policy.js +123 -20
  125. package/scripts/jit-harness-compose.js +628 -0
  126. package/scripts/jsonl-watcher.js +10 -0
  127. package/scripts/lesson-embedding-index.js +95 -12
  128. package/scripts/lesson-retrieval.js +105 -19
  129. package/scripts/local-model-profile.js +19 -2
  130. package/scripts/mailer/resend-mailer.js +1 -1
  131. package/scripts/matryoshka-embedding.js +235 -0
  132. package/scripts/mcp-oauth.js +42 -4
  133. package/scripts/mcp-session-handles.js +1016 -0
  134. package/scripts/mcp-wiring-doctor.js +314 -0
  135. package/scripts/memory-firewall.js +115 -2
  136. package/scripts/memory-scope-readiness.js +299 -0
  137. package/scripts/memory-vs-rag-route.js +161 -0
  138. package/scripts/model-tier-router.js +148 -21
  139. package/scripts/nvidia-specdecode-al-doctor.js +536 -0
  140. package/scripts/openui-catalog-compose-honesty.js +593 -0
  141. package/scripts/operational-integrity.js +19 -1
  142. package/scripts/override-audit.js +213 -0
  143. package/scripts/package-manager-honesty-doctor.js +458 -0
  144. package/scripts/pr-manager.js +63 -1
  145. package/scripts/prove-herdr-adapter.js +52 -0
  146. package/scripts/prove-memory-pyramid-and-symbolic-canvas.js +95 -0
  147. package/scripts/prove-workos.js +73 -0
  148. package/scripts/provider-attestation-conformance.js +192 -0
  149. package/scripts/provider-receipt-contract.js +136 -0
  150. package/scripts/qwen38-max-cost-optimizer.js +401 -0
  151. package/scripts/radware-threat-defense.js +280 -0
  152. package/scripts/rag-embedding-identity.js +221 -0
  153. package/scripts/rag-precision-guardrails.js +112 -2
  154. package/scripts/remote-feedback-capture.js +159 -0
  155. package/scripts/research-agent-harness.js +256 -0
  156. package/scripts/rsi-safety-hillclimb.js +200 -0
  157. package/scripts/rule-sprawl.js +188 -0
  158. package/scripts/schedule-manager.js +147 -0
  159. package/scripts/self-heal.js +8 -0
  160. package/scripts/session-lease.js +415 -0
  161. package/scripts/simatree-data-governance.js +347 -0
  162. package/scripts/slo-alert-engine.js +172 -7
  163. package/scripts/solver-parity.js +539 -0
  164. package/scripts/stealth-memory-injection-gate.js +333 -0
  165. package/scripts/switchyard-router.js +366 -0
  166. package/scripts/telemetry-analytics.js +84 -27
  167. package/scripts/temporal-decay-weighting.js +138 -0
  168. package/scripts/test-all.js +165 -0
  169. package/scripts/token-savings.js +42 -0
  170. package/scripts/tool-kpi-tracker.js +108 -5
  171. package/scripts/tool-registry.js +193 -5
  172. package/scripts/universal-claim-evaluator.js +14 -2
  173. package/scripts/vector-store.js +279 -9
  174. package/scripts/workflow-notebook.js +391 -0
  175. package/scripts/workflow-sentinel.js +111 -12
  176. package/scripts/workos-production-guard.js +260 -0
  177. package/scripts/workspace-search-route.js +515 -0
  178. package/server.json +2 -2
  179. package/src/agent-identity-boundary.js +76 -0
  180. package/src/agent-retrieval-cache.js +155 -0
  181. package/src/alert-noise-ledger.js +502 -0
  182. package/src/api/server.js +724 -153
  183. package/src/git-fast-cache.js +220 -0
  184. package/src/git-wal-sync.js +156 -0
  185. package/src/hash-anchored-edit.js +82 -0
  186. package/src/hermes-platform-protocol.js +475 -0
  187. package/src/hermes-sync-plane.js +241 -0
  188. package/src/index.js +30 -1
  189. package/src/iso42001-compliance-guard.js +97 -0
  190. package/src/latency-budget.js +244 -0
  191. package/src/mcp-writeguard.js +316 -0
  192. package/src/miminions-adapter.js +106 -0
  193. package/src/pipeline-compass.js +104 -0
  194. package/src/ppl-alert-pipeline.js +284 -0
  195. package/src/rendezvous-router.js +90 -0
  196. package/src/security-questionnaire.js +195 -0
@@ -27,6 +27,200 @@ function getAuditLogPath() {
27
27
  return path.join(resolveFeedbackDir(), AUDIT_LOG_FILENAME);
28
28
  }
29
29
 
30
+ /**
31
+ * Resolve the acting non-human identity for audit attribution. Sessions and
32
+ * worktree leases export THUMBGATE_SESSION_AGENT; THUMBGATE_AGENT_ID is the
33
+ * generic override. Null when the caller cannot be attributed — audit records
34
+ * must never invent an identity.
35
+ */
36
+ function resolveAuditAgentId() {
37
+ return process.env.THUMBGATE_SESSION_AGENT
38
+ || process.env.THUMBGATE_AGENT_ID
39
+ || null;
40
+ }
41
+
42
+ // ---------------------------------------------------------------------------
43
+ // Agent identity store — registry + observed-agent stream
44
+ //
45
+ // Lives here (not in org-dashboard) because the gates-engine identity gate and
46
+ // audit attribution are public runtime surfaces, while org-dashboard stays out
47
+ // of the npm tarball. org-dashboard re-exports these for its Pro reporting.
48
+ // ---------------------------------------------------------------------------
49
+
50
+ const REGISTRY_FILENAME = 'agent-registry.jsonl';
51
+ const OBSERVED_FILENAME = 'observed-agents.jsonl';
52
+ const OBSERVED_COMPACT_BYTES = 512 * 1024;
53
+
54
+ function getRegistryPath() {
55
+ return path.join(resolveFeedbackDir(), REGISTRY_FILENAME);
56
+ }
57
+
58
+ function getObservedAgentsPath() {
59
+ return path.join(resolveFeedbackDir(), OBSERVED_FILENAME);
60
+ }
61
+
62
+ /**
63
+ * Register an agent session. Called on MCP server startup or agent bootstrap.
64
+ */
65
+ function registerAgent({ agentId, source, project, branch, metadata } = {}) {
66
+ const id = agentId || `agent_${Date.now()}_${crypto.randomUUID().slice(0, 8)}`;
67
+ const record = {
68
+ id,
69
+ registeredAt: new Date().toISOString(),
70
+ lastSeenAt: new Date().toISOString(),
71
+ source: source || 'unknown',
72
+ project: project || path.basename(process.cwd()),
73
+ branch: branch || null,
74
+ toolCalls: 0,
75
+ gateBlocks: 0,
76
+ gateWarns: 0,
77
+ metadata: { lifecycleStatus: 'active', ...(metadata || {}) },
78
+ };
79
+ const registryPath = getRegistryPath();
80
+ ensureDir(path.dirname(registryPath));
81
+ fs.appendFileSync(registryPath, JSON.stringify(record) + '\n');
82
+ return record;
83
+ }
84
+
85
+ /**
86
+ * Record agent activity — called after each tool call evaluation.
87
+ */
88
+ function recordAgentActivity(agentId, decision) {
89
+ const registryPath = getRegistryPath();
90
+ if (!fs.existsSync(registryPath)) return;
91
+ const lines = fs.readFileSync(registryPath, 'utf-8').trim().split('\n');
92
+ const updated = [];
93
+ let found = false;
94
+ for (const line of lines) {
95
+ try {
96
+ const record = JSON.parse(line);
97
+ if (record.id === agentId && !found) {
98
+ record.lastSeenAt = new Date().toISOString();
99
+ record.toolCalls = (record.toolCalls || 0) + 1;
100
+ if (decision === 'deny') record.gateBlocks = (record.gateBlocks || 0) + 1;
101
+ if (decision === 'warn') record.gateWarns = (record.gateWarns || 0) + 1;
102
+ found = true;
103
+ }
104
+ updated.push(JSON.stringify(record));
105
+ } catch {
106
+ updated.push(line);
107
+ }
108
+ }
109
+ fs.writeFileSync(registryPath, updated.join('\n') + '\n');
110
+ }
111
+
112
+ /**
113
+ * Load all registered agent sessions.
114
+ */
115
+ function loadAgentRegistry() {
116
+ const registryPath = getRegistryPath();
117
+ if (!fs.existsSync(registryPath)) return [];
118
+ const raw = fs.readFileSync(registryPath, 'utf-8').trim();
119
+ if (!raw) return [];
120
+ const records = [];
121
+ for (const line of raw.split('\n')) {
122
+ try {
123
+ records.push(JSON.parse(line));
124
+ } catch {
125
+ // Skip corrupt rows; identity checks fail open, never crash.
126
+ }
127
+ }
128
+ return records;
129
+ }
130
+
131
+ /**
132
+ * Retire an agent identity. A retired agent that keeps acting is flagged by
133
+ * the gates-engine identity gate (deny under strict enforcement).
134
+ */
135
+ function retireAgent(agentId, reason) {
136
+ const registryPath = getRegistryPath();
137
+ if (!fs.existsSync(registryPath)) return false;
138
+ const lines = fs.readFileSync(registryPath, 'utf-8').trim().split('\n');
139
+ const updated = [];
140
+ let found = false;
141
+ for (const line of lines) {
142
+ try {
143
+ const record = JSON.parse(line);
144
+ if (record.id === agentId) {
145
+ record.metadata = record.metadata || {};
146
+ record.metadata.lifecycleStatus = 'retired';
147
+ record.metadata.retiredAt = new Date().toISOString();
148
+ if (reason) record.metadata.retireReason = String(reason);
149
+ found = true;
150
+ }
151
+ updated.push(JSON.stringify(record));
152
+ } catch {
153
+ updated.push(line);
154
+ }
155
+ }
156
+ if (found) fs.writeFileSync(registryPath, updated.join('\n') + '\n');
157
+ return found;
158
+ }
159
+
160
+ /**
161
+ * Record one observation of an acting agent — the producer side of shadow-AI
162
+ * detection, called from the gates-engine evaluation path on every attributed
163
+ * tool call. Appends are plain (never lost to a busy lock); compaction runs
164
+ * only under the cross-process ledger lock so a concurrent agent's append can
165
+ * never be truncated by the read-aggregate-rewrite window.
166
+ */
167
+ function recordObservedAgent(agentId) {
168
+ const id = String(agentId || '').trim();
169
+ if (!id) return null;
170
+ const observedPath = getObservedAgentsPath();
171
+ ensureDir(path.dirname(observedPath));
172
+ const event = { id, seenAt: new Date().toISOString() };
173
+ fs.appendFileSync(observedPath, JSON.stringify(event) + '\n');
174
+ try {
175
+ if (fs.statSync(observedPath).size > OBSERVED_COMPACT_BYTES) {
176
+ const { withFileLedgerLock } = require('./file-ledger-lock');
177
+ withFileLedgerLock(observedPath + '.lock', () => {
178
+ const compacted = loadObservedAgents()
179
+ .map((row) => JSON.stringify(row))
180
+ .join('\n');
181
+ fs.writeFileSync(observedPath, compacted + '\n');
182
+ });
183
+ }
184
+ } catch {
185
+ // Busy lock or read error: skip compaction, never drop the observation.
186
+ }
187
+ return event;
188
+ }
189
+
190
+ /**
191
+ * Aggregate observation events into one row per agent id:
192
+ * { id, firstSeenAt, lastSeenAt, observations }.
193
+ */
194
+ function loadObservedAgents() {
195
+ const observedPath = getObservedAgentsPath();
196
+ if (!fs.existsSync(observedPath)) return [];
197
+ const byId = new Map();
198
+ const raw = fs.readFileSync(observedPath, 'utf-8').trim();
199
+ if (!raw) return [];
200
+ for (const line of raw.split('\n')) {
201
+ let event;
202
+ try {
203
+ event = JSON.parse(line);
204
+ } catch {
205
+ continue;
206
+ }
207
+ const id = String(event.id || '').trim();
208
+ if (!id) continue;
209
+ const seenAt = event.seenAt || event.lastSeenAt || new Date().toISOString();
210
+ const row = byId.get(id) || {
211
+ id,
212
+ firstSeenAt: event.firstSeenAt || seenAt,
213
+ lastSeenAt: seenAt,
214
+ observations: 0,
215
+ };
216
+ if (seenAt < row.firstSeenAt) row.firstSeenAt = seenAt;
217
+ if (seenAt > row.lastSeenAt) row.lastSeenAt = seenAt;
218
+ row.observations += Number(event.observations) > 0 ? Number(event.observations) : 1;
219
+ byId.set(id, row);
220
+ }
221
+ return [...byId.values()];
222
+ }
223
+
30
224
 
31
225
  // ---------------------------------------------------------------------------
32
226
  // Core audit record
@@ -53,6 +247,7 @@ function recordAuditEvent(params = {}) {
53
247
  timestamp: new Date().toISOString(),
54
248
  toolName: params.toolName || 'unknown',
55
249
  toolInput: sanitizeToolInput(params.toolInput || {}),
250
+ agentId: params.agentId || resolveAuditAgentId(),
56
251
  decision: params.decision || 'allow',
57
252
  gateId: params.gateId || null,
58
253
  message: params.message || null,
@@ -61,6 +256,13 @@ function recordAuditEvent(params = {}) {
61
256
  source: params.source || 'gates-engine',
62
257
  };
63
258
 
259
+ // Typed override payload (see scripts/override-audit.js). Carried verbatim so
260
+ // an override is filterable by decision === 'override' rather than having to
261
+ // be inferred from toolName, which cannot distinguish it from a normal call.
262
+ if (params.override && typeof params.override === 'object') {
263
+ record.override = params.override;
264
+ }
265
+
64
266
  // Safe stringify: never let circular/toxic tool inputs crash the gate path
65
267
  // (Antithesis-style invariant: evaluation + audit must not throw).
66
268
  let line;
@@ -353,6 +555,16 @@ module.exports = {
353
555
  recordAuditEvent,
354
556
  auditToFeedback,
355
557
  readAuditLog,
558
+ registerAgent,
559
+ recordAgentActivity,
560
+ loadAgentRegistry,
561
+ retireAgent,
562
+ recordObservedAgent,
563
+ loadObservedAgents,
564
+ getRegistryPath,
565
+ getObservedAgentsPath,
566
+ REGISTRY_FILENAME,
567
+ OBSERVED_FILENAME,
356
568
  auditStats,
357
569
  latencyStats,
358
570
  skillAdherence,
@@ -110,7 +110,7 @@ const CONFIG = {
110
110
  },
111
111
  RESEND_API_KEY: process.env.RESEND_API_KEY || process.env.THUMBGATE_RESEND_API_KEY || '',
112
112
  TRIAL_EMAIL_FROM: process.env.THUMBGATE_TRIAL_EMAIL_FROM || process.env.RESEND_FROM_EMAIL || process.env.RESEND_FROM || 'onboarding@resend.dev',
113
- TRIAL_EMAIL_REPLY_TO: process.env.THUMBGATE_TRIAL_EMAIL_REPLY_TO || 'igor.ganapolsky@gmail.com',
113
+ TRIAL_EMAIL_REPLY_TO: process.env.THUMBGATE_TRIAL_EMAIL_REPLY_TO || 'support@thumbgate.ai',
114
114
  CREDIT_PACKS: {}
115
115
  };
116
116