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
@@ -0,0 +1,318 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Codex Runbook Flywheel — ThumbGate steal of OpenAI's "Automating repetitive
5
+ * work at OpenAI with Codex" workflow (developers.openai.com blog).
6
+ *
7
+ * The episode's loop, verbatim in spirit:
8
+ * run the workflow -> document it (commands, results, dead ends,
9
+ * decisions) -> the next run reuses what earlier runs learned.
10
+ *
11
+ * Four enforcement primitives, all deterministic:
12
+ *
13
+ * 1. Plan-before-act. Codex writes the plan into the notebook and WAITS
14
+ * for approval before executing. -> newRunbook() starts at 'plan';
15
+ * execute() refuses to run without an approved plan.
16
+ *
17
+ * 2. Consequential choices need human judgment. Automatic approval review
18
+ * handles eligible actions WITHOUT changing permission boundaries.
19
+ * -> autoReview() marks only bounded, reversible actions eligible;
20
+ * consequential ones stay on the human queue.
21
+ *
22
+ * 3. Capture decisions that would otherwise vanish into chat history:
23
+ * which option was chosen, why, what to do differently next time.
24
+ * -> captureDecision() appends to a per-workflow decision log.
25
+ *
26
+ * 4. Cheap discovery for the next run: a companion index over past
27
+ * runbooks (the *.index.md analog), searchable by workflow name.
28
+ * -> buildIndex() / discoverContext().
29
+ */
30
+
31
+ const RUN_STATES = Object.freeze(['plan', 'approved', 'running', 'done', 'blocked']);
32
+
33
+ const CONSEQUENTIAL = Object.freeze([
34
+ 'payment', 'external-email', 'production-deploy', 'delete', 'permission-change', 'publish',
35
+ ]);
36
+
37
+ const ALLOWED_ACTIONS = Object.freeze([
38
+ 'read-file', 'list-files', 'grep', 'search', 'read-notes',
39
+ 'list-models', 'estimate-cost', 'check-quota',
40
+ ]);
41
+
42
+ /**
43
+ * Create a runbook. Starts at the plan stage — execution is impossible until
44
+ * a human approves. Mirrors "wait for me to review and approve the plan."
45
+ */
46
+ function newRunbook(workflow, goal) {
47
+ if (!workflow || !goal) {
48
+ throw new Error('runbook needs a workflow name and a goal');
49
+ }
50
+ return {
51
+ id: require('crypto').randomUUID(),
52
+ workflow,
53
+ goal,
54
+ state: 'plan',
55
+ plan: [],
56
+ decisions: [],
57
+ steps: [],
58
+ deadEnds: [],
59
+ createdAt: new Date().toISOString(),
60
+ };
61
+ }
62
+
63
+ /**
64
+ * Normalize a step to its stable identifier. String steps are used directly.
65
+ * Object steps must have an `id` property; otherwise approval is rejected.
66
+ * This prevents the approved-snapshot and executeStep from disagreeing due
67
+ * to object reference identity.
68
+ */
69
+ function stepId(step) {
70
+ if (typeof step === 'string') return step.trim() || null;
71
+ if (step && typeof step === 'object' && typeof step.id === 'string' && step.id.trim()) {
72
+ return step.id.trim();
73
+ }
74
+ return null;
75
+ }
76
+
77
+ /**
78
+ * Record the plan and approve it. Approval is an explicit human act.
79
+ * Steps are normalized to immutable identifiers so that executeStep can
80
+ * match against the approved plan without relying on object reference identity.
81
+ */
82
+ function approvePlan(runbook, plan, approver) {
83
+ if (runbook.state !== 'plan') {
84
+ return { ok: false, reason: `cannot approve from state "${runbook.state}"` };
85
+ }
86
+ if (!Array.isArray(plan) || plan.length === 0) {
87
+ return { ok: false, reason: 'an empty plan cannot be approved' };
88
+ }
89
+ if (!approver || typeof approver !== 'string' || !approver.trim()) {
90
+ return { ok: false, reason: 'approval requires a non-empty, trimmed string approver' };
91
+ }
92
+ // Normalize each step to a stable identifier. Object entries without a
93
+ // usable `id` are rejected rather than silently cloned by reference.
94
+ const normalized = [];
95
+ for (const s of plan) {
96
+ const id = stepId(s);
97
+ if (id === null) {
98
+ return { ok: false, reason: `step ${JSON.stringify(s)} has no stable id — reject or assign one` };
99
+ }
100
+ normalized.push(id);
101
+ }
102
+ runbook.approvedBy = approver.trim();
103
+ runbook.approvedPlan = Object.freeze(normalized);
104
+ runbook.state = 'approved';
105
+ runbook.approvedAt = new Date().toISOString();
106
+ return { ok: true, state: runbook.state };
107
+ }
108
+
109
+ /**
110
+ * Automatic approval review for individual actions. Uses an explicit
111
+ * allowlist of safe action types — fail closed for anything unlisted.
112
+ */
113
+ function autoReview(action) {
114
+ if (!action || !action.type || typeof action.type !== 'string') {
115
+ return { eligible: false, reason: 'missing or invalid action type — human approval required' };
116
+ }
117
+ if (!ALLOWED_ACTIONS.includes(action.type)) {
118
+ return { eligible: false, reason: `"${action.type}" is unlisted — human approval required` };
119
+ }
120
+ if (CONSEQUENTIAL.includes(action.type)) {
121
+ return { eligible: false, reason: `"${action.type}" is consequential — human approval required` };
122
+ }
123
+ if (action.irreversible) {
124
+ return { eligible: false, reason: 'irreversible actions are never auto-approved' };
125
+ }
126
+ return { eligible: true, reason: 'bounded and reversible — auto-review passes' };
127
+ }
128
+
129
+ /**
130
+ * Execute one step. Refuses unless the plan was approved.
131
+ */
132
+ function executeStep(runbook, step, outcome) {
133
+ if (runbook.state !== 'approved' && runbook.state !== 'running') {
134
+ return { ok: false, reason: `execution refused — runbook state is "${runbook.state}", not approved` };
135
+ }
136
+ if (!Array.isArray(runbook.approvedPlan)) {
137
+ return { ok: false, reason: 'execution refused — no approved plan snapshot on record' };
138
+ }
139
+ if (!runbook.approvedPlan.includes(stepId(step))) {
140
+ return { ok: false, reason: `execution refused — "${step}" is not in the approved plan` };
141
+ }
142
+ runbook.state = 'running';
143
+ runbook.steps.push({ step, outcome: outcome || 'ok', at: new Date().toISOString() });
144
+ return { ok: true, executed: runbook.steps.length };
145
+ }
146
+
147
+ /**
148
+ * Capture a decision that would otherwise disappear into chat history.
149
+ */
150
+ function captureDecision(runbook, decision) {
151
+ if (!decision || !decision.choice || !decision.reason) {
152
+ return { ok: false, reason: 'a decision needs both a choice and a reason' };
153
+ }
154
+ runbook.decisions.push({
155
+ choice: decision.choice,
156
+ reason: decision.reason,
157
+ nextTime: decision.nextTime || null,
158
+ at: new Date().toISOString(),
159
+ });
160
+ return { ok: true, decisions: runbook.decisions.length };
161
+ }
162
+
163
+ /**
164
+ * Mark a dead end — the article documents these on purpose so the next run
165
+ * doesn't repeat them.
166
+ */
167
+ function recordDeadEnd(runbook, deadEnd) {
168
+ runbook.deadEnds.push({ deadEnd, at: new Date().toISOString() });
169
+ return { deadEnds: runbook.deadEnds.length };
170
+ }
171
+
172
+ /**
173
+ * Close the runbook. Only a running/approved runbook can close, and only
174
+ * with at least one recorded step.
175
+ */
176
+ function closeRunbook(runbook) {
177
+ if (runbook.state !== 'approved' && runbook.state !== 'running') {
178
+ return { ok: false, reason: `cannot close from state "${runbook.state}"` };
179
+ }
180
+ if (runbook.steps.length === 0) {
181
+ return { ok: false, reason: 'cannot close a runbook with no recorded steps' };
182
+ }
183
+ runbook.state = 'done';
184
+ runbook.completedAt = new Date().toISOString();
185
+ return { ok: true, state: 'done' };
186
+ }
187
+
188
+ /**
189
+ * Build the companion index over completed runbooks (the *.index.md analog).
190
+ * Full decision and dead-end records are stored alongside counts so later
191
+ * runs can reuse the captured guidance.
192
+ */
193
+ function buildIndex(runbooks) {
194
+ return (runbooks || [])
195
+ .filter((r) => r.state === 'done')
196
+ .map((r) => ({
197
+ workflow: r.workflow,
198
+ goal: r.goal,
199
+ steps: r.steps.length,
200
+ decisions: r.decisions.length,
201
+ deadEnds: r.deadEnds.length,
202
+ decisionsLog: r.decisions.map((d) => ({ ...d })),
203
+ deadEndsLog: r.deadEnds.map((d) => ({ ...d })),
204
+ completedAt: r.completedAt,
205
+ }));
206
+ }
207
+
208
+ /**
209
+ * Discover prior context for a workflow — what earlier runs learned.
210
+ * Returns the full decision and dead-end records so callers can act on
211
+ * the captured guidance, not just counts.
212
+ */
213
+ function discoverContext(index, workflow) {
214
+ const prior = (index || []).filter((e) => e.workflow === workflow);
215
+ return {
216
+ workflow,
217
+ priorRuns: prior.length,
218
+ totalDecisions: prior.reduce((n, e) => n + e.decisions, 0),
219
+ totalDeadEnds: prior.reduce((n, e) => n + e.deadEnds, 0),
220
+ decisions: prior.flatMap((e) => (e.decisionsLog || []).map((d) => ({ ...d }))),
221
+ deadEnds: prior.flatMap((e) => (e.deadEndsLog || []).map((d) => ({ ...d }))),
222
+ reusable: prior.length > 0,
223
+ };
224
+ }
225
+
226
+ function isCliEntrypoint() {
227
+ return require.main === module;
228
+ }
229
+
230
+ function parseCliArgs(argv) {
231
+ const args = argv.slice(2);
232
+ const mode = { dryRun: false, solve: false };
233
+ for (const arg of args) {
234
+ if (arg === '--dry-run') mode.dryRun = true;
235
+ else if (arg === '--solve') mode.solve = true;
236
+ }
237
+ return mode;
238
+ }
239
+
240
+ function main() {
241
+ const { dryRun, solve } = parseCliArgs(process.argv);
242
+ const rb = newRunbook('model-eval', 'Run the evaluation against the current model');
243
+
244
+ const premature = executeStep(rb, 'run eval'); // must refuse
245
+ approvePlan(rb, ['review previous run', 'write plan', 'run eval', 'document'], 'igor');
246
+ const review = { auto: autoReview({ type: 'read-file' }), blocked: autoReview({ type: 'production-deploy' }) };
247
+
248
+ if (dryRun) {
249
+ // Dry-run mode: do not record execution steps or complete the runbook.
250
+ // Surface the plan and auto-review decisions only.
251
+ process.stdout.write(JSON.stringify({
252
+ mode: 'dry-run',
253
+ honesty: 'deterministic model of the OpenAI Codex+Runme runbook flywheel',
254
+ source: 'https://developers.openai.com/blog/automating-repetitive-work-at-openai-with-codex',
255
+ prematureExecution: premature,
256
+ autoReview: review,
257
+ approvedPlan: rb.approvedPlan,
258
+ state: rb.state,
259
+ }, null, 2) + '\n');
260
+ return;
261
+ }
262
+
263
+ if (solve) {
264
+ // Solve mode: execute the approved plan end-to-end.
265
+ return runSolve(rb, review, premature);
266
+ }
267
+
268
+ // Default mode: execute the approved plan end-to-end.
269
+ runSolve(rb, review, premature);
270
+ }
271
+
272
+ function runSolve(rb, review, premature) {
273
+ executeStep(rb, 'review previous run', 'ok');
274
+ executeStep(rb, 'run eval', 'ok');
275
+ captureDecision(rb, {
276
+ choice: 'reuse existing eval cluster',
277
+ reason: 'quota exhausted on new provisioning',
278
+ nextTime: 'check quota before provisioning',
279
+ });
280
+ recordDeadEnd(rb, 'new cluster provisioning — quota exhausted');
281
+ closeRunbook(rb);
282
+
283
+ const index = buildIndex([rb]);
284
+ const context = discoverContext(index, 'model-eval');
285
+
286
+ process.stdout.write(JSON.stringify({
287
+ mode: 'solve',
288
+ honesty: 'deterministic model of the OpenAI Codex+Runme runbook flywheel',
289
+ source: 'https://developers.openai.com/blog/automating-repetitive-work-at-openai-with-codex',
290
+ prematureExecution: premature,
291
+ autoReview: review,
292
+ finalState: rb.state,
293
+ decisions: rb.decisions.length,
294
+ deadEnds: rb.deadEnds.length,
295
+ decisionsLog: rb.decisions,
296
+ deadEndsLog: rb.deadEnds,
297
+ index, context,
298
+ }, null, 2) + '\n');
299
+ }
300
+
301
+ if (isCliEntrypoint()) main();
302
+
303
+ module.exports = {
304
+ RUN_STATES,
305
+ CONSEQUENTIAL,
306
+ ALLOWED_ACTIONS,
307
+ stepId,
308
+ newRunbook,
309
+ approvePlan,
310
+ autoReview,
311
+ executeStep,
312
+ captureDecision,
313
+ recordDeadEnd,
314
+ closeRunbook,
315
+ buildIndex,
316
+ discoverContext,
317
+ isCliEntrypoint,
318
+ };
@@ -141,6 +141,168 @@ function buildFeedbackContextFootprintReport(entries = [], anchors = [], options
141
141
  };
142
142
  }
143
143
 
144
+ function renderSymbolicTaskCanvas(options = {}) {
145
+ const activeTask = options.activeTask || 'Execute Task';
146
+ const milestones = Array.isArray(options.milestones) ? options.milestones : [];
147
+ const blockers = Array.isArray(options.blockers) ? options.blockers : [];
148
+
149
+ let mermaidDiagram = 'graph TD\n';
150
+ mermaidDiagram += ` Start["Task Goal: ${activeTask}"]\n`;
151
+
152
+ if (milestones.length === 0) {
153
+ mermaidDiagram += ' Start --> Step1["In Progress"]\n';
154
+ } else {
155
+ let prevId = 'Start';
156
+ milestones.forEach((m, idx) => {
157
+ const stepId = `Step${idx + 1}`;
158
+ const status = m.status === 'completed' ? ' [DONE]' : m.status === 'blocked' ? ' [BLOCKED]' : ' [IN_PROGRESS]';
159
+ const label = `${m.name || m.title || `Milestone ${idx + 1}`}${status}`;
160
+ mermaidDiagram += ` ${prevId} --> ${stepId}["${label.replace(/"/g, "'")}"]\n`;
161
+ prevId = stepId;
162
+ });
163
+ }
164
+
165
+ if (blockers.length > 0) {
166
+ blockers.forEach((b, idx) => {
167
+ mermaidDiagram += ` Blocker${idx + 1}["BLOCKED: ${String(b).replace(/"/g, "'")}"] -.-> Start\n`;
168
+ });
169
+ }
170
+
171
+ const canvasText = [
172
+ `# Symbolic Task Canvas: ${activeTask}`,
173
+ `**Milestones:** ${milestones.length}`,
174
+ `**Blockers:** ${blockers.length}`,
175
+ '```mermaid',
176
+ mermaidDiagram.trim(),
177
+ '```',
178
+ ].join('\n');
179
+
180
+ return {
181
+ canvasText,
182
+ mermaidDiagram,
183
+ activeTask,
184
+ milestoneCount: milestones.length,
185
+ blockerCount: blockers.length,
186
+ };
187
+ }
188
+
189
+ function compactSymbolicTaskCanvas(entries = [], options = {}) {
190
+ const safeEntries = Array.isArray(entries) ? entries : [];
191
+ const activeTask = options.activeTask || 'Active Session Task';
192
+ const milestones = [];
193
+ const blockers = [];
194
+
195
+ for (const entry of safeEntries) {
196
+ if (!entry) continue;
197
+ const text = typeof entry === 'string' ? entry : JSON.stringify(entry);
198
+ if (/block|fail|error/i.test(text)) {
199
+ blockers.push(text.slice(0, 80));
200
+ } else {
201
+ milestones.push({ name: text.slice(0, 60), status: /done|pass|success/i.test(text) ? 'completed' : 'in_progress' });
202
+ }
203
+ }
204
+
205
+ const canvas = renderSymbolicTaskCanvas({ activeTask, milestones: milestones.slice(0, 5), blockers: blockers.slice(0, 3) });
206
+ const footprint = measureFootprint(safeEntries, canvas.canvasText, {
207
+ targetReduction: options.targetReduction || 0.5,
208
+ charsPerToken: options.charsPerToken,
209
+ });
210
+
211
+ return {
212
+ kind: 'symbolic-task-canvas',
213
+ strategy: 'symbolic-state-offloading',
214
+ canvas,
215
+ footprint,
216
+ };
217
+ }
218
+
219
+ function isPositiveInt(value) {
220
+ const n = Number(value);
221
+ return Number.isInteger(n) && n > 0;
222
+ }
223
+
224
+ function buildMatryoshkaEmbeddingReport(options = {}) {
225
+ const defaults = {
226
+ fullDimension: 1536,
227
+ targetDimensions: [768, 512, 256, 128],
228
+ itemCount: 1000,
229
+ };
230
+
231
+ const fullDimensionRaw = options.fullDimension == null ? defaults.fullDimension : options.fullDimension;
232
+ if (!isPositiveInt(fullDimensionRaw)) {
233
+ throw new Error('matryoshkaOptions.fullDimension must be a positive integer');
234
+ }
235
+ const fullDimension = Number(fullDimensionRaw);
236
+
237
+ const itemsRaw = options.itemCount == null ? defaults.itemCount : options.itemCount;
238
+ if (!isPositiveInt(itemsRaw)) {
239
+ throw new Error('matryoshkaOptions.itemCount must be a positive integer');
240
+ }
241
+ const items = Number(itemsRaw);
242
+
243
+ let targetDimensions;
244
+ if (Array.isArray(options.targetDimensions) && options.targetDimensions.length > 0) {
245
+ targetDimensions = options.targetDimensions.map(Number);
246
+ for (const dim of targetDimensions) {
247
+ if (!isPositiveInt(dim)) {
248
+ throw new Error('matryoshkaOptions.targetDimensions must be positive integers');
249
+ }
250
+ if (dim > fullDimension) {
251
+ throw new Error('matryoshkaOptions.targetDimensions must be <= fullDimension');
252
+ }
253
+ }
254
+ } else {
255
+ targetDimensions = defaults.targetDimensions.filter((dim) => dim <= fullDimension);
256
+ }
257
+
258
+ if (targetDimensions.length === 0) {
259
+ throw new Error('matryoshkaOptions.targetDimensions must include at least one valid dimension');
260
+ }
261
+
262
+ const baselineBytes = items * fullDimension * 4;
263
+ const qualityVerified = options.qualityVerified === true
264
+ && options.behaviorPreserved === true
265
+ && Number.isFinite(Number(options.accuracyLossEstimatePct));
266
+
267
+ const tiers = targetDimensions.map((dim) => {
268
+ const dimBytes = items * dim * 4;
269
+ const reductionRatio = baselineBytes > 0 ? (baselineBytes - dimBytes) / baselineBytes : 0;
270
+ return {
271
+ dimension: dim,
272
+ bytesPerItem: dim * 4,
273
+ totalBytes: dimBytes,
274
+ reductionPercent: Number((reductionRatio * 100).toFixed(1)),
275
+ estimatedMemorySavingsBytes: Math.max(0, baselineBytes - dimBytes),
276
+ recommendedUsage:
277
+ dim <= 256
278
+ ? 'Fast coarse vector filtering & initial top-K candidate pooling'
279
+ : 'High-precision re-ranking & final gate evaluation',
280
+ };
281
+ });
282
+
283
+ return {
284
+ kind: 'matryoshka-embedding-compaction',
285
+ strategy: 'matryoshka-representation-learning-mrl',
286
+ fullDimension,
287
+ itemCount: items,
288
+ baselineTotalBytes: baselineBytes,
289
+ qualityContract: qualityVerified
290
+ ? {
291
+ behaviorPreserved: true,
292
+ accuracyLossEstimatePct: `${Number(options.accuracyLossEstimatePct)}%`,
293
+ verified: true,
294
+ reason: 'Provider-specific golden evaluation met required recall/precision thresholds.',
295
+ }
296
+ : {
297
+ behaviorPreserved: false,
298
+ accuracyLossEstimatePct: 'unverified',
299
+ verified: false,
300
+ reason: 'Quality unverified: no provider-specific Matryoshka golden evaluation evidence was supplied. Do not treat truncation as behavior-preserving until deterministic RAG eval meets required thresholds.',
301
+ },
302
+ tiers,
303
+ };
304
+ }
305
+
144
306
  function buildContextFootprintReport(options = {}) {
145
307
  const targetReduction = normalizeRatio(options.targetReduction);
146
308
  const report = {
@@ -152,6 +314,8 @@ function buildContextFootprintReport(options = {}) {
152
314
  'Use construct_context_pack with maxChars before injecting lessons into a model prompt.',
153
315
  'Keep gate ids, proof URLs, and anchor lessons stable so compaction does not hide evidence.',
154
316
  'Track estimated token savings beside every optimized context path.',
317
+ 'Offload verbose raw logs into a Symbolic Task Canvas (Mermaid state graph) to save ~60% tokens.',
318
+ 'Truncate Matryoshka vector embeddings (1536d -> 256d) for fast coarse filtering, reserving full dimensions for final re-ranking.',
155
319
  ],
156
320
  };
157
321
 
@@ -177,6 +341,23 @@ function buildContextFootprintReport(options = {}) {
177
341
  );
178
342
  }
179
343
 
344
+ if (options.symbolicCanvas || Array.isArray(options.symbolicEntries)) {
345
+ report.symbolicTaskCanvas = compactSymbolicTaskCanvas(
346
+ options.symbolicEntries || options.entries || [],
347
+ {
348
+ activeTask: options.activeTask,
349
+ targetReduction,
350
+ charsPerToken: options.charsPerToken,
351
+ },
352
+ );
353
+ }
354
+
355
+ if (options.matryoshkaEmbedding || options.matryoshkaOptions) {
356
+ report.matryoshkaEmbedding = buildMatryoshkaEmbeddingReport(
357
+ typeof options.matryoshkaOptions === 'object' ? options.matryoshkaOptions : {},
358
+ );
359
+ }
360
+
180
361
  return report;
181
362
  }
182
363
 
@@ -187,5 +368,10 @@ module.exports = {
187
368
  measureFootprint,
188
369
  buildMcpToolFootprintReport,
189
370
  buildFeedbackContextFootprintReport,
371
+ renderSymbolicTaskCanvas,
372
+ compactSymbolicTaskCanvas,
373
+ buildMatryoshkaEmbeddingReport,
190
374
  buildContextFootprintReport,
191
375
  };
376
+
377
+