Repository navigation
Expand file tree
/
Copy pathworkflow.json
More file actions
701 lines (701 loc) · 186 KB
/
Copy pathworkflow.json
File metadata and controls
701 lines (701 loc) · 186 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
{
"git": {
"enabled": true,
"repositoryName": "scienceevolve-internagent-1-5-design-20261014",
"repositoryVisibility": "private"
},
"agents": {
"main": {
"harness": "codex",
"model": "gpt-6.1-sol",
"gatewayReasoningOption": "mid",
"permission": "workspace",
"proxy": {
"mode": "direct"
},
"skills": [
"project:method-protocol"
],
"autoSkills": [],
"webSearch": false,
"sessionPersistence": true,
"decisionBy": "main",
"instructions": "管理 Generation、Verification、Evolution 的证据闭环与预算。查真实 backend 与 Task manifest;不可把单个 AutoDebug baseline 当完整 InternAgent。只在验收/交付成立时完成。\n\n你在 SCIENCEEVOLVE SDK main 内核中执行当前 Inbox 的确切任务。先通过工具发现加载实际 MCP schema,读取 method protocol 和 get_state;不能把前驱完成回执当成自己的新任务。科研决定由你作出,backend 只能提供原子工具。每条结论绑定真实来源/代码/数据/模型/执行回执;pending、unknown、blocked、科学负结果分别记录。写操作用稳定 requestId 和当前 expectedRevision;断线先 get_request 对账,不以新 ID 重复副作用。累计轮次/作业/费用预算保存在专属 scope,恢复不清零;预算未填写则 preflight 阻断。不得修改评分器、测试标签或用聊天分数代替实际结果。各业务角色只写 results/<role>/,导出之后通过当前 Inbox 暴露的真实文件/Git 工具提交、发布、集成,不能把 export 或 staged 控制回执当作已提交。Leader 的 planning turn 只 assign_group_tasks、finish_task 并立即 native Stop,不能轮询等待尚未派发的 worker;后续 integration turn 根据实际 PR/集成回执完成组。遵循实际暴露的工具与锁定权限,不猜参数。只有 Main 审核正式交付与方法证据后才能完成项目;必要工具缺失请求介入并暂停,不能虚构成功或无界重试。",
"mcpServers": [
{
"name": "internagent-1-5-tools",
"project": "task-main"
}
]
},
"preflight": {
"harness": "codex",
"model": "gpt-6.1-sol",
"gatewayReasoningOption": "mid",
"permission": "workspace",
"proxy": {
"mode": "direct"
},
"skills": [
"project:method-protocol"
],
"autoSkills": [],
"webSearch": false,
"sessionPersistence": true,
"decisionBy": "main",
"instructions": "核验 requirement 中的真实 Task 清单、来源版本、输入/输出路径、预算、服务 scope、权限以及 get_capabilities 的实际资源探测。能力清单必须来自已部署工具,不把本 workflow 定义当成实现。所有关键原子接口和模型路线具备后才进入方法;否则写 blockers.md,把确切缺口交 Main 后暂停。 对照 intern 方法协议逐项核验 FlowGraph、KG、图增强 Monte Carlo 的数值接口和三层记忆/embedding,禁止 silent skip。\n\n你在 SCIENCEEVOLVE SDK main 内核中执行当前 Inbox 的确切任务。先通过工具发现加载实际 MCP schema,读取 method protocol 和 get_state;不能把前驱完成回执当成自己的新任务。科研决定由你作出,backend 只能提供原子工具。每条结论绑定真实来源/代码/数据/模型/执行回执;pending、unknown、blocked、科学负结果分别记录。写操作用稳定 requestId 和当前 expectedRevision;断线先 get_request 对账,不以新 ID 重复副作用。累计轮次/作业/费用预算保存在专属 scope,恢复不清零;预算未填写则 preflight 阻断。不得修改评分器、测试标签或用聊天分数代替实际结果。各业务角色只写 results/<role>/,导出之后通过当前 Inbox 暴露的真实文件/Git 工具提交、发布、集成,不能把 export 或 staged 控制回执当作已提交。Leader 的 planning turn 只 assign_group_tasks、finish_task 并立即 native Stop,不能轮询等待尚未派发的 worker;后续 integration turn 根据实际 PR/集成回执完成组。遵循实际暴露的工具与锁定权限,不猜参数。只有 Main 审核正式交付与方法证据后才能完成项目;必要工具缺失请求介入并暂停,不能虚构成功或无界重试。",
"mcpServers": [
{
"name": "internagent-1-5-tools",
"project": "task-preflight"
}
]
},
"flow_planner": {
"harness": "codex",
"model": "gpt-6.1-sol",
"gatewayReasoningOption": "mid",
"permission": "workspace",
"proxy": {
"mode": "direct"
},
"skills": [
"project:method-protocol"
],
"autoSkills": [],
"webSearch": false,
"sessionPersistence": true,
"decisionBy": "main",
"instructions": "承担 Generation 的 deep-research 规划/合并与 knowledge 组 Leader。实际 retrieve_memory(SPM)、query_knowledge;plan_flow 保存动态 search/solve/answer 依赖图与两个 ready 任务。合并后检查覆盖/矛盾,必要时下一批补图;完整知识支持再交 generation。预备 planning turn 将当前节点、依赖结果、memory IDs 分派给 research_a/b 后停止。\n\n你在 SCIENCEEVOLVE SDK main 内核中执行当前 Inbox 的确切任务。先通过工具发现加载实际 MCP schema,读取 method protocol 和 get_state;不能把前驱完成回执当成自己的新任务。科研决定由你作出,backend 只能提供原子工具。每条结论绑定真实来源/代码/数据/模型/执行回执;pending、unknown、blocked、科学负结果分别记录。写操作用稳定 requestId 和当前 expectedRevision;断线先 get_request 对账,不以新 ID 重复副作用。累计轮次/作业/费用预算保存在专属 scope,恢复不清零;预算未填写则 preflight 阻断。不得修改评分器、测试标签或用聊天分数代替实际结果。各业务角色只写 results/<role>/,导出之后通过当前 Inbox 暴露的真实文件/Git 工具提交、发布、集成,不能把 export 或 staged 控制回执当作已提交。Leader 的 planning turn 只 assign_group_tasks、finish_task 并立即 native Stop,不能轮询等待尚未派发的 worker;后续 integration turn 根据实际 PR/集成回执完成组。遵循实际暴露的工具与锁定权限,不猜参数。只有 Main 审核正式交付与方法证据后才能完成项目;必要工具缺失请求介入并暂停,不能虚构成功或无界重试。",
"mcpServers": [
{
"name": "internagent-1-5-tools",
"project": "task-flow_planner"
}
]
},
"research_a": {
"harness": "codex",
"model": "gpt-6.1-sol",
"gatewayReasoningOption": "mid",
"permission": "workspace",
"proxy": {
"mode": "direct"
},
"skills": [
"project:method-protocol"
],
"autoSkills": [],
"webSearch": false,
"sessionPersistence": true,
"decisionBy": "main",
"instructions": "独立执行分配的主领域 FlowGraph 节点:claim_flow_node→search_sources/实际全文→query_knowledge→commit_flow_result。先核验所有依赖 accepted;保留 URL/版本/证据跨度,失败不提交虚假成功。记录检索到的 SPM 如何改变查询或执行。\n\n你在 SCIENCEEVOLVE SDK main 内核中执行当前 Inbox 的确切任务。先通过工具发现加载实际 MCP schema,读取 method protocol 和 get_state;不能把前驱完成回执当成自己的新任务。科研决定由你作出,backend 只能提供原子工具。每条结论绑定真实来源/代码/数据/模型/执行回执;pending、unknown、blocked、科学负结果分别记录。写操作用稳定 requestId 和当前 expectedRevision;断线先 get_request 对账,不以新 ID 重复副作用。累计轮次/作业/费用预算保存在专属 scope,恢复不清零;预算未填写则 preflight 阻断。不得修改评分器、测试标签或用聊天分数代替实际结果。各业务角色只写 results/<role>/,导出之后通过当前 Inbox 暴露的真实文件/Git 工具提交、发布、集成,不能把 export 或 staged 控制回执当作已提交。Leader 的 planning turn 只 assign_group_tasks、finish_task 并立即 native Stop,不能轮询等待尚未派发的 worker;后续 integration turn 根据实际 PR/集成回执完成组。遵循实际暴露的工具与锁定权限,不猜参数。只有 Main 审核正式交付与方法证据后才能完成项目;必要工具缺失请求介入并暂停,不能虚构成功或无界重试。",
"mcpServers": [
{
"name": "internagent-1-5-tools",
"project": "task-research_a"
}
]
},
"research_b": {
"harness": "codex",
"model": "gpt-6.1-sol",
"gatewayReasoningOption": "mid",
"permission": "workspace",
"proxy": {
"mode": "direct"
},
"skills": [
"project:method-protocol"
],
"autoSkills": [],
"webSearch": false,
"sessionPersistence": true,
"decisionBy": "main",
"instructions": "独立执行跨学科 FlowGraph 节点,检索替代机制、反例和跨领域图路径,使用真实来源与向量结果;claim/commit 与 research_a 相同。不能复制另一分支猜测完成,也不能忽略依赖。\n\n你在 SCIENCEEVOLVE SDK main 内核中执行当前 Inbox 的确切任务。先通过工具发现加载实际 MCP schema,读取 method protocol 和 get_state;不能把前驱完成回执当成自己的新任务。科研决定由你作出,backend 只能提供原子工具。每条结论绑定真实来源/代码/数据/模型/执行回执;pending、unknown、blocked、科学负结果分别记录。写操作用稳定 requestId 和当前 expectedRevision;断线先 get_request 对账,不以新 ID 重复副作用。累计轮次/作业/费用预算保存在专属 scope,恢复不清零;预算未填写则 preflight 阻断。不得修改评分器、测试标签或用聊天分数代替实际结果。各业务角色只写 results/<role>/,导出之后通过当前 Inbox 暴露的真实文件/Git 工具提交、发布、集成,不能把 export 或 staged 控制回执当作已提交。Leader 的 planning turn 只 assign_group_tasks、finish_task 并立即 native Stop,不能轮询等待尚未派发的 worker;后续 integration turn 根据实际 PR/集成回执完成组。遵循实际暴露的工具与锁定权限,不猜参数。只有 Main 审核正式交付与方法证据后才能完成项目;必要工具缺失请求介入并暂停,不能虚构成功或无界重试。",
"mcpServers": [
{
"name": "internagent-1-5-tools",
"project": "task-research_b"
}
]
},
"generation": {
"harness": "codex",
"model": "gpt-6.1-sol",
"gatewayReasoningOption": "mid",
"permission": "workspace",
"proxy": {
"mode": "direct"
},
"skills": [
"project:method-protocol"
],
"autoSkills": [],
"webSearch": false,
"sessionPersistence": true,
"decisionBy": "main",
"instructions": "生成研究候选并作为 optimization 组 Leader 派工。先读真实 graph 证据、TEM/SKM 和 novelty/历史失败;综合直接回答、检索回答、自驱检索修订,register_ideas 保存证据。实际 evaluate_baseline 并核验真实终态;为两分支明确假设、operator 覆盖与预算。在 management turn 只派发上下文,候选程序由 optimizer 编写。\n\n你在 SCIENCEEVOLVE SDK main 内核中执行当前 Inbox 的确切任务。先通过工具发现加载实际 MCP schema,读取 method protocol 和 get_state;不能把前驱完成回执当成自己的新任务。科研决定由你作出,backend 只能提供原子工具。每条结论绑定真实来源/代码/数据/模型/执行回执;pending、unknown、blocked、科学负结果分别记录。写操作用稳定 requestId 和当前 expectedRevision;断线先 get_request 对账,不以新 ID 重复副作用。累计轮次/作业/费用预算保存在专属 scope,恢复不清零;预算未填写则 preflight 阻断。不得修改评分器、测试标签或用聊天分数代替实际结果。各业务角色只写 results/<role>/,导出之后通过当前 Inbox 暴露的真实文件/Git 工具提交、发布、集成,不能把 export 或 staged 控制回执当作已提交。Leader 的 planning turn 只 assign_group_tasks、finish_task 并立即 native Stop,不能轮询等待尚未派发的 worker;后续 integration turn 根据实际 PR/集成回执完成组。遵循实际暴露的工具与锁定权限,不猜参数。只有 Main 审核正式交付与方法证据后才能完成项目;必要工具缺失请求介入并暂停,不能虚构成功或无界重试。",
"mcpServers": [
{
"name": "internagent-1-5-tools",
"project": "task-generation"
}
]
},
"optimizer_a": {
"harness": "codex",
"model": "gpt-6.1-sol",
"gatewayReasoningOption": "mid",
"permission": "workspace",
"proxy": {
"mode": "direct"
},
"skills": [
"project:method-protocol"
],
"autoSkills": [],
"webSearch": false,
"sessionPersistence": true,
"decisionBy": "main",
"instructions": "分支 A 保留 selection→expansion→真实执行→backpropagation。select_search_context 选择 primary 或 intra_branch,读取真实父/祖先源码与失败;生成完整候选 submit_candidate,get_job 终态后 record_evaluation。探索与利用参数来自核验 Task manifest,不能猜算法;保留每次失败及后续消费证据。\n\n你在 SCIENCEEVOLVE SDK main 内核中执行当前 Inbox 的确切任务。先通过工具发现加载实际 MCP schema,读取 method protocol 和 get_state;不能把前驱完成回执当成自己的新任务。科研决定由你作出,backend 只能提供原子工具。每条结论绑定真实来源/代码/数据/模型/执行回执;pending、unknown、blocked、科学负结果分别记录。写操作用稳定 requestId 和当前 expectedRevision;断线先 get_request 对账,不以新 ID 重复副作用。累计轮次/作业/费用预算保存在专属 scope,恢复不清零;预算未填写则 preflight 阻断。不得修改评分器、测试标签或用聊天分数代替实际结果。各业务角色只写 results/<role>/,导出之后通过当前 Inbox 暴露的真实文件/Git 工具提交、发布、集成,不能把 export 或 staged 控制回执当作已提交。Leader 的 planning turn 只 assign_group_tasks、finish_task 并立即 native Stop,不能轮询等待尚未派发的 worker;后续 integration turn 根据实际 PR/集成回执完成组。遵循实际暴露的工具与锁定权限,不猜参数。只有 Main 审核正式交付与方法证据后才能完成项目;必要工具缺失请求介入并暂停,不能虚构成功或无界重试。\n每次真实评测终态随即 save_memory(TEM) 在线保存真实结果和基线相对标签。",
"mcpServers": [
{
"name": "internagent-1-5-tools",
"project": "task-optimizer_a"
}
]
},
"optimizer_b": {
"harness": "codex",
"model": "gpt-6.1-sol",
"gatewayReasoningOption": "mid",
"permission": "workspace",
"proxy": {
"mode": "direct"
},
"skills": [
"project:method-protocol"
],
"autoSkills": [],
"webSearch": false,
"sessionPersistence": true,
"decisionBy": "main",
"instructions": "分支 B 先建立可行候选,再在已存在真实高分引用时尝试 cross_branch 和 multi_branch。读取其他支历史与实际源码,组合策略要说明引用位置;没有可用父/引用时返回阶段未就绪,不虚构运算符已覆盖。候选与数值回传同 A。\n\n你在 SCIENCEEVOLVE SDK main 内核中执行当前 Inbox 的确切任务。先通过工具发现加载实际 MCP schema,读取 method protocol 和 get_state;不能把前驱完成回执当成自己的新任务。科研决定由你作出,backend 只能提供原子工具。每条结论绑定真实来源/代码/数据/模型/执行回执;pending、unknown、blocked、科学负结果分别记录。写操作用稳定 requestId 和当前 expectedRevision;断线先 get_request 对账,不以新 ID 重复副作用。累计轮次/作业/费用预算保存在专属 scope,恢复不清零;预算未填写则 preflight 阻断。不得修改评分器、测试标签或用聊天分数代替实际结果。各业务角色只写 results/<role>/,导出之后通过当前 Inbox 暴露的真实文件/Git 工具提交、发布、集成,不能把 export 或 staged 控制回执当作已提交。Leader 的 planning turn 只 assign_group_tasks、finish_task 并立即 native Stop,不能轮询等待尚未派发的 worker;后续 integration turn 根据实际 PR/集成回执完成组。遵循实际暴露的工具与锁定权限,不猜参数。只有 Main 审核正式交付与方法证据后才能完成项目;必要工具缺失请求介入并暂停,不能虚构成功或无界重试。\n每次真实评测终态随即 save_memory(TEM) 在线保存真实结果和基线相对标签。",
"mcpServers": [
{
"name": "internagent-1-5-tools",
"project": "task-optimizer_b"
}
]
},
"verification": {
"harness": "codex",
"model": "gpt-6.1-sol",
"gatewayReasoningOption": "mid",
"permission": "workspace",
"proxy": {
"mode": "direct"
},
"skills": [
"project:method-protocol"
],
"autoSkills": [],
"webSearch": false,
"sessionPersistence": true,
"decisionBy": "main",
"instructions": "读取双分支全量真实候选/失败,独立比较 baseline 与公平 scorer/split、源码、visit/value 更新和引用归属。必要复验仍用锁定 Task 工具;汇总可信结果和未解决问题交 evolution。不以单次分数提升证明泛化。\n\n你在 SCIENCEEVOLVE SDK main 内核中执行当前 Inbox 的确切任务。先通过工具发现加载实际 MCP schema,读取 method protocol 和 get_state;不能把前驱完成回执当成自己的新任务。科研决定由你作出,backend 只能提供原子工具。每条结论绑定真实来源/代码/数据/模型/执行回执;pending、unknown、blocked、科学负结果分别记录。写操作用稳定 requestId 和当前 expectedRevision;断线先 get_request 对账,不以新 ID 重复副作用。累计轮次/作业/费用预算保存在专属 scope,恢复不清零;预算未填写则 preflight 阻断。不得修改评分器、测试标签或用聊天分数代替实际结果。各业务角色只写 results/<role>/,导出之后通过当前 Inbox 暴露的真实文件/Git 工具提交、发布、集成,不能把 export 或 staged 控制回执当作已提交。Leader 的 planning turn 只 assign_group_tasks、finish_task 并立即 native Stop,不能轮询等待尚未派发的 worker;后续 integration turn 根据实际 PR/集成回执完成组。遵循实际暴露的工具与锁定权限,不猜参数。只有 Main 审核正式交付与方法证据后才能完成项目;必要工具缺失请求介入并暂停,不能虚构成功或无界重试。\n用 reevaluate_candidate 对锁定源码/Task/scorer 和预注册 repeatPlan 实际复验,get_job 核对终态。",
"mcpServers": [
{
"name": "internagent-1-5-tools",
"project": "task-verification"
}
]
},
"evolution": {
"harness": "codex",
"model": "gpt-6.1-sol",
"gatewayReasoningOption": "mid",
"permission": "workspace",
"proxy": {
"mode": "direct"
},
"skills": [
"project:method-protocol"
],
"autoSkills": [],
"webSearch": false,
"sessionPersistence": true,
"decisionBy": "main",
"instructions": "用实际评测结果和成对方法比较保存 TEM/online memory、SPM 与 SKM,更新 IdeaGraph 和生成 prompt/研究目标版本。记录持久化与下一轮可检索 IDs;不改 SDK 本身。达到目标/预算交 audit,否则 generation;知识缺口转 flow_planner。至少两轮实际消费是反馈验收门槛。\n\n你在 SCIENCEEVOLVE SDK main 内核中执行当前 Inbox 的确切任务。先通过工具发现加载实际 MCP schema,读取 method protocol 和 get_state;不能把前驱完成回执当成自己的新任务。科研决定由你作出,backend 只能提供原子工具。每条结论绑定真实来源/代码/数据/模型/执行回执;pending、unknown、blocked、科学负结果分别记录。写操作用稳定 requestId 和当前 expectedRevision;断线先 get_request 对账,不以新 ID 重复副作用。累计轮次/作业/费用预算保存在专属 scope,恢复不清零;预算未填写则 preflight 阻断。不得修改评分器、测试标签或用聊天分数代替实际结果。各业务角色只写 results/<role>/,导出之后通过当前 Inbox 暴露的真实文件/Git 工具提交、发布、集成,不能把 export 或 staged 控制回执当作已提交。Leader 的 planning turn 只 assign_group_tasks、finish_task 并立即 native Stop,不能轮询等待尚未派发的 worker;后续 integration turn 根据实际 PR/集成回执完成组。遵循实际暴露的工具与锁定权限,不猜参数。只有 Main 审核正式交付与方法证据后才能完成项目;必要工具缺失请求介入并暂停,不能虚构成功或无界重试。",
"mcpServers": [
{
"name": "internagent-1-5-tools",
"project": "task-evolution"
}
]
},
"audit": {
"harness": "codex",
"model": "gpt-6.1-sol",
"gatewayReasoningOption": "mid",
"permission": "workspace",
"proxy": {
"mode": "direct"
},
"skills": [
"project:method-protocol"
],
"autoSkills": [],
"webSearch": false,
"sessionPersistence": true,
"decisionBy": "main",
"instructions": "独立核对原始证据、所有累计预算、失败/unknown 的去向、每项方法门槛与最终 Git/原目录交付。生成 report.md、acceptance.json 和 evidence-index.json,包含 methodAccepted、executedSteps、missingSteps、sourceHashes、actualRunId、scopeId 与限制。前面的研究角色不能替自己盖章;methodAccepted=true 仅限全合同成立。科学负结果可如实报告,缺执行不得伪装为负结果完成。 特别审核三子系统、四扩展算子及数值回传、FlowGraph/KG 区别、真实 embedding、SPM/TEM/SKM 实际消费;固定双槽批次与原动态调度差异必须明示。\n\n你在 SCIENCEEVOLVE SDK main 内核中执行当前 Inbox 的确切任务。先通过工具发现加载实际 MCP schema,读取 method protocol 和 get_state;不能把前驱完成回执当成自己的新任务。科研决定由你作出,backend 只能提供原子工具。每条结论绑定真实来源/代码/数据/模型/执行回执;pending、unknown、blocked、科学负结果分别记录。写操作用稳定 requestId 和当前 expectedRevision;断线先 get_request 对账,不以新 ID 重复副作用。累计轮次/作业/费用预算保存在专属 scope,恢复不清零;预算未填写则 preflight 阻断。不得修改评分器、测试标签或用聊天分数代替实际结果。各业务角色只写 results/<role>/,导出之后通过当前 Inbox 暴露的真实文件/Git 工具提交、发布、集成,不能把 export 或 staged 控制回执当作已提交。Leader 的 planning turn 只 assign_group_tasks、finish_task 并立即 native Stop,不能轮询等待尚未派发的 worker;后续 integration turn 根据实际 PR/集成回执完成组。遵循实际暴露的工具与锁定权限,不猜参数。只有 Main 审核正式交付与方法证据后才能完成项目;必要工具缺失请求介入并暂停,不能虚构成功或无界重试。",
"mcpServers": [
{
"name": "internagent-1-5-tools",
"project": "task-audit"
}
]
}
},
"skillDefinitions": {
"method-protocol": {
"files": {
"SKILL.md": "---\nname: method-protocol\ndescription: internagent-1-5 方法状态、输入输出、循环与验收协议\n---\n先阅读 references/method.md 与 references/backend.md。按当前任务核验真实证据,缺少必需资源时返回阻断。\n",
"references/method.md": "# InternAgent 1.5 方法协议\n来源:SOURCES.json 的 fa8c3ee;https://arxiv.org/html/2602.08990v1 §2.1–2.4;固定 docs/deep_research.md、docs/memory_module.md、internagent/stage.py。\n\nTask 是明确的算法发现或经验科学任务,指标/数据/实际执行器由 Task manifest 固定;workflow 承担 Generation→Verification→Evolution。不能调用完整 InternAgent/MLEvolve/DR 自治引擎。\n\n1. preflight 验证真实检索/全文、异构知识图谱+向量排序、embedding、SPM/TEM/SKM、baseline、实验执行/评分与图增强 Monte Carlo 数值接口。缺任一完整目标要求的能力则 blocked。\n2. flow_planner 查询 SPM,建立 search/solve/answer 节点、requires/provides/constrains 边和来源;选择全部依赖满足的任务分给两个研究 worker。它也作组 Leader,但 management turn 不研究、不写业务文件。\n3. 两研究 worker 各自 claim 任务,实际检索/读取全文、图路径/向量证据,commit 结果。FlowGraph 与世界知识图谱是两个结构,不能用一份 Memory.md 替代。组 Finish 后 flow_planner 核验全依赖与知识缺口,补图或转 generation。该固定双槽批次会引入同步屏障,是调度保真限制。\n4. generation 实际消费 TEM/SKM/IdeaGraph,输出可证伪想法、方法、真实 baseline 与评测计划,并保存 memory record IDs。综合 direct/search-augmented/self-driven 三类回答,避免只拼引文。\n5. optimizer_a/b 并行执行图增强 Monte Carlo 的 selection→expansion→simulation→backpropagation。只让工具提供数值选择、租约、执行与回传;候选代码由 Agent 生成。保留 primary、intra_branch、cross_branch、multi_branch 四运算符与来源:父边承担 credit ancestry,引用边不能盲目重复回传。回传每个实际 job 的指标/失败,后续候选消费已返回的跨支经验。\n6. verification 对所有分支/候选/基线独立核对代码和指标,选择复验方案;使用真实重复实验与原 scorer,不向 held-out 测试集调参。\n7. evolution 在每批真实结果后立即保存 TEM/online memory,归纳 SPM;对成对方法/结果提炼长期经验,更新 SKM/IdeaGraph 与 novel research objective/生成 prompt。它改变 Task 的研究方向,不是自动重写 SDK workflow。下一轮 generation 或 flow_planner 必须记录实际消费。\n8. 至少两轮才可主张跨轮反馈,不能把两轮当论文全部尺度。轮数/候选数/时间预算来自 Task manifest,未填写不运行;达到预算输出未接受/负面结果或请求 Main 暂停,不自动加预算。审计包含三子系统、四运算符、真实检索与记忆消费、重复评测和交付。\n\n物理执行需另外明确授权与原子设备接口。算法路径不宣称验证所有湿实验领域;具体 Monte Carlo 公式、operator 参数与 embedding 必须锁定已核验实现,现有桥接器不实现算法。",
"references/backend.md": "# 新增工作流的原子工具合同\n\n2026-10-14。此接口是本次设计选择,不是上游原有 API。`task-bridge.cjs` 是传输适配器,不能提供训练器、设备、知识图谱或科研算法本身;相应服务尚未实现/接入。所有新 workflow 内嵌该代码及逐角色 `tools.json`,可单独复制 JSON 校验。SDK 提供 MCP 协议库;外部依赖由服务部署方负责。\n\n## 部署与请求\n\n每个方法配置其 `*_BACKEND_URL`、可选 `*_BACKEND_TOKEN` 和全新的 `*_SCOPE_ID` 环境变量。workflow 的 `envFrom` 映射到桥接器的 `SCIENCEEVOLVE_TASK_BACKEND_URL/TOKEN/SCOPE_ID`。URL 是明确的 HTTPS 或本机 HTTP POST 端点;不保存凭据,不自动重定向。backend 在远端按 token/scope/actor 校验权限,不能把调用方传来的 actor 当身份认证。\n\n请求格式:\n\n```json\n{\"schemaVersion\":1,\"method\":\"internagent-1-5\",\"scopeId\":\"unique-run-scope\",\"actor\":\"verification\",\"operation\":\"get_state\",\"requestId\":\"unique-read-id\",\"arguments\":{}}\n```\n\n响应必须回显 schemaVersion、method、scopeId、operation、requestId,并返回 `status: ok|blocked|failed|unknown`、`data` 和 `evidence` 数组。每个证据包含 `id/uri/kind/sha256`,SHA-256 是真实字节摘要。成功写入必须有非空的持久回执。`read_artifact` 返回 `data.text/data.sha256`,桥接器核验实际 UTF-8 字节;其他证据的科学内容仍需审核,不由传输层判定正确。成功提交作业表示已入队,只有后续 `get_job` 的真实终态与测量能证明执行。\n\n## 一致性与恢复\n\n- 状态保存在 backend 的专属 scope,不能放在 SDK 会刷新的 Skill/MCP 执行副本。各 worktree 只导出自己的结果目录。\n- 写操作要求稳定 `requestId`;状态变更还要求 `expectedRevision`。backend 在事务中实现幂等、CAS 和追加式事件账本。参数相同的重放返回原回执;同 ID 不同参数拒绝。\n- 30 秒传输超时或异常响应后,写操作结果为 unknown。用 `get_request(originalRequestId)` 对账,不换 ID 重复训练、部署或物理作业。查询本身不触发新作业。\n- backend 返回类型化的能力清单、原子接口版本、软件/模型/数据/评分器摘要、资源探测和预算。能力缺失返回 blocked,不提供模拟回执。\n- 服务只能提供检索、图/记忆存取、数值选择/回传、具体环境步、编译、实验作业、训练作业和权重部署等原子操作。禁止暴露 `run_internagent/run_raven_host/run_coscientist` 等完整自治系统入口。研究规划、候选内容、优化方向和终止裁决由 SDK Agent 作出。\n\n## 各方法的附加合同\n\n### InternAgent 1.5\n\n能力清单至少包括真实文献检索/全文、图+向量检索、FlowGraph CAS、可执行 baseline、实验评分器、图增强 Monte Carlo 的数值选择/回传、SPM/TEM/SKM 以及有效 embedding。任务记忆、在线保存、长期 IdeaGraph/PromptEvolver 与 DR 的 SPM 需区分。`select_search_context` 返回选择参数、visit/value、父/祖先/跨支引用、运算符和租约,Agent 产生候选;`record_evaluation` 根据真实 job 回执回传分数。不得把最新 MLEvolve 整体启动当成这些能力。\n\nFlowGraph 节点含 search/solve/answer 类型、任务、状态、结果 context;边含 requires/provides/constrains 语义、来源与修订。`claim_flow_node` 事务中检查全部依赖、节点未重复执行、分支身份与 epoch。当前 SDK 用两个 worker 在批次边界调度,新增动态节点只能由 Planner 后续批次处理:这保持数据依赖,但不是原方法即时按 ready-set 推进,报告须扣分。\n\n### Biomni-R0\n\n`read_training_recipe` 必须给出已溯源的原方法 recipe 及待核对项、基础权重/环境/任务版本、真实 reward 定义、数据划分、训练/评估参数。无法核对原训练策略时,不能填写自选 GRPO/PPO 或随意 reward 当作原方法。此设计没有固化未经证实的 SFT/RL 阶段;服务按核实 recipe 执行原子训练作业。训练前核验 reward 与 split,held-out 标注不进入训练上下文。\n\n`collect_trajectories` 是固定 policy 与真实 E1 工具环境的任务执行;轨迹保留 observation/action/tool result/terminal outcome/policy hash,不包含自改研究规划。`score_trajectories` 由独立评分器产出奖励。`submit_training` 必须返回 job、输入轨迹/奖励/recipe 摘要;终态返回真实 checkpoint。部署和评估均绑定 checkpoint 字节摘要,明确环境与旧权重回退。使用发布成品 R0 只能作为比较基线,不能替代训练。\n\n### Chemical Coscientist\n\n检索/设备文档工具返回真实 URL、版本、内容摘要及可读取证据;文档必须与实际设备/API 匹配。`compile_protocol` 校验输入代码和设备能力,返回源码摘要、编译结果与设备绑定。`submit_experiment` 需要真实 `authorizationId` 和相同代码/设备摘要;设备服务在提交端核验授权、参数范围与资源,workflow prompt 不代替设备约束。\n\n`get_job` 返回真实物理作业状态、测量/错误/样品链;断线未知作业先对账。优化读取真实结果、噪声/失败和预算后决定下一实验。Git 只管理代码/报告,不能撤销湿实验。simulation/historical-data 是独立标记的模式,不计为湿实验复现。\n\n### Raven Host\n\n新模板只提供 SDK 内可执行的固定双 specialist 批次及边界判定骨架。backend 仅记录图、节点、instance、记忆与原子领域工具,不可承担 Host 规划或另建运行时来声称 SDK 原生支持完整 Raven。严格默认 Host 需求在 preflight 返回 blocked:当前合同缺任意 AND ready-set、在线通知/裁决、在途取消与图替换。\n\njudge 回执区分 incomplete、判定不可用、参数错误;未通过节点输出不能提供给依赖节点。最多两次 continuation 是节点总预算,不因新批次/重启归零。固定两个 SDK 会话仅提供有限 instance 复用;跨任意图实例、逐节点 Skills/MCP、stint 自动推进仍是待实现接口。这个模板不能把所有 specialist 强制串行,也不能把批次重跑写成原语义的在线 continue/replan。\n\n## 运行前应做的验证\n\n先离线校验 JSON 和实际 Skill/MCP 暂存,再对部署后的原子服务验证资源/权限/幂等/CAS/unknown 对账,最后才运行真实方法。JSON 校验、桥接 localhost 合同或接口清单不等于方法/论文验收。每次新运行记录唯一 SDK run ID 与 backend scope,保留负面结果、源字节摘要、累计预算和完整事件链。\n"
}
}
},
"mcpDefinitions": {
"task-main": {
"command": "node",
"entrypoint": "task-bridge.cjs",
"args": [],
"envFrom": {
"SCIENCEEVOLVE_TASK_BACKEND_URL": "SCIENCEEVOLVE_INTERNAGENT_BACKEND_URL",
"SCIENCEEVOLVE_TASK_BACKEND_TOKEN": "SCIENCEEVOLVE_INTERNAGENT_BACKEND_TOKEN",
"SCIENCEEVOLVE_TASK_SCOPE_ID": "SCIENCEEVOLVE_INTERNAGENT_SCOPE_ID"
},
"files": {
"task-bridge.cjs": "'use strict';\n// Transport only. Scientific decisions stay in SCIENCEEVOLVE agents; backends expose atomic tools.\nconst { Server } = require('@modelcontextprotocol/sdk/server/index.js');\nconst { StdioServerTransport } = require('@modelcontextprotocol/sdk/server/stdio.js');\nconst { ListToolsRequestSchema, CallToolRequestSchema } = require('@modelcontextprotocol/sdk/types.js');\nconst { randomUUID, createHash } = require('node:crypto');\nconst spec = require('./tools.json');\n\nfunction check(schema, value, at = 'arguments') {\n if (schema.enum && !schema.enum.includes(value)) throw new Error(`${at}: unsupported enum`);\n if (schema.type === 'object') {\n if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error(`${at}: object required`);\n for (const key of schema.required || []) if (!(key in value)) throw new Error(`${at}.${key}: required`);\n for (const [key, item] of Object.entries(value)) {\n if (schema.properties?.[key]) check(schema.properties[key], item, `${at}.${key}`);\n else if (schema.additionalProperties === false) throw new Error(`${at}.${key}: unknown field`);\n }\n } else if (schema.type === 'array') {\n if (!Array.isArray(value)) throw new Error(`${at}: array required`);\n if (schema.minItems !== undefined && value.length < schema.minItems) throw new Error(`${at}: too few items`);\n if (schema.maxItems !== undefined && value.length > schema.maxItems) throw new Error(`${at}: too many items`);\n for (const item of value) check(schema.items, item, `${at}[]`);\n } else if (schema.type === 'string') {\n if (typeof value !== 'string' || value.length < (schema.minLength ?? 0) || value.length > (schema.maxLength ?? Infinity)) throw new Error(`${at}: invalid string`);\n if (schema.pattern && !new RegExp(schema.pattern).test(value)) throw new Error(`${at}: invalid pattern`);\n } else if (schema.type === 'integer') {\n if (!Number.isSafeInteger(value) || value < (schema.minimum ?? -Infinity) || value > (schema.maximum ?? Infinity)) throw new Error(`${at}: invalid integer`);\n } else if (schema.type === 'boolean') {\n if (typeof value !== 'boolean') throw new Error(`${at}: boolean required`);\n }\n}\n\nasync function dispatch(tool, args) {\n check(tool.inputSchema, args);\n const raw = process.env.SCIENCEEVOLVE_TASK_BACKEND_URL;\n const scopeId = process.env.SCIENCEEVOLVE_TASK_SCOPE_ID;\n if (!raw || !scopeId) return { isError: true, content: [{ type: 'text', text: JSON.stringify({ status: 'blocked', reason: 'Configure the method-specific backend URL and a fresh scope ID; no backend is bundled.' }) }] };\n const endpoint = new URL(raw);\n if (!(endpoint.protocol === 'https:' || (endpoint.protocol === 'http:' && ['localhost', '127.0.0.1', '[::1]'].includes(endpoint.hostname))) || endpoint.username || endpoint.password || endpoint.search || endpoint.hash) throw new Error('Use an explicit HTTPS or loopback HTTP endpoint without inline credentials');\n const requestId = tool.mode === 'write' ? args.requestId : randomUUID();\n if (tool.mode === 'write' && !requestId) throw new Error('Mutation requires a stable requestId');\n let response;\n try {\n response = await fetch(endpoint, {\n method: 'POST', redirect: 'error', signal: AbortSignal.timeout(30000),\n headers: { 'content-type': 'application/json', ...(process.env.SCIENCEEVOLVE_TASK_BACKEND_TOKEN ? { authorization: `Bearer ${process.env.SCIENCEEVOLVE_TASK_BACKEND_TOKEN}` } : {}) },\n body: JSON.stringify({ schemaVersion: 1, method: spec.method, scopeId, actor: spec.actor, operation: tool.name, requestId, arguments: args })\n });\n } catch {\n // Never retry a possibly accepted training/physical job automatically.\n return { isError: true, content: [{ type: 'text', text: JSON.stringify({ status: tool.mode === 'write' ? 'outcome_unknown' : 'unavailable', requestId, operation: tool.name, reason: 'Transport failed; reconcile this exact requestId using get_request. Do not create a replacement job.' }) }] };\n }\n if (!response.ok) return { isError: true, content: [{ type: 'text', text: JSON.stringify({ status: tool.mode === 'write' ? 'outcome_unknown' : 'unavailable', requestId, operation: tool.name, httpStatus: response.status, reason: 'Reconcile before replaying any mutation.' }) }] };\n const body = await response.text();\n if (Buffer.byteLength(body) > 2 * 1024 * 1024) throw new Error('Backend response too large; use paged evidence');\n const result = JSON.parse(body);\n if (result.schemaVersion !== 1 || result.method !== spec.method || result.scopeId !== scopeId || result.operation !== tool.name || result.requestId !== requestId) throw new Error(`Mismatched backend receipt; mutation outcome remains unknown: ${requestId}`);\n if (!['ok', 'blocked', 'failed', 'unknown'].includes(result.status)) throw new Error(`Invalid receipt status: ${requestId}`);\n if (!Array.isArray(result.evidence)) throw new Error(`Receipt requires an evidence array: ${requestId}`);\n for (const evidence of result.evidence) {\n if (!evidence || typeof evidence.id !== 'string' || typeof evidence.uri !== 'string' || typeof evidence.kind !== 'string' || !/^[a-f0-9]{64}$/.test(evidence.sha256)) throw new Error(`Malformed evidence reference: ${requestId}`);\n }\n if (tool.mode === 'write' && result.status === 'ok' && result.evidence.length === 0) throw new Error(`Successful mutation requires a durable receipt: ${requestId}`);\n if (tool.name === 'read_artifact' && result.status === 'ok') {\n if (typeof result.data?.text !== 'string' || createHash('sha256').update(result.data.text, 'utf8').digest('hex') !== result.data.sha256) throw new Error('Artifact bytes do not match the claimed SHA-256');\n }\n // Evidence references and an HTTP OK are not a scientific pass. Agents audit actual bytes/results.\n return { isError: result.status !== 'ok', content: [{ type: 'text', text: JSON.stringify(result) }] };\n}\n\nconst server = new Server({ name: `${spec.method}-${spec.actor}-atomic-tools`, version: '1.0.0' }, { capabilities: { tools: {} } });\nserver.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: spec.tools.map(({ mode, ...tool }) => tool) }));\nserver.setRequestHandler(CallToolRequestSchema, async request => {\n const tool = spec.tools.find(item => item.name === request.params.name);\n if (!tool) throw new Error('Tool is not assigned to this role');\n try { return await dispatch(tool, request.params.arguments || {}); }\n catch (error) { return { isError: true, content: [{ type: 'text', text: error.message }] }; }\n});\nserver.connect(new StdioServerTransport());\nprocess.stdin.on('end', () => { server.close().finally(() => process.exit()); });\n\n",
"tools.json": "{\n \"method\": \"internagent-1-5\",\n \"actor\": \"main\",\n \"tools\": [\n {\n \"name\": \"get_capabilities\",\n \"description\": \"Read actual method/tool versions, resources, scope budget, provenance and capability limitations. A design declaration is not a resource probe.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [],\n \"properties\": {}\n }\n },\n {\n \"name\": \"get_state\",\n \"description\": \"Read durable current scope revision, budgets, jobs, graph/memory/weight versions and accepted evidence. Do not infer current tasks from an old predecessor handoff.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [],\n \"properties\": {}\n }\n },\n {\n \"name\": \"get_request\",\n \"description\": \"Reconcile the original durable request without submitting another job; preserve unknown until authoritative evidence exists.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"originalRequestId\"\n ],\n \"properties\": {\n \"originalRequestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"get_job\",\n \"description\": \"Read actual job status, input/output hashes, error or measurement receipts. Accepted/queued is not completed.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"jobId\"\n ],\n \"properties\": {\n \"jobId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"read_artifact\",\n \"description\": \"Read a small retained UTF-8 artifact and verify its SHA-256 bytes; paginate large evidence at the backend.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"artifactId\"\n ],\n \"properties\": {\n \"artifactId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n }\n ]\n}\n"
}
},
"task-preflight": {
"command": "node",
"entrypoint": "task-bridge.cjs",
"args": [],
"envFrom": {
"SCIENCEEVOLVE_TASK_BACKEND_URL": "SCIENCEEVOLVE_INTERNAGENT_BACKEND_URL",
"SCIENCEEVOLVE_TASK_BACKEND_TOKEN": "SCIENCEEVOLVE_INTERNAGENT_BACKEND_TOKEN",
"SCIENCEEVOLVE_TASK_SCOPE_ID": "SCIENCEEVOLVE_INTERNAGENT_SCOPE_ID"
},
"files": {
"task-bridge.cjs": "'use strict';\n// Transport only. Scientific decisions stay in SCIENCEEVOLVE agents; backends expose atomic tools.\nconst { Server } = require('@modelcontextprotocol/sdk/server/index.js');\nconst { StdioServerTransport } = require('@modelcontextprotocol/sdk/server/stdio.js');\nconst { ListToolsRequestSchema, CallToolRequestSchema } = require('@modelcontextprotocol/sdk/types.js');\nconst { randomUUID, createHash } = require('node:crypto');\nconst spec = require('./tools.json');\n\nfunction check(schema, value, at = 'arguments') {\n if (schema.enum && !schema.enum.includes(value)) throw new Error(`${at}: unsupported enum`);\n if (schema.type === 'object') {\n if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error(`${at}: object required`);\n for (const key of schema.required || []) if (!(key in value)) throw new Error(`${at}.${key}: required`);\n for (const [key, item] of Object.entries(value)) {\n if (schema.properties?.[key]) check(schema.properties[key], item, `${at}.${key}`);\n else if (schema.additionalProperties === false) throw new Error(`${at}.${key}: unknown field`);\n }\n } else if (schema.type === 'array') {\n if (!Array.isArray(value)) throw new Error(`${at}: array required`);\n if (schema.minItems !== undefined && value.length < schema.minItems) throw new Error(`${at}: too few items`);\n if (schema.maxItems !== undefined && value.length > schema.maxItems) throw new Error(`${at}: too many items`);\n for (const item of value) check(schema.items, item, `${at}[]`);\n } else if (schema.type === 'string') {\n if (typeof value !== 'string' || value.length < (schema.minLength ?? 0) || value.length > (schema.maxLength ?? Infinity)) throw new Error(`${at}: invalid string`);\n if (schema.pattern && !new RegExp(schema.pattern).test(value)) throw new Error(`${at}: invalid pattern`);\n } else if (schema.type === 'integer') {\n if (!Number.isSafeInteger(value) || value < (schema.minimum ?? -Infinity) || value > (schema.maximum ?? Infinity)) throw new Error(`${at}: invalid integer`);\n } else if (schema.type === 'boolean') {\n if (typeof value !== 'boolean') throw new Error(`${at}: boolean required`);\n }\n}\n\nasync function dispatch(tool, args) {\n check(tool.inputSchema, args);\n const raw = process.env.SCIENCEEVOLVE_TASK_BACKEND_URL;\n const scopeId = process.env.SCIENCEEVOLVE_TASK_SCOPE_ID;\n if (!raw || !scopeId) return { isError: true, content: [{ type: 'text', text: JSON.stringify({ status: 'blocked', reason: 'Configure the method-specific backend URL and a fresh scope ID; no backend is bundled.' }) }] };\n const endpoint = new URL(raw);\n if (!(endpoint.protocol === 'https:' || (endpoint.protocol === 'http:' && ['localhost', '127.0.0.1', '[::1]'].includes(endpoint.hostname))) || endpoint.username || endpoint.password || endpoint.search || endpoint.hash) throw new Error('Use an explicit HTTPS or loopback HTTP endpoint without inline credentials');\n const requestId = tool.mode === 'write' ? args.requestId : randomUUID();\n if (tool.mode === 'write' && !requestId) throw new Error('Mutation requires a stable requestId');\n let response;\n try {\n response = await fetch(endpoint, {\n method: 'POST', redirect: 'error', signal: AbortSignal.timeout(30000),\n headers: { 'content-type': 'application/json', ...(process.env.SCIENCEEVOLVE_TASK_BACKEND_TOKEN ? { authorization: `Bearer ${process.env.SCIENCEEVOLVE_TASK_BACKEND_TOKEN}` } : {}) },\n body: JSON.stringify({ schemaVersion: 1, method: spec.method, scopeId, actor: spec.actor, operation: tool.name, requestId, arguments: args })\n });\n } catch {\n // Never retry a possibly accepted training/physical job automatically.\n return { isError: true, content: [{ type: 'text', text: JSON.stringify({ status: tool.mode === 'write' ? 'outcome_unknown' : 'unavailable', requestId, operation: tool.name, reason: 'Transport failed; reconcile this exact requestId using get_request. Do not create a replacement job.' }) }] };\n }\n if (!response.ok) return { isError: true, content: [{ type: 'text', text: JSON.stringify({ status: tool.mode === 'write' ? 'outcome_unknown' : 'unavailable', requestId, operation: tool.name, httpStatus: response.status, reason: 'Reconcile before replaying any mutation.' }) }] };\n const body = await response.text();\n if (Buffer.byteLength(body) > 2 * 1024 * 1024) throw new Error('Backend response too large; use paged evidence');\n const result = JSON.parse(body);\n if (result.schemaVersion !== 1 || result.method !== spec.method || result.scopeId !== scopeId || result.operation !== tool.name || result.requestId !== requestId) throw new Error(`Mismatched backend receipt; mutation outcome remains unknown: ${requestId}`);\n if (!['ok', 'blocked', 'failed', 'unknown'].includes(result.status)) throw new Error(`Invalid receipt status: ${requestId}`);\n if (!Array.isArray(result.evidence)) throw new Error(`Receipt requires an evidence array: ${requestId}`);\n for (const evidence of result.evidence) {\n if (!evidence || typeof evidence.id !== 'string' || typeof evidence.uri !== 'string' || typeof evidence.kind !== 'string' || !/^[a-f0-9]{64}$/.test(evidence.sha256)) throw new Error(`Malformed evidence reference: ${requestId}`);\n }\n if (tool.mode === 'write' && result.status === 'ok' && result.evidence.length === 0) throw new Error(`Successful mutation requires a durable receipt: ${requestId}`);\n if (tool.name === 'read_artifact' && result.status === 'ok') {\n if (typeof result.data?.text !== 'string' || createHash('sha256').update(result.data.text, 'utf8').digest('hex') !== result.data.sha256) throw new Error('Artifact bytes do not match the claimed SHA-256');\n }\n // Evidence references and an HTTP OK are not a scientific pass. Agents audit actual bytes/results.\n return { isError: result.status !== 'ok', content: [{ type: 'text', text: JSON.stringify(result) }] };\n}\n\nconst server = new Server({ name: `${spec.method}-${spec.actor}-atomic-tools`, version: '1.0.0' }, { capabilities: { tools: {} } });\nserver.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: spec.tools.map(({ mode, ...tool }) => tool) }));\nserver.setRequestHandler(CallToolRequestSchema, async request => {\n const tool = spec.tools.find(item => item.name === request.params.name);\n if (!tool) throw new Error('Tool is not assigned to this role');\n try { return await dispatch(tool, request.params.arguments || {}); }\n catch (error) { return { isError: true, content: [{ type: 'text', text: error.message }] }; }\n});\nserver.connect(new StdioServerTransport());\nprocess.stdin.on('end', () => { server.close().finally(() => process.exit()); });\n\n",
"tools.json": "{\n \"method\": \"internagent-1-5\",\n \"actor\": \"preflight\",\n \"tools\": [\n {\n \"name\": \"get_capabilities\",\n \"description\": \"Read actual method/tool versions, resources, scope budget, provenance and capability limitations. A design declaration is not a resource probe.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [],\n \"properties\": {}\n }\n },\n {\n \"name\": \"get_state\",\n \"description\": \"Read durable current scope revision, budgets, jobs, graph/memory/weight versions and accepted evidence. Do not infer current tasks from an old predecessor handoff.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [],\n \"properties\": {}\n }\n },\n {\n \"name\": \"get_request\",\n \"description\": \"Reconcile the original durable request without submitting another job; preserve unknown until authoritative evidence exists.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"originalRequestId\"\n ],\n \"properties\": {\n \"originalRequestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"get_job\",\n \"description\": \"Read actual job status, input/output hashes, error or measurement receipts. Accepted/queued is not completed.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"jobId\"\n ],\n \"properties\": {\n \"jobId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"read_artifact\",\n \"description\": \"Read a small retained UTF-8 artifact and verify its SHA-256 bytes; paginate large evidence at the backend.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"artifactId\"\n ],\n \"properties\": {\n \"artifactId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"query_knowledge\",\n \"description\": \"Retrieve typed cross-domain graph paths plus dense-vector results, ranking and exact supporting source spans.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"query\"\n ],\n \"properties\": {\n \"query\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"retrieve_memory\",\n \"description\": \"Retrieve an actual SPM, TEM or SKM record with query, similarity, record IDs and injected context; report empty/unavailable explicitly.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"query\",\n \"memoryType\"\n ],\n \"properties\": {\n \"query\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"memoryType\": {\n \"type\": \"string\",\n \"enum\": [\n \"SPM\",\n \"TEM\",\n \"SKM\"\n ]\n }\n }\n }\n }\n ]\n}\n"
}
},
"task-flow_planner": {
"command": "node",
"entrypoint": "task-bridge.cjs",
"args": [],
"envFrom": {
"SCIENCEEVOLVE_TASK_BACKEND_URL": "SCIENCEEVOLVE_INTERNAGENT_BACKEND_URL",
"SCIENCEEVOLVE_TASK_BACKEND_TOKEN": "SCIENCEEVOLVE_INTERNAGENT_BACKEND_TOKEN",
"SCIENCEEVOLVE_TASK_SCOPE_ID": "SCIENCEEVOLVE_INTERNAGENT_SCOPE_ID"
},
"files": {
"task-bridge.cjs": "'use strict';\n// Transport only. Scientific decisions stay in SCIENCEEVOLVE agents; backends expose atomic tools.\nconst { Server } = require('@modelcontextprotocol/sdk/server/index.js');\nconst { StdioServerTransport } = require('@modelcontextprotocol/sdk/server/stdio.js');\nconst { ListToolsRequestSchema, CallToolRequestSchema } = require('@modelcontextprotocol/sdk/types.js');\nconst { randomUUID, createHash } = require('node:crypto');\nconst spec = require('./tools.json');\n\nfunction check(schema, value, at = 'arguments') {\n if (schema.enum && !schema.enum.includes(value)) throw new Error(`${at}: unsupported enum`);\n if (schema.type === 'object') {\n if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error(`${at}: object required`);\n for (const key of schema.required || []) if (!(key in value)) throw new Error(`${at}.${key}: required`);\n for (const [key, item] of Object.entries(value)) {\n if (schema.properties?.[key]) check(schema.properties[key], item, `${at}.${key}`);\n else if (schema.additionalProperties === false) throw new Error(`${at}.${key}: unknown field`);\n }\n } else if (schema.type === 'array') {\n if (!Array.isArray(value)) throw new Error(`${at}: array required`);\n if (schema.minItems !== undefined && value.length < schema.minItems) throw new Error(`${at}: too few items`);\n if (schema.maxItems !== undefined && value.length > schema.maxItems) throw new Error(`${at}: too many items`);\n for (const item of value) check(schema.items, item, `${at}[]`);\n } else if (schema.type === 'string') {\n if (typeof value !== 'string' || value.length < (schema.minLength ?? 0) || value.length > (schema.maxLength ?? Infinity)) throw new Error(`${at}: invalid string`);\n if (schema.pattern && !new RegExp(schema.pattern).test(value)) throw new Error(`${at}: invalid pattern`);\n } else if (schema.type === 'integer') {\n if (!Number.isSafeInteger(value) || value < (schema.minimum ?? -Infinity) || value > (schema.maximum ?? Infinity)) throw new Error(`${at}: invalid integer`);\n } else if (schema.type === 'boolean') {\n if (typeof value !== 'boolean') throw new Error(`${at}: boolean required`);\n }\n}\n\nasync function dispatch(tool, args) {\n check(tool.inputSchema, args);\n const raw = process.env.SCIENCEEVOLVE_TASK_BACKEND_URL;\n const scopeId = process.env.SCIENCEEVOLVE_TASK_SCOPE_ID;\n if (!raw || !scopeId) return { isError: true, content: [{ type: 'text', text: JSON.stringify({ status: 'blocked', reason: 'Configure the method-specific backend URL and a fresh scope ID; no backend is bundled.' }) }] };\n const endpoint = new URL(raw);\n if (!(endpoint.protocol === 'https:' || (endpoint.protocol === 'http:' && ['localhost', '127.0.0.1', '[::1]'].includes(endpoint.hostname))) || endpoint.username || endpoint.password || endpoint.search || endpoint.hash) throw new Error('Use an explicit HTTPS or loopback HTTP endpoint without inline credentials');\n const requestId = tool.mode === 'write' ? args.requestId : randomUUID();\n if (tool.mode === 'write' && !requestId) throw new Error('Mutation requires a stable requestId');\n let response;\n try {\n response = await fetch(endpoint, {\n method: 'POST', redirect: 'error', signal: AbortSignal.timeout(30000),\n headers: { 'content-type': 'application/json', ...(process.env.SCIENCEEVOLVE_TASK_BACKEND_TOKEN ? { authorization: `Bearer ${process.env.SCIENCEEVOLVE_TASK_BACKEND_TOKEN}` } : {}) },\n body: JSON.stringify({ schemaVersion: 1, method: spec.method, scopeId, actor: spec.actor, operation: tool.name, requestId, arguments: args })\n });\n } catch {\n // Never retry a possibly accepted training/physical job automatically.\n return { isError: true, content: [{ type: 'text', text: JSON.stringify({ status: tool.mode === 'write' ? 'outcome_unknown' : 'unavailable', requestId, operation: tool.name, reason: 'Transport failed; reconcile this exact requestId using get_request. Do not create a replacement job.' }) }] };\n }\n if (!response.ok) return { isError: true, content: [{ type: 'text', text: JSON.stringify({ status: tool.mode === 'write' ? 'outcome_unknown' : 'unavailable', requestId, operation: tool.name, httpStatus: response.status, reason: 'Reconcile before replaying any mutation.' }) }] };\n const body = await response.text();\n if (Buffer.byteLength(body) > 2 * 1024 * 1024) throw new Error('Backend response too large; use paged evidence');\n const result = JSON.parse(body);\n if (result.schemaVersion !== 1 || result.method !== spec.method || result.scopeId !== scopeId || result.operation !== tool.name || result.requestId !== requestId) throw new Error(`Mismatched backend receipt; mutation outcome remains unknown: ${requestId}`);\n if (!['ok', 'blocked', 'failed', 'unknown'].includes(result.status)) throw new Error(`Invalid receipt status: ${requestId}`);\n if (!Array.isArray(result.evidence)) throw new Error(`Receipt requires an evidence array: ${requestId}`);\n for (const evidence of result.evidence) {\n if (!evidence || typeof evidence.id !== 'string' || typeof evidence.uri !== 'string' || typeof evidence.kind !== 'string' || !/^[a-f0-9]{64}$/.test(evidence.sha256)) throw new Error(`Malformed evidence reference: ${requestId}`);\n }\n if (tool.mode === 'write' && result.status === 'ok' && result.evidence.length === 0) throw new Error(`Successful mutation requires a durable receipt: ${requestId}`);\n if (tool.name === 'read_artifact' && result.status === 'ok') {\n if (typeof result.data?.text !== 'string' || createHash('sha256').update(result.data.text, 'utf8').digest('hex') !== result.data.sha256) throw new Error('Artifact bytes do not match the claimed SHA-256');\n }\n // Evidence references and an HTTP OK are not a scientific pass. Agents audit actual bytes/results.\n return { isError: result.status !== 'ok', content: [{ type: 'text', text: JSON.stringify(result) }] };\n}\n\nconst server = new Server({ name: `${spec.method}-${spec.actor}-atomic-tools`, version: '1.0.0' }, { capabilities: { tools: {} } });\nserver.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: spec.tools.map(({ mode, ...tool }) => tool) }));\nserver.setRequestHandler(CallToolRequestSchema, async request => {\n const tool = spec.tools.find(item => item.name === request.params.name);\n if (!tool) throw new Error('Tool is not assigned to this role');\n try { return await dispatch(tool, request.params.arguments || {}); }\n catch (error) { return { isError: true, content: [{ type: 'text', text: error.message }] }; }\n});\nserver.connect(new StdioServerTransport());\nprocess.stdin.on('end', () => { server.close().finally(() => process.exit()); });\n\n",
"tools.json": "{\n \"method\": \"internagent-1-5\",\n \"actor\": \"flow_planner\",\n \"tools\": [\n {\n \"name\": \"get_capabilities\",\n \"description\": \"Read actual method/tool versions, resources, scope budget, provenance and capability limitations. A design declaration is not a resource probe.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [],\n \"properties\": {}\n }\n },\n {\n \"name\": \"get_state\",\n \"description\": \"Read durable current scope revision, budgets, jobs, graph/memory/weight versions and accepted evidence. Do not infer current tasks from an old predecessor handoff.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [],\n \"properties\": {}\n }\n },\n {\n \"name\": \"get_request\",\n \"description\": \"Reconcile the original durable request without submitting another job; preserve unknown until authoritative evidence exists.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"originalRequestId\"\n ],\n \"properties\": {\n \"originalRequestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"get_job\",\n \"description\": \"Read actual job status, input/output hashes, error or measurement receipts. Accepted/queued is not completed.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"jobId\"\n ],\n \"properties\": {\n \"jobId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"read_artifact\",\n \"description\": \"Read a small retained UTF-8 artifact and verify its SHA-256 bytes; paginate large evidence at the backend.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"artifactId\"\n ],\n \"properties\": {\n \"artifactId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"retrieve_memory\",\n \"description\": \"Retrieve an actual SPM, TEM or SKM record with query, similarity, record IDs and injected context; report empty/unavailable explicitly.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"query\",\n \"memoryType\"\n ],\n \"properties\": {\n \"query\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"memoryType\": {\n \"type\": \"string\",\n \"enum\": [\n \"SPM\",\n \"TEM\",\n \"SKM\"\n ]\n }\n }\n }\n },\n {\n \"name\": \"query_knowledge\",\n \"description\": \"Retrieve typed cross-domain graph paths plus dense-vector results, ranking and exact supporting source spans.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"query\"\n ],\n \"properties\": {\n \"query\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"plan_flow\",\n \"description\": \"CAS-persist an Agent-authored search/solve/answer FlowGraph revision, typed dependency edges, selected ready nodes and causal evidence. Backend validates, does not autonomously plan.\",\n \"mode\": \"write\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"graph\",\n \"assignments\",\n \"requestId\",\n \"expectedRevision\"\n ],\n \"properties\": {\n \"graph\": {\n \"type\": \"object\",\n \"additionalProperties\": true\n },\n \"assignments\": {\n \"type\": \"object\",\n \"additionalProperties\": true\n },\n \"requestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 128\n },\n \"expectedRevision\": {\n \"type\": \"integer\",\n \"minimum\": 0\n }\n }\n }\n }\n ]\n}\n"
}
},
"task-research_a": {
"command": "node",
"entrypoint": "task-bridge.cjs",
"args": [],
"envFrom": {
"SCIENCEEVOLVE_TASK_BACKEND_URL": "SCIENCEEVOLVE_INTERNAGENT_BACKEND_URL",
"SCIENCEEVOLVE_TASK_BACKEND_TOKEN": "SCIENCEEVOLVE_INTERNAGENT_BACKEND_TOKEN",
"SCIENCEEVOLVE_TASK_SCOPE_ID": "SCIENCEEVOLVE_INTERNAGENT_SCOPE_ID"
},
"files": {
"task-bridge.cjs": "'use strict';\n// Transport only. Scientific decisions stay in SCIENCEEVOLVE agents; backends expose atomic tools.\nconst { Server } = require('@modelcontextprotocol/sdk/server/index.js');\nconst { StdioServerTransport } = require('@modelcontextprotocol/sdk/server/stdio.js');\nconst { ListToolsRequestSchema, CallToolRequestSchema } = require('@modelcontextprotocol/sdk/types.js');\nconst { randomUUID, createHash } = require('node:crypto');\nconst spec = require('./tools.json');\n\nfunction check(schema, value, at = 'arguments') {\n if (schema.enum && !schema.enum.includes(value)) throw new Error(`${at}: unsupported enum`);\n if (schema.type === 'object') {\n if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error(`${at}: object required`);\n for (const key of schema.required || []) if (!(key in value)) throw new Error(`${at}.${key}: required`);\n for (const [key, item] of Object.entries(value)) {\n if (schema.properties?.[key]) check(schema.properties[key], item, `${at}.${key}`);\n else if (schema.additionalProperties === false) throw new Error(`${at}.${key}: unknown field`);\n }\n } else if (schema.type === 'array') {\n if (!Array.isArray(value)) throw new Error(`${at}: array required`);\n if (schema.minItems !== undefined && value.length < schema.minItems) throw new Error(`${at}: too few items`);\n if (schema.maxItems !== undefined && value.length > schema.maxItems) throw new Error(`${at}: too many items`);\n for (const item of value) check(schema.items, item, `${at}[]`);\n } else if (schema.type === 'string') {\n if (typeof value !== 'string' || value.length < (schema.minLength ?? 0) || value.length > (schema.maxLength ?? Infinity)) throw new Error(`${at}: invalid string`);\n if (schema.pattern && !new RegExp(schema.pattern).test(value)) throw new Error(`${at}: invalid pattern`);\n } else if (schema.type === 'integer') {\n if (!Number.isSafeInteger(value) || value < (schema.minimum ?? -Infinity) || value > (schema.maximum ?? Infinity)) throw new Error(`${at}: invalid integer`);\n } else if (schema.type === 'boolean') {\n if (typeof value !== 'boolean') throw new Error(`${at}: boolean required`);\n }\n}\n\nasync function dispatch(tool, args) {\n check(tool.inputSchema, args);\n const raw = process.env.SCIENCEEVOLVE_TASK_BACKEND_URL;\n const scopeId = process.env.SCIENCEEVOLVE_TASK_SCOPE_ID;\n if (!raw || !scopeId) return { isError: true, content: [{ type: 'text', text: JSON.stringify({ status: 'blocked', reason: 'Configure the method-specific backend URL and a fresh scope ID; no backend is bundled.' }) }] };\n const endpoint = new URL(raw);\n if (!(endpoint.protocol === 'https:' || (endpoint.protocol === 'http:' && ['localhost', '127.0.0.1', '[::1]'].includes(endpoint.hostname))) || endpoint.username || endpoint.password || endpoint.search || endpoint.hash) throw new Error('Use an explicit HTTPS or loopback HTTP endpoint without inline credentials');\n const requestId = tool.mode === 'write' ? args.requestId : randomUUID();\n if (tool.mode === 'write' && !requestId) throw new Error('Mutation requires a stable requestId');\n let response;\n try {\n response = await fetch(endpoint, {\n method: 'POST', redirect: 'error', signal: AbortSignal.timeout(30000),\n headers: { 'content-type': 'application/json', ...(process.env.SCIENCEEVOLVE_TASK_BACKEND_TOKEN ? { authorization: `Bearer ${process.env.SCIENCEEVOLVE_TASK_BACKEND_TOKEN}` } : {}) },\n body: JSON.stringify({ schemaVersion: 1, method: spec.method, scopeId, actor: spec.actor, operation: tool.name, requestId, arguments: args })\n });\n } catch {\n // Never retry a possibly accepted training/physical job automatically.\n return { isError: true, content: [{ type: 'text', text: JSON.stringify({ status: tool.mode === 'write' ? 'outcome_unknown' : 'unavailable', requestId, operation: tool.name, reason: 'Transport failed; reconcile this exact requestId using get_request. Do not create a replacement job.' }) }] };\n }\n if (!response.ok) return { isError: true, content: [{ type: 'text', text: JSON.stringify({ status: tool.mode === 'write' ? 'outcome_unknown' : 'unavailable', requestId, operation: tool.name, httpStatus: response.status, reason: 'Reconcile before replaying any mutation.' }) }] };\n const body = await response.text();\n if (Buffer.byteLength(body) > 2 * 1024 * 1024) throw new Error('Backend response too large; use paged evidence');\n const result = JSON.parse(body);\n if (result.schemaVersion !== 1 || result.method !== spec.method || result.scopeId !== scopeId || result.operation !== tool.name || result.requestId !== requestId) throw new Error(`Mismatched backend receipt; mutation outcome remains unknown: ${requestId}`);\n if (!['ok', 'blocked', 'failed', 'unknown'].includes(result.status)) throw new Error(`Invalid receipt status: ${requestId}`);\n if (!Array.isArray(result.evidence)) throw new Error(`Receipt requires an evidence array: ${requestId}`);\n for (const evidence of result.evidence) {\n if (!evidence || typeof evidence.id !== 'string' || typeof evidence.uri !== 'string' || typeof evidence.kind !== 'string' || !/^[a-f0-9]{64}$/.test(evidence.sha256)) throw new Error(`Malformed evidence reference: ${requestId}`);\n }\n if (tool.mode === 'write' && result.status === 'ok' && result.evidence.length === 0) throw new Error(`Successful mutation requires a durable receipt: ${requestId}`);\n if (tool.name === 'read_artifact' && result.status === 'ok') {\n if (typeof result.data?.text !== 'string' || createHash('sha256').update(result.data.text, 'utf8').digest('hex') !== result.data.sha256) throw new Error('Artifact bytes do not match the claimed SHA-256');\n }\n // Evidence references and an HTTP OK are not a scientific pass. Agents audit actual bytes/results.\n return { isError: result.status !== 'ok', content: [{ type: 'text', text: JSON.stringify(result) }] };\n}\n\nconst server = new Server({ name: `${spec.method}-${spec.actor}-atomic-tools`, version: '1.0.0' }, { capabilities: { tools: {} } });\nserver.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: spec.tools.map(({ mode, ...tool }) => tool) }));\nserver.setRequestHandler(CallToolRequestSchema, async request => {\n const tool = spec.tools.find(item => item.name === request.params.name);\n if (!tool) throw new Error('Tool is not assigned to this role');\n try { return await dispatch(tool, request.params.arguments || {}); }\n catch (error) { return { isError: true, content: [{ type: 'text', text: error.message }] }; }\n});\nserver.connect(new StdioServerTransport());\nprocess.stdin.on('end', () => { server.close().finally(() => process.exit()); });\n\n",
"tools.json": "{\n \"method\": \"internagent-1-5\",\n \"actor\": \"research_a\",\n \"tools\": [\n {\n \"name\": \"get_capabilities\",\n \"description\": \"Read actual method/tool versions, resources, scope budget, provenance and capability limitations. A design declaration is not a resource probe.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [],\n \"properties\": {}\n }\n },\n {\n \"name\": \"get_state\",\n \"description\": \"Read durable current scope revision, budgets, jobs, graph/memory/weight versions and accepted evidence. Do not infer current tasks from an old predecessor handoff.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [],\n \"properties\": {}\n }\n },\n {\n \"name\": \"get_request\",\n \"description\": \"Reconcile the original durable request without submitting another job; preserve unknown until authoritative evidence exists.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"originalRequestId\"\n ],\n \"properties\": {\n \"originalRequestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"get_job\",\n \"description\": \"Read actual job status, input/output hashes, error or measurement receipts. Accepted/queued is not completed.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"jobId\"\n ],\n \"properties\": {\n \"jobId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"read_artifact\",\n \"description\": \"Read a small retained UTF-8 artifact and verify its SHA-256 bytes; paginate large evidence at the backend.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"artifactId\"\n ],\n \"properties\": {\n \"artifactId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"retrieve_memory\",\n \"description\": \"Retrieve an actual SPM, TEM or SKM record with query, similarity, record IDs and injected context; report empty/unavailable explicitly.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"query\",\n \"memoryType\"\n ],\n \"properties\": {\n \"query\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"memoryType\": {\n \"type\": \"string\",\n \"enum\": [\n \"SPM\",\n \"TEM\",\n \"SKM\"\n ]\n }\n }\n }\n },\n {\n \"name\": \"search_sources\",\n \"description\": \"Search actual scholarly/web/domain sources and return source IDs, URLs, versions and full-text access references.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"query\",\n \"domains\"\n ],\n \"properties\": {\n \"query\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"domains\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"minItems\": 1,\n \"maxItems\": 100\n }\n }\n }\n },\n {\n \"name\": \"query_knowledge\",\n \"description\": \"Retrieve typed cross-domain graph paths plus dense-vector results, ranking and exact supporting source spans.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"query\"\n ],\n \"properties\": {\n \"query\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"claim_flow_node\",\n \"description\": \"Atomically claim one assigned node only when all required dependencies have accepted results; preserve ownership/epoch and prevent duplicate execution.\",\n \"mode\": \"write\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"nodeId\",\n \"instanceId\",\n \"requestId\",\n \"expectedRevision\"\n ],\n \"properties\": {\n \"nodeId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"instanceId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"requestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 128\n },\n \"expectedRevision\": {\n \"type\": \"integer\",\n \"minimum\": 0\n }\n }\n }\n },\n {\n \"name\": \"commit_flow_result\",\n \"description\": \"Commit actual node evidence/context and graph entities/relations with lease/epoch; failed or unavailable retrieval cannot be marked successful.\",\n \"mode\": \"write\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"nodeId\",\n \"leaseId\",\n \"result\",\n \"requestId\",\n \"expectedRevision\"\n ],\n \"properties\": {\n \"nodeId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"leaseId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"result\": {\n \"type\": \"object\",\n \"additionalProperties\": true\n },\n \"requestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 128\n },\n \"expectedRevision\": {\n \"type\": \"integer\",\n \"minimum\": 0\n }\n }\n }\n },\n {\n \"name\": \"export_evidence\",\n \"description\": \"Create an immutable scope evidence manifest for this actor. Export receipt does not commit SDK branch files or complete a group.\",\n \"mode\": \"write\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"selection\",\n \"requestId\",\n \"expectedRevision\"\n ],\n \"properties\": {\n \"selection\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"minItems\": 1,\n \"maxItems\": 100\n },\n \"requestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 128\n },\n \"expectedRevision\": {\n \"type\": \"integer\",\n \"minimum\": 0\n }\n }\n }\n }\n ]\n}\n"
}
},
"task-research_b": {
"command": "node",
"entrypoint": "task-bridge.cjs",
"args": [],
"envFrom": {
"SCIENCEEVOLVE_TASK_BACKEND_URL": "SCIENCEEVOLVE_INTERNAGENT_BACKEND_URL",
"SCIENCEEVOLVE_TASK_BACKEND_TOKEN": "SCIENCEEVOLVE_INTERNAGENT_BACKEND_TOKEN",
"SCIENCEEVOLVE_TASK_SCOPE_ID": "SCIENCEEVOLVE_INTERNAGENT_SCOPE_ID"
},
"files": {
"task-bridge.cjs": "'use strict';\n// Transport only. Scientific decisions stay in SCIENCEEVOLVE agents; backends expose atomic tools.\nconst { Server } = require('@modelcontextprotocol/sdk/server/index.js');\nconst { StdioServerTransport } = require('@modelcontextprotocol/sdk/server/stdio.js');\nconst { ListToolsRequestSchema, CallToolRequestSchema } = require('@modelcontextprotocol/sdk/types.js');\nconst { randomUUID, createHash } = require('node:crypto');\nconst spec = require('./tools.json');\n\nfunction check(schema, value, at = 'arguments') {\n if (schema.enum && !schema.enum.includes(value)) throw new Error(`${at}: unsupported enum`);\n if (schema.type === 'object') {\n if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error(`${at}: object required`);\n for (const key of schema.required || []) if (!(key in value)) throw new Error(`${at}.${key}: required`);\n for (const [key, item] of Object.entries(value)) {\n if (schema.properties?.[key]) check(schema.properties[key], item, `${at}.${key}`);\n else if (schema.additionalProperties === false) throw new Error(`${at}.${key}: unknown field`);\n }\n } else if (schema.type === 'array') {\n if (!Array.isArray(value)) throw new Error(`${at}: array required`);\n if (schema.minItems !== undefined && value.length < schema.minItems) throw new Error(`${at}: too few items`);\n if (schema.maxItems !== undefined && value.length > schema.maxItems) throw new Error(`${at}: too many items`);\n for (const item of value) check(schema.items, item, `${at}[]`);\n } else if (schema.type === 'string') {\n if (typeof value !== 'string' || value.length < (schema.minLength ?? 0) || value.length > (schema.maxLength ?? Infinity)) throw new Error(`${at}: invalid string`);\n if (schema.pattern && !new RegExp(schema.pattern).test(value)) throw new Error(`${at}: invalid pattern`);\n } else if (schema.type === 'integer') {\n if (!Number.isSafeInteger(value) || value < (schema.minimum ?? -Infinity) || value > (schema.maximum ?? Infinity)) throw new Error(`${at}: invalid integer`);\n } else if (schema.type === 'boolean') {\n if (typeof value !== 'boolean') throw new Error(`${at}: boolean required`);\n }\n}\n\nasync function dispatch(tool, args) {\n check(tool.inputSchema, args);\n const raw = process.env.SCIENCEEVOLVE_TASK_BACKEND_URL;\n const scopeId = process.env.SCIENCEEVOLVE_TASK_SCOPE_ID;\n if (!raw || !scopeId) return { isError: true, content: [{ type: 'text', text: JSON.stringify({ status: 'blocked', reason: 'Configure the method-specific backend URL and a fresh scope ID; no backend is bundled.' }) }] };\n const endpoint = new URL(raw);\n if (!(endpoint.protocol === 'https:' || (endpoint.protocol === 'http:' && ['localhost', '127.0.0.1', '[::1]'].includes(endpoint.hostname))) || endpoint.username || endpoint.password || endpoint.search || endpoint.hash) throw new Error('Use an explicit HTTPS or loopback HTTP endpoint without inline credentials');\n const requestId = tool.mode === 'write' ? args.requestId : randomUUID();\n if (tool.mode === 'write' && !requestId) throw new Error('Mutation requires a stable requestId');\n let response;\n try {\n response = await fetch(endpoint, {\n method: 'POST', redirect: 'error', signal: AbortSignal.timeout(30000),\n headers: { 'content-type': 'application/json', ...(process.env.SCIENCEEVOLVE_TASK_BACKEND_TOKEN ? { authorization: `Bearer ${process.env.SCIENCEEVOLVE_TASK_BACKEND_TOKEN}` } : {}) },\n body: JSON.stringify({ schemaVersion: 1, method: spec.method, scopeId, actor: spec.actor, operation: tool.name, requestId, arguments: args })\n });\n } catch {\n // Never retry a possibly accepted training/physical job automatically.\n return { isError: true, content: [{ type: 'text', text: JSON.stringify({ status: tool.mode === 'write' ? 'outcome_unknown' : 'unavailable', requestId, operation: tool.name, reason: 'Transport failed; reconcile this exact requestId using get_request. Do not create a replacement job.' }) }] };\n }\n if (!response.ok) return { isError: true, content: [{ type: 'text', text: JSON.stringify({ status: tool.mode === 'write' ? 'outcome_unknown' : 'unavailable', requestId, operation: tool.name, httpStatus: response.status, reason: 'Reconcile before replaying any mutation.' }) }] };\n const body = await response.text();\n if (Buffer.byteLength(body) > 2 * 1024 * 1024) throw new Error('Backend response too large; use paged evidence');\n const result = JSON.parse(body);\n if (result.schemaVersion !== 1 || result.method !== spec.method || result.scopeId !== scopeId || result.operation !== tool.name || result.requestId !== requestId) throw new Error(`Mismatched backend receipt; mutation outcome remains unknown: ${requestId}`);\n if (!['ok', 'blocked', 'failed', 'unknown'].includes(result.status)) throw new Error(`Invalid receipt status: ${requestId}`);\n if (!Array.isArray(result.evidence)) throw new Error(`Receipt requires an evidence array: ${requestId}`);\n for (const evidence of result.evidence) {\n if (!evidence || typeof evidence.id !== 'string' || typeof evidence.uri !== 'string' || typeof evidence.kind !== 'string' || !/^[a-f0-9]{64}$/.test(evidence.sha256)) throw new Error(`Malformed evidence reference: ${requestId}`);\n }\n if (tool.mode === 'write' && result.status === 'ok' && result.evidence.length === 0) throw new Error(`Successful mutation requires a durable receipt: ${requestId}`);\n if (tool.name === 'read_artifact' && result.status === 'ok') {\n if (typeof result.data?.text !== 'string' || createHash('sha256').update(result.data.text, 'utf8').digest('hex') !== result.data.sha256) throw new Error('Artifact bytes do not match the claimed SHA-256');\n }\n // Evidence references and an HTTP OK are not a scientific pass. Agents audit actual bytes/results.\n return { isError: result.status !== 'ok', content: [{ type: 'text', text: JSON.stringify(result) }] };\n}\n\nconst server = new Server({ name: `${spec.method}-${spec.actor}-atomic-tools`, version: '1.0.0' }, { capabilities: { tools: {} } });\nserver.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: spec.tools.map(({ mode, ...tool }) => tool) }));\nserver.setRequestHandler(CallToolRequestSchema, async request => {\n const tool = spec.tools.find(item => item.name === request.params.name);\n if (!tool) throw new Error('Tool is not assigned to this role');\n try { return await dispatch(tool, request.params.arguments || {}); }\n catch (error) { return { isError: true, content: [{ type: 'text', text: error.message }] }; }\n});\nserver.connect(new StdioServerTransport());\nprocess.stdin.on('end', () => { server.close().finally(() => process.exit()); });\n\n",
"tools.json": "{\n \"method\": \"internagent-1-5\",\n \"actor\": \"research_b\",\n \"tools\": [\n {\n \"name\": \"get_capabilities\",\n \"description\": \"Read actual method/tool versions, resources, scope budget, provenance and capability limitations. A design declaration is not a resource probe.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [],\n \"properties\": {}\n }\n },\n {\n \"name\": \"get_state\",\n \"description\": \"Read durable current scope revision, budgets, jobs, graph/memory/weight versions and accepted evidence. Do not infer current tasks from an old predecessor handoff.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [],\n \"properties\": {}\n }\n },\n {\n \"name\": \"get_request\",\n \"description\": \"Reconcile the original durable request without submitting another job; preserve unknown until authoritative evidence exists.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"originalRequestId\"\n ],\n \"properties\": {\n \"originalRequestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"get_job\",\n \"description\": \"Read actual job status, input/output hashes, error or measurement receipts. Accepted/queued is not completed.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"jobId\"\n ],\n \"properties\": {\n \"jobId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"read_artifact\",\n \"description\": \"Read a small retained UTF-8 artifact and verify its SHA-256 bytes; paginate large evidence at the backend.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"artifactId\"\n ],\n \"properties\": {\n \"artifactId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"retrieve_memory\",\n \"description\": \"Retrieve an actual SPM, TEM or SKM record with query, similarity, record IDs and injected context; report empty/unavailable explicitly.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"query\",\n \"memoryType\"\n ],\n \"properties\": {\n \"query\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"memoryType\": {\n \"type\": \"string\",\n \"enum\": [\n \"SPM\",\n \"TEM\",\n \"SKM\"\n ]\n }\n }\n }\n },\n {\n \"name\": \"search_sources\",\n \"description\": \"Search actual scholarly/web/domain sources and return source IDs, URLs, versions and full-text access references.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"query\",\n \"domains\"\n ],\n \"properties\": {\n \"query\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"domains\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"minItems\": 1,\n \"maxItems\": 100\n }\n }\n }\n },\n {\n \"name\": \"query_knowledge\",\n \"description\": \"Retrieve typed cross-domain graph paths plus dense-vector results, ranking and exact supporting source spans.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"query\"\n ],\n \"properties\": {\n \"query\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"claim_flow_node\",\n \"description\": \"Atomically claim one assigned node only when all required dependencies have accepted results; preserve ownership/epoch and prevent duplicate execution.\",\n \"mode\": \"write\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"nodeId\",\n \"instanceId\",\n \"requestId\",\n \"expectedRevision\"\n ],\n \"properties\": {\n \"nodeId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"instanceId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"requestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 128\n },\n \"expectedRevision\": {\n \"type\": \"integer\",\n \"minimum\": 0\n }\n }\n }\n },\n {\n \"name\": \"commit_flow_result\",\n \"description\": \"Commit actual node evidence/context and graph entities/relations with lease/epoch; failed or unavailable retrieval cannot be marked successful.\",\n \"mode\": \"write\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"nodeId\",\n \"leaseId\",\n \"result\",\n \"requestId\",\n \"expectedRevision\"\n ],\n \"properties\": {\n \"nodeId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"leaseId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"result\": {\n \"type\": \"object\",\n \"additionalProperties\": true\n },\n \"requestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 128\n },\n \"expectedRevision\": {\n \"type\": \"integer\",\n \"minimum\": 0\n }\n }\n }\n },\n {\n \"name\": \"export_evidence\",\n \"description\": \"Create an immutable scope evidence manifest for this actor. Export receipt does not commit SDK branch files or complete a group.\",\n \"mode\": \"write\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"selection\",\n \"requestId\",\n \"expectedRevision\"\n ],\n \"properties\": {\n \"selection\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"minItems\": 1,\n \"maxItems\": 100\n },\n \"requestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 128\n },\n \"expectedRevision\": {\n \"type\": \"integer\",\n \"minimum\": 0\n }\n }\n }\n }\n ]\n}\n"
}
},
"task-generation": {
"command": "node",
"entrypoint": "task-bridge.cjs",
"args": [],
"envFrom": {
"SCIENCEEVOLVE_TASK_BACKEND_URL": "SCIENCEEVOLVE_INTERNAGENT_BACKEND_URL",
"SCIENCEEVOLVE_TASK_BACKEND_TOKEN": "SCIENCEEVOLVE_INTERNAGENT_BACKEND_TOKEN",
"SCIENCEEVOLVE_TASK_SCOPE_ID": "SCIENCEEVOLVE_INTERNAGENT_SCOPE_ID"
},
"files": {
"task-bridge.cjs": "'use strict';\n// Transport only. Scientific decisions stay in SCIENCEEVOLVE agents; backends expose atomic tools.\nconst { Server } = require('@modelcontextprotocol/sdk/server/index.js');\nconst { StdioServerTransport } = require('@modelcontextprotocol/sdk/server/stdio.js');\nconst { ListToolsRequestSchema, CallToolRequestSchema } = require('@modelcontextprotocol/sdk/types.js');\nconst { randomUUID, createHash } = require('node:crypto');\nconst spec = require('./tools.json');\n\nfunction check(schema, value, at = 'arguments') {\n if (schema.enum && !schema.enum.includes(value)) throw new Error(`${at}: unsupported enum`);\n if (schema.type === 'object') {\n if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error(`${at}: object required`);\n for (const key of schema.required || []) if (!(key in value)) throw new Error(`${at}.${key}: required`);\n for (const [key, item] of Object.entries(value)) {\n if (schema.properties?.[key]) check(schema.properties[key], item, `${at}.${key}`);\n else if (schema.additionalProperties === false) throw new Error(`${at}.${key}: unknown field`);\n }\n } else if (schema.type === 'array') {\n if (!Array.isArray(value)) throw new Error(`${at}: array required`);\n if (schema.minItems !== undefined && value.length < schema.minItems) throw new Error(`${at}: too few items`);\n if (schema.maxItems !== undefined && value.length > schema.maxItems) throw new Error(`${at}: too many items`);\n for (const item of value) check(schema.items, item, `${at}[]`);\n } else if (schema.type === 'string') {\n if (typeof value !== 'string' || value.length < (schema.minLength ?? 0) || value.length > (schema.maxLength ?? Infinity)) throw new Error(`${at}: invalid string`);\n if (schema.pattern && !new RegExp(schema.pattern).test(value)) throw new Error(`${at}: invalid pattern`);\n } else if (schema.type === 'integer') {\n if (!Number.isSafeInteger(value) || value < (schema.minimum ?? -Infinity) || value > (schema.maximum ?? Infinity)) throw new Error(`${at}: invalid integer`);\n } else if (schema.type === 'boolean') {\n if (typeof value !== 'boolean') throw new Error(`${at}: boolean required`);\n }\n}\n\nasync function dispatch(tool, args) {\n check(tool.inputSchema, args);\n const raw = process.env.SCIENCEEVOLVE_TASK_BACKEND_URL;\n const scopeId = process.env.SCIENCEEVOLVE_TASK_SCOPE_ID;\n if (!raw || !scopeId) return { isError: true, content: [{ type: 'text', text: JSON.stringify({ status: 'blocked', reason: 'Configure the method-specific backend URL and a fresh scope ID; no backend is bundled.' }) }] };\n const endpoint = new URL(raw);\n if (!(endpoint.protocol === 'https:' || (endpoint.protocol === 'http:' && ['localhost', '127.0.0.1', '[::1]'].includes(endpoint.hostname))) || endpoint.username || endpoint.password || endpoint.search || endpoint.hash) throw new Error('Use an explicit HTTPS or loopback HTTP endpoint without inline credentials');\n const requestId = tool.mode === 'write' ? args.requestId : randomUUID();\n if (tool.mode === 'write' && !requestId) throw new Error('Mutation requires a stable requestId');\n let response;\n try {\n response = await fetch(endpoint, {\n method: 'POST', redirect: 'error', signal: AbortSignal.timeout(30000),\n headers: { 'content-type': 'application/json', ...(process.env.SCIENCEEVOLVE_TASK_BACKEND_TOKEN ? { authorization: `Bearer ${process.env.SCIENCEEVOLVE_TASK_BACKEND_TOKEN}` } : {}) },\n body: JSON.stringify({ schemaVersion: 1, method: spec.method, scopeId, actor: spec.actor, operation: tool.name, requestId, arguments: args })\n });\n } catch {\n // Never retry a possibly accepted training/physical job automatically.\n return { isError: true, content: [{ type: 'text', text: JSON.stringify({ status: tool.mode === 'write' ? 'outcome_unknown' : 'unavailable', requestId, operation: tool.name, reason: 'Transport failed; reconcile this exact requestId using get_request. Do not create a replacement job.' }) }] };\n }\n if (!response.ok) return { isError: true, content: [{ type: 'text', text: JSON.stringify({ status: tool.mode === 'write' ? 'outcome_unknown' : 'unavailable', requestId, operation: tool.name, httpStatus: response.status, reason: 'Reconcile before replaying any mutation.' }) }] };\n const body = await response.text();\n if (Buffer.byteLength(body) > 2 * 1024 * 1024) throw new Error('Backend response too large; use paged evidence');\n const result = JSON.parse(body);\n if (result.schemaVersion !== 1 || result.method !== spec.method || result.scopeId !== scopeId || result.operation !== tool.name || result.requestId !== requestId) throw new Error(`Mismatched backend receipt; mutation outcome remains unknown: ${requestId}`);\n if (!['ok', 'blocked', 'failed', 'unknown'].includes(result.status)) throw new Error(`Invalid receipt status: ${requestId}`);\n if (!Array.isArray(result.evidence)) throw new Error(`Receipt requires an evidence array: ${requestId}`);\n for (const evidence of result.evidence) {\n if (!evidence || typeof evidence.id !== 'string' || typeof evidence.uri !== 'string' || typeof evidence.kind !== 'string' || !/^[a-f0-9]{64}$/.test(evidence.sha256)) throw new Error(`Malformed evidence reference: ${requestId}`);\n }\n if (tool.mode === 'write' && result.status === 'ok' && result.evidence.length === 0) throw new Error(`Successful mutation requires a durable receipt: ${requestId}`);\n if (tool.name === 'read_artifact' && result.status === 'ok') {\n if (typeof result.data?.text !== 'string' || createHash('sha256').update(result.data.text, 'utf8').digest('hex') !== result.data.sha256) throw new Error('Artifact bytes do not match the claimed SHA-256');\n }\n // Evidence references and an HTTP OK are not a scientific pass. Agents audit actual bytes/results.\n return { isError: result.status !== 'ok', content: [{ type: 'text', text: JSON.stringify(result) }] };\n}\n\nconst server = new Server({ name: `${spec.method}-${spec.actor}-atomic-tools`, version: '1.0.0' }, { capabilities: { tools: {} } });\nserver.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: spec.tools.map(({ mode, ...tool }) => tool) }));\nserver.setRequestHandler(CallToolRequestSchema, async request => {\n const tool = spec.tools.find(item => item.name === request.params.name);\n if (!tool) throw new Error('Tool is not assigned to this role');\n try { return await dispatch(tool, request.params.arguments || {}); }\n catch (error) { return { isError: true, content: [{ type: 'text', text: error.message }] }; }\n});\nserver.connect(new StdioServerTransport());\nprocess.stdin.on('end', () => { server.close().finally(() => process.exit()); });\n\n",
"tools.json": "{\n \"method\": \"internagent-1-5\",\n \"actor\": \"generation\",\n \"tools\": [\n {\n \"name\": \"get_capabilities\",\n \"description\": \"Read actual method/tool versions, resources, scope budget, provenance and capability limitations. A design declaration is not a resource probe.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [],\n \"properties\": {}\n }\n },\n {\n \"name\": \"get_state\",\n \"description\": \"Read durable current scope revision, budgets, jobs, graph/memory/weight versions and accepted evidence. Do not infer current tasks from an old predecessor handoff.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [],\n \"properties\": {}\n }\n },\n {\n \"name\": \"get_request\",\n \"description\": \"Reconcile the original durable request without submitting another job; preserve unknown until authoritative evidence exists.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"originalRequestId\"\n ],\n \"properties\": {\n \"originalRequestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"get_job\",\n \"description\": \"Read actual job status, input/output hashes, error or measurement receipts. Accepted/queued is not completed.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"jobId\"\n ],\n \"properties\": {\n \"jobId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"read_artifact\",\n \"description\": \"Read a small retained UTF-8 artifact and verify its SHA-256 bytes; paginate large evidence at the backend.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"artifactId\"\n ],\n \"properties\": {\n \"artifactId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"retrieve_memory\",\n \"description\": \"Retrieve an actual SPM, TEM or SKM record with query, similarity, record IDs and injected context; report empty/unavailable explicitly.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"query\",\n \"memoryType\"\n ],\n \"properties\": {\n \"query\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"memoryType\": {\n \"type\": \"string\",\n \"enum\": [\n \"SPM\",\n \"TEM\",\n \"SKM\"\n ]\n }\n }\n }\n },\n {\n \"name\": \"query_knowledge\",\n \"description\": \"Retrieve typed cross-domain graph paths plus dense-vector results, ranking and exact supporting source spans.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"query\"\n ],\n \"properties\": {\n \"query\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"register_ideas\",\n \"description\": \"Persist Agent-authored novel ideas, source/memory links, baseline and falsifiable evaluation plan; never launch an external autonomous generator.\",\n \"mode\": \"write\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"ideas\",\n \"requestId\",\n \"expectedRevision\"\n ],\n \"properties\": {\n \"ideas\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"additionalProperties\": true\n },\n \"minItems\": 1,\n \"maxItems\": 20\n },\n \"requestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 128\n },\n \"expectedRevision\": {\n \"type\": \"integer\",\n \"minimum\": 0\n }\n }\n }\n },\n {\n \"name\": \"evaluate_baseline\",\n \"description\": \"Enqueue actual fixed baseline code/protocol with locked data split and scorer. Inspect its real terminal receipt before search.\",\n \"mode\": \"write\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"baselineArtifactId\",\n \"taskManifestId\",\n \"requestId\",\n \"expectedRevision\"\n ],\n \"properties\": {\n \"baselineArtifactId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"taskManifestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"requestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 128\n },\n \"expectedRevision\": {\n \"type\": \"integer\",\n \"minimum\": 0\n }\n }\n }\n }\n ]\n}\n"
}
},
"task-optimizer_a": {
"command": "node",
"entrypoint": "task-bridge.cjs",
"args": [],
"envFrom": {
"SCIENCEEVOLVE_TASK_BACKEND_URL": "SCIENCEEVOLVE_INTERNAGENT_BACKEND_URL",
"SCIENCEEVOLVE_TASK_BACKEND_TOKEN": "SCIENCEEVOLVE_INTERNAGENT_BACKEND_TOKEN",
"SCIENCEEVOLVE_TASK_SCOPE_ID": "SCIENCEEVOLVE_INTERNAGENT_SCOPE_ID"
},
"files": {
"task-bridge.cjs": "'use strict';\n// Transport only. Scientific decisions stay in SCIENCEEVOLVE agents; backends expose atomic tools.\nconst { Server } = require('@modelcontextprotocol/sdk/server/index.js');\nconst { StdioServerTransport } = require('@modelcontextprotocol/sdk/server/stdio.js');\nconst { ListToolsRequestSchema, CallToolRequestSchema } = require('@modelcontextprotocol/sdk/types.js');\nconst { randomUUID, createHash } = require('node:crypto');\nconst spec = require('./tools.json');\n\nfunction check(schema, value, at = 'arguments') {\n if (schema.enum && !schema.enum.includes(value)) throw new Error(`${at}: unsupported enum`);\n if (schema.type === 'object') {\n if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error(`${at}: object required`);\n for (const key of schema.required || []) if (!(key in value)) throw new Error(`${at}.${key}: required`);\n for (const [key, item] of Object.entries(value)) {\n if (schema.properties?.[key]) check(schema.properties[key], item, `${at}.${key}`);\n else if (schema.additionalProperties === false) throw new Error(`${at}.${key}: unknown field`);\n }\n } else if (schema.type === 'array') {\n if (!Array.isArray(value)) throw new Error(`${at}: array required`);\n if (schema.minItems !== undefined && value.length < schema.minItems) throw new Error(`${at}: too few items`);\n if (schema.maxItems !== undefined && value.length > schema.maxItems) throw new Error(`${at}: too many items`);\n for (const item of value) check(schema.items, item, `${at}[]`);\n } else if (schema.type === 'string') {\n if (typeof value !== 'string' || value.length < (schema.minLength ?? 0) || value.length > (schema.maxLength ?? Infinity)) throw new Error(`${at}: invalid string`);\n if (schema.pattern && !new RegExp(schema.pattern).test(value)) throw new Error(`${at}: invalid pattern`);\n } else if (schema.type === 'integer') {\n if (!Number.isSafeInteger(value) || value < (schema.minimum ?? -Infinity) || value > (schema.maximum ?? Infinity)) throw new Error(`${at}: invalid integer`);\n } else if (schema.type === 'boolean') {\n if (typeof value !== 'boolean') throw new Error(`${at}: boolean required`);\n }\n}\n\nasync function dispatch(tool, args) {\n check(tool.inputSchema, args);\n const raw = process.env.SCIENCEEVOLVE_TASK_BACKEND_URL;\n const scopeId = process.env.SCIENCEEVOLVE_TASK_SCOPE_ID;\n if (!raw || !scopeId) return { isError: true, content: [{ type: 'text', text: JSON.stringify({ status: 'blocked', reason: 'Configure the method-specific backend URL and a fresh scope ID; no backend is bundled.' }) }] };\n const endpoint = new URL(raw);\n if (!(endpoint.protocol === 'https:' || (endpoint.protocol === 'http:' && ['localhost', '127.0.0.1', '[::1]'].includes(endpoint.hostname))) || endpoint.username || endpoint.password || endpoint.search || endpoint.hash) throw new Error('Use an explicit HTTPS or loopback HTTP endpoint without inline credentials');\n const requestId = tool.mode === 'write' ? args.requestId : randomUUID();\n if (tool.mode === 'write' && !requestId) throw new Error('Mutation requires a stable requestId');\n let response;\n try {\n response = await fetch(endpoint, {\n method: 'POST', redirect: 'error', signal: AbortSignal.timeout(30000),\n headers: { 'content-type': 'application/json', ...(process.env.SCIENCEEVOLVE_TASK_BACKEND_TOKEN ? { authorization: `Bearer ${process.env.SCIENCEEVOLVE_TASK_BACKEND_TOKEN}` } : {}) },\n body: JSON.stringify({ schemaVersion: 1, method: spec.method, scopeId, actor: spec.actor, operation: tool.name, requestId, arguments: args })\n });\n } catch {\n // Never retry a possibly accepted training/physical job automatically.\n return { isError: true, content: [{ type: 'text', text: JSON.stringify({ status: tool.mode === 'write' ? 'outcome_unknown' : 'unavailable', requestId, operation: tool.name, reason: 'Transport failed; reconcile this exact requestId using get_request. Do not create a replacement job.' }) }] };\n }\n if (!response.ok) return { isError: true, content: [{ type: 'text', text: JSON.stringify({ status: tool.mode === 'write' ? 'outcome_unknown' : 'unavailable', requestId, operation: tool.name, httpStatus: response.status, reason: 'Reconcile before replaying any mutation.' }) }] };\n const body = await response.text();\n if (Buffer.byteLength(body) > 2 * 1024 * 1024) throw new Error('Backend response too large; use paged evidence');\n const result = JSON.parse(body);\n if (result.schemaVersion !== 1 || result.method !== spec.method || result.scopeId !== scopeId || result.operation !== tool.name || result.requestId !== requestId) throw new Error(`Mismatched backend receipt; mutation outcome remains unknown: ${requestId}`);\n if (!['ok', 'blocked', 'failed', 'unknown'].includes(result.status)) throw new Error(`Invalid receipt status: ${requestId}`);\n if (!Array.isArray(result.evidence)) throw new Error(`Receipt requires an evidence array: ${requestId}`);\n for (const evidence of result.evidence) {\n if (!evidence || typeof evidence.id !== 'string' || typeof evidence.uri !== 'string' || typeof evidence.kind !== 'string' || !/^[a-f0-9]{64}$/.test(evidence.sha256)) throw new Error(`Malformed evidence reference: ${requestId}`);\n }\n if (tool.mode === 'write' && result.status === 'ok' && result.evidence.length === 0) throw new Error(`Successful mutation requires a durable receipt: ${requestId}`);\n if (tool.name === 'read_artifact' && result.status === 'ok') {\n if (typeof result.data?.text !== 'string' || createHash('sha256').update(result.data.text, 'utf8').digest('hex') !== result.data.sha256) throw new Error('Artifact bytes do not match the claimed SHA-256');\n }\n // Evidence references and an HTTP OK are not a scientific pass. Agents audit actual bytes/results.\n return { isError: result.status !== 'ok', content: [{ type: 'text', text: JSON.stringify(result) }] };\n}\n\nconst server = new Server({ name: `${spec.method}-${spec.actor}-atomic-tools`, version: '1.0.0' }, { capabilities: { tools: {} } });\nserver.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: spec.tools.map(({ mode, ...tool }) => tool) }));\nserver.setRequestHandler(CallToolRequestSchema, async request => {\n const tool = spec.tools.find(item => item.name === request.params.name);\n if (!tool) throw new Error('Tool is not assigned to this role');\n try { return await dispatch(tool, request.params.arguments || {}); }\n catch (error) { return { isError: true, content: [{ type: 'text', text: error.message }] }; }\n});\nserver.connect(new StdioServerTransport());\nprocess.stdin.on('end', () => { server.close().finally(() => process.exit()); });\n\n",
"tools.json": "{\n \"method\": \"internagent-1-5\",\n \"actor\": \"optimizer_a\",\n \"tools\": [\n {\n \"name\": \"get_capabilities\",\n \"description\": \"Read actual method/tool versions, resources, scope budget, provenance and capability limitations. A design declaration is not a resource probe.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [],\n \"properties\": {}\n }\n },\n {\n \"name\": \"get_state\",\n \"description\": \"Read durable current scope revision, budgets, jobs, graph/memory/weight versions and accepted evidence. Do not infer current tasks from an old predecessor handoff.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [],\n \"properties\": {}\n }\n },\n {\n \"name\": \"get_request\",\n \"description\": \"Reconcile the original durable request without submitting another job; preserve unknown until authoritative evidence exists.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"originalRequestId\"\n ],\n \"properties\": {\n \"originalRequestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"get_job\",\n \"description\": \"Read actual job status, input/output hashes, error or measurement receipts. Accepted/queued is not completed.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"jobId\"\n ],\n \"properties\": {\n \"jobId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"read_artifact\",\n \"description\": \"Read a small retained UTF-8 artifact and verify its SHA-256 bytes; paginate large evidence at the backend.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"artifactId\"\n ],\n \"properties\": {\n \"artifactId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"select_search_context\",\n \"description\": \"Apply the explicit numeric graph-Monte-Carlo selection policy and lease a parent/operator context: primary, intra_branch, cross_branch or multi_branch. Return visit/value, ancestors and reference artifact IDs, not a generated proposal.\",\n \"mode\": \"write\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"ideaId\",\n \"branchId\",\n \"operator\",\n \"requestId\",\n \"expectedRevision\"\n ],\n \"properties\": {\n \"ideaId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"branchId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"operator\": {\n \"type\": \"string\",\n \"enum\": [\n \"primary\",\n \"intra_branch\",\n \"cross_branch\",\n \"multi_branch\"\n ]\n },\n \"requestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 128\n },\n \"expectedRevision\": {\n \"type\": \"integer\",\n \"minimum\": 0\n }\n }\n }\n },\n {\n \"name\": \"submit_candidate\",\n \"description\": \"Persist actual Agent-authored source/protocol and enqueue one atomic experiment tied to selected context, task/split/scorer hashes. No black-box MLEvolve invocation.\",\n \"mode\": \"write\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"contextId\",\n \"source\",\n \"taskManifestId\",\n \"requestId\",\n \"expectedRevision\"\n ],\n \"properties\": {\n \"contextId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"source\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 50000\n },\n \"taskManifestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"requestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 128\n },\n \"expectedRevision\": {\n \"type\": \"integer\",\n \"minimum\": 0\n }\n }\n }\n },\n {\n \"name\": \"record_evaluation\",\n \"description\": \"Backpropagate real experiment metrics through the recorded ancestral path; retain reference edges separately from credit ancestry and keep failures.\",\n \"mode\": \"write\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"candidateId\",\n \"jobReceiptId\",\n \"requestId\",\n \"expectedRevision\"\n ],\n \"properties\": {\n \"candidateId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"jobReceiptId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"requestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 128\n },\n \"expectedRevision\": {\n \"type\": \"integer\",\n \"minimum\": 0\n }\n }\n }\n },\n {\n \"name\": \"export_evidence\",\n \"description\": \"Create an immutable scope evidence manifest for this actor. Export receipt does not commit SDK branch files or complete a group.\",\n \"mode\": \"write\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"selection\",\n \"requestId\",\n \"expectedRevision\"\n ],\n \"properties\": {\n \"selection\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"minItems\": 1,\n \"maxItems\": 100\n },\n \"requestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 128\n },\n \"expectedRevision\": {\n \"type\": \"integer\",\n \"minimum\": 0\n }\n }\n }\n },\n {\n \"name\": \"save_memory\",\n \"description\": \"Append evidence-derived SPM/TEM/SKM with real experiment/source IDs and baseline-relative labels; online save and retrieval are independent controls.\",\n \"mode\": \"write\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"memoryType\",\n \"record\",\n \"requestId\",\n \"expectedRevision\"\n ],\n \"properties\": {\n \"memoryType\": {\n \"type\": \"string\",\n \"enum\": [\n \"SPM\",\n \"TEM\",\n \"SKM\"\n ]\n },\n \"record\": {\n \"type\": \"object\",\n \"additionalProperties\": true\n },\n \"requestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 128\n },\n \"expectedRevision\": {\n \"type\": \"integer\",\n \"minimum\": 0\n }\n }\n }\n }\n ]\n}\n"
}
},
"task-optimizer_b": {
"command": "node",
"entrypoint": "task-bridge.cjs",
"args": [],
"envFrom": {
"SCIENCEEVOLVE_TASK_BACKEND_URL": "SCIENCEEVOLVE_INTERNAGENT_BACKEND_URL",
"SCIENCEEVOLVE_TASK_BACKEND_TOKEN": "SCIENCEEVOLVE_INTERNAGENT_BACKEND_TOKEN",
"SCIENCEEVOLVE_TASK_SCOPE_ID": "SCIENCEEVOLVE_INTERNAGENT_SCOPE_ID"
},
"files": {
"task-bridge.cjs": "'use strict';\n// Transport only. Scientific decisions stay in SCIENCEEVOLVE agents; backends expose atomic tools.\nconst { Server } = require('@modelcontextprotocol/sdk/server/index.js');\nconst { StdioServerTransport } = require('@modelcontextprotocol/sdk/server/stdio.js');\nconst { ListToolsRequestSchema, CallToolRequestSchema } = require('@modelcontextprotocol/sdk/types.js');\nconst { randomUUID, createHash } = require('node:crypto');\nconst spec = require('./tools.json');\n\nfunction check(schema, value, at = 'arguments') {\n if (schema.enum && !schema.enum.includes(value)) throw new Error(`${at}: unsupported enum`);\n if (schema.type === 'object') {\n if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error(`${at}: object required`);\n for (const key of schema.required || []) if (!(key in value)) throw new Error(`${at}.${key}: required`);\n for (const [key, item] of Object.entries(value)) {\n if (schema.properties?.[key]) check(schema.properties[key], item, `${at}.${key}`);\n else if (schema.additionalProperties === false) throw new Error(`${at}.${key}: unknown field`);\n }\n } else if (schema.type === 'array') {\n if (!Array.isArray(value)) throw new Error(`${at}: array required`);\n if (schema.minItems !== undefined && value.length < schema.minItems) throw new Error(`${at}: too few items`);\n if (schema.maxItems !== undefined && value.length > schema.maxItems) throw new Error(`${at}: too many items`);\n for (const item of value) check(schema.items, item, `${at}[]`);\n } else if (schema.type === 'string') {\n if (typeof value !== 'string' || value.length < (schema.minLength ?? 0) || value.length > (schema.maxLength ?? Infinity)) throw new Error(`${at}: invalid string`);\n if (schema.pattern && !new RegExp(schema.pattern).test(value)) throw new Error(`${at}: invalid pattern`);\n } else if (schema.type === 'integer') {\n if (!Number.isSafeInteger(value) || value < (schema.minimum ?? -Infinity) || value > (schema.maximum ?? Infinity)) throw new Error(`${at}: invalid integer`);\n } else if (schema.type === 'boolean') {\n if (typeof value !== 'boolean') throw new Error(`${at}: boolean required`);\n }\n}\n\nasync function dispatch(tool, args) {\n check(tool.inputSchema, args);\n const raw = process.env.SCIENCEEVOLVE_TASK_BACKEND_URL;\n const scopeId = process.env.SCIENCEEVOLVE_TASK_SCOPE_ID;\n if (!raw || !scopeId) return { isError: true, content: [{ type: 'text', text: JSON.stringify({ status: 'blocked', reason: 'Configure the method-specific backend URL and a fresh scope ID; no backend is bundled.' }) }] };\n const endpoint = new URL(raw);\n if (!(endpoint.protocol === 'https:' || (endpoint.protocol === 'http:' && ['localhost', '127.0.0.1', '[::1]'].includes(endpoint.hostname))) || endpoint.username || endpoint.password || endpoint.search || endpoint.hash) throw new Error('Use an explicit HTTPS or loopback HTTP endpoint without inline credentials');\n const requestId = tool.mode === 'write' ? args.requestId : randomUUID();\n if (tool.mode === 'write' && !requestId) throw new Error('Mutation requires a stable requestId');\n let response;\n try {\n response = await fetch(endpoint, {\n method: 'POST', redirect: 'error', signal: AbortSignal.timeout(30000),\n headers: { 'content-type': 'application/json', ...(process.env.SCIENCEEVOLVE_TASK_BACKEND_TOKEN ? { authorization: `Bearer ${process.env.SCIENCEEVOLVE_TASK_BACKEND_TOKEN}` } : {}) },\n body: JSON.stringify({ schemaVersion: 1, method: spec.method, scopeId, actor: spec.actor, operation: tool.name, requestId, arguments: args })\n });\n } catch {\n // Never retry a possibly accepted training/physical job automatically.\n return { isError: true, content: [{ type: 'text', text: JSON.stringify({ status: tool.mode === 'write' ? 'outcome_unknown' : 'unavailable', requestId, operation: tool.name, reason: 'Transport failed; reconcile this exact requestId using get_request. Do not create a replacement job.' }) }] };\n }\n if (!response.ok) return { isError: true, content: [{ type: 'text', text: JSON.stringify({ status: tool.mode === 'write' ? 'outcome_unknown' : 'unavailable', requestId, operation: tool.name, httpStatus: response.status, reason: 'Reconcile before replaying any mutation.' }) }] };\n const body = await response.text();\n if (Buffer.byteLength(body) > 2 * 1024 * 1024) throw new Error('Backend response too large; use paged evidence');\n const result = JSON.parse(body);\n if (result.schemaVersion !== 1 || result.method !== spec.method || result.scopeId !== scopeId || result.operation !== tool.name || result.requestId !== requestId) throw new Error(`Mismatched backend receipt; mutation outcome remains unknown: ${requestId}`);\n if (!['ok', 'blocked', 'failed', 'unknown'].includes(result.status)) throw new Error(`Invalid receipt status: ${requestId}`);\n if (!Array.isArray(result.evidence)) throw new Error(`Receipt requires an evidence array: ${requestId}`);\n for (const evidence of result.evidence) {\n if (!evidence || typeof evidence.id !== 'string' || typeof evidence.uri !== 'string' || typeof evidence.kind !== 'string' || !/^[a-f0-9]{64}$/.test(evidence.sha256)) throw new Error(`Malformed evidence reference: ${requestId}`);\n }\n if (tool.mode === 'write' && result.status === 'ok' && result.evidence.length === 0) throw new Error(`Successful mutation requires a durable receipt: ${requestId}`);\n if (tool.name === 'read_artifact' && result.status === 'ok') {\n if (typeof result.data?.text !== 'string' || createHash('sha256').update(result.data.text, 'utf8').digest('hex') !== result.data.sha256) throw new Error('Artifact bytes do not match the claimed SHA-256');\n }\n // Evidence references and an HTTP OK are not a scientific pass. Agents audit actual bytes/results.\n return { isError: result.status !== 'ok', content: [{ type: 'text', text: JSON.stringify(result) }] };\n}\n\nconst server = new Server({ name: `${spec.method}-${spec.actor}-atomic-tools`, version: '1.0.0' }, { capabilities: { tools: {} } });\nserver.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: spec.tools.map(({ mode, ...tool }) => tool) }));\nserver.setRequestHandler(CallToolRequestSchema, async request => {\n const tool = spec.tools.find(item => item.name === request.params.name);\n if (!tool) throw new Error('Tool is not assigned to this role');\n try { return await dispatch(tool, request.params.arguments || {}); }\n catch (error) { return { isError: true, content: [{ type: 'text', text: error.message }] }; }\n});\nserver.connect(new StdioServerTransport());\nprocess.stdin.on('end', () => { server.close().finally(() => process.exit()); });\n\n",
"tools.json": "{\n \"method\": \"internagent-1-5\",\n \"actor\": \"optimizer_b\",\n \"tools\": [\n {\n \"name\": \"get_capabilities\",\n \"description\": \"Read actual method/tool versions, resources, scope budget, provenance and capability limitations. A design declaration is not a resource probe.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [],\n \"properties\": {}\n }\n },\n {\n \"name\": \"get_state\",\n \"description\": \"Read durable current scope revision, budgets, jobs, graph/memory/weight versions and accepted evidence. Do not infer current tasks from an old predecessor handoff.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [],\n \"properties\": {}\n }\n },\n {\n \"name\": \"get_request\",\n \"description\": \"Reconcile the original durable request without submitting another job; preserve unknown until authoritative evidence exists.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"originalRequestId\"\n ],\n \"properties\": {\n \"originalRequestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"get_job\",\n \"description\": \"Read actual job status, input/output hashes, error or measurement receipts. Accepted/queued is not completed.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"jobId\"\n ],\n \"properties\": {\n \"jobId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"read_artifact\",\n \"description\": \"Read a small retained UTF-8 artifact and verify its SHA-256 bytes; paginate large evidence at the backend.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"artifactId\"\n ],\n \"properties\": {\n \"artifactId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"select_search_context\",\n \"description\": \"Apply the explicit numeric graph-Monte-Carlo selection policy and lease a parent/operator context: primary, intra_branch, cross_branch or multi_branch. Return visit/value, ancestors and reference artifact IDs, not a generated proposal.\",\n \"mode\": \"write\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"ideaId\",\n \"branchId\",\n \"operator\",\n \"requestId\",\n \"expectedRevision\"\n ],\n \"properties\": {\n \"ideaId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"branchId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"operator\": {\n \"type\": \"string\",\n \"enum\": [\n \"primary\",\n \"intra_branch\",\n \"cross_branch\",\n \"multi_branch\"\n ]\n },\n \"requestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 128\n },\n \"expectedRevision\": {\n \"type\": \"integer\",\n \"minimum\": 0\n }\n }\n }\n },\n {\n \"name\": \"submit_candidate\",\n \"description\": \"Persist actual Agent-authored source/protocol and enqueue one atomic experiment tied to selected context, task/split/scorer hashes. No black-box MLEvolve invocation.\",\n \"mode\": \"write\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"contextId\",\n \"source\",\n \"taskManifestId\",\n \"requestId\",\n \"expectedRevision\"\n ],\n \"properties\": {\n \"contextId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"source\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 50000\n },\n \"taskManifestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"requestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 128\n },\n \"expectedRevision\": {\n \"type\": \"integer\",\n \"minimum\": 0\n }\n }\n }\n },\n {\n \"name\": \"record_evaluation\",\n \"description\": \"Backpropagate real experiment metrics through the recorded ancestral path; retain reference edges separately from credit ancestry and keep failures.\",\n \"mode\": \"write\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"candidateId\",\n \"jobReceiptId\",\n \"requestId\",\n \"expectedRevision\"\n ],\n \"properties\": {\n \"candidateId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"jobReceiptId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"requestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 128\n },\n \"expectedRevision\": {\n \"type\": \"integer\",\n \"minimum\": 0\n }\n }\n }\n },\n {\n \"name\": \"export_evidence\",\n \"description\": \"Create an immutable scope evidence manifest for this actor. Export receipt does not commit SDK branch files or complete a group.\",\n \"mode\": \"write\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"selection\",\n \"requestId\",\n \"expectedRevision\"\n ],\n \"properties\": {\n \"selection\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"minItems\": 1,\n \"maxItems\": 100\n },\n \"requestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 128\n },\n \"expectedRevision\": {\n \"type\": \"integer\",\n \"minimum\": 0\n }\n }\n }\n },\n {\n \"name\": \"save_memory\",\n \"description\": \"Append evidence-derived SPM/TEM/SKM with real experiment/source IDs and baseline-relative labels; online save and retrieval are independent controls.\",\n \"mode\": \"write\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"memoryType\",\n \"record\",\n \"requestId\",\n \"expectedRevision\"\n ],\n \"properties\": {\n \"memoryType\": {\n \"type\": \"string\",\n \"enum\": [\n \"SPM\",\n \"TEM\",\n \"SKM\"\n ]\n },\n \"record\": {\n \"type\": \"object\",\n \"additionalProperties\": true\n },\n \"requestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 128\n },\n \"expectedRevision\": {\n \"type\": \"integer\",\n \"minimum\": 0\n }\n }\n }\n }\n ]\n}\n"
}
},
"task-verification": {
"command": "node",
"entrypoint": "task-bridge.cjs",
"args": [],
"envFrom": {
"SCIENCEEVOLVE_TASK_BACKEND_URL": "SCIENCEEVOLVE_INTERNAGENT_BACKEND_URL",
"SCIENCEEVOLVE_TASK_BACKEND_TOKEN": "SCIENCEEVOLVE_INTERNAGENT_BACKEND_TOKEN",
"SCIENCEEVOLVE_TASK_SCOPE_ID": "SCIENCEEVOLVE_INTERNAGENT_SCOPE_ID"
},
"files": {
"task-bridge.cjs": "'use strict';\n// Transport only. Scientific decisions stay in SCIENCEEVOLVE agents; backends expose atomic tools.\nconst { Server } = require('@modelcontextprotocol/sdk/server/index.js');\nconst { StdioServerTransport } = require('@modelcontextprotocol/sdk/server/stdio.js');\nconst { ListToolsRequestSchema, CallToolRequestSchema } = require('@modelcontextprotocol/sdk/types.js');\nconst { randomUUID, createHash } = require('node:crypto');\nconst spec = require('./tools.json');\n\nfunction check(schema, value, at = 'arguments') {\n if (schema.enum && !schema.enum.includes(value)) throw new Error(`${at}: unsupported enum`);\n if (schema.type === 'object') {\n if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error(`${at}: object required`);\n for (const key of schema.required || []) if (!(key in value)) throw new Error(`${at}.${key}: required`);\n for (const [key, item] of Object.entries(value)) {\n if (schema.properties?.[key]) check(schema.properties[key], item, `${at}.${key}`);\n else if (schema.additionalProperties === false) throw new Error(`${at}.${key}: unknown field`);\n }\n } else if (schema.type === 'array') {\n if (!Array.isArray(value)) throw new Error(`${at}: array required`);\n if (schema.minItems !== undefined && value.length < schema.minItems) throw new Error(`${at}: too few items`);\n if (schema.maxItems !== undefined && value.length > schema.maxItems) throw new Error(`${at}: too many items`);\n for (const item of value) check(schema.items, item, `${at}[]`);\n } else if (schema.type === 'string') {\n if (typeof value !== 'string' || value.length < (schema.minLength ?? 0) || value.length > (schema.maxLength ?? Infinity)) throw new Error(`${at}: invalid string`);\n if (schema.pattern && !new RegExp(schema.pattern).test(value)) throw new Error(`${at}: invalid pattern`);\n } else if (schema.type === 'integer') {\n if (!Number.isSafeInteger(value) || value < (schema.minimum ?? -Infinity) || value > (schema.maximum ?? Infinity)) throw new Error(`${at}: invalid integer`);\n } else if (schema.type === 'boolean') {\n if (typeof value !== 'boolean') throw new Error(`${at}: boolean required`);\n }\n}\n\nasync function dispatch(tool, args) {\n check(tool.inputSchema, args);\n const raw = process.env.SCIENCEEVOLVE_TASK_BACKEND_URL;\n const scopeId = process.env.SCIENCEEVOLVE_TASK_SCOPE_ID;\n if (!raw || !scopeId) return { isError: true, content: [{ type: 'text', text: JSON.stringify({ status: 'blocked', reason: 'Configure the method-specific backend URL and a fresh scope ID; no backend is bundled.' }) }] };\n const endpoint = new URL(raw);\n if (!(endpoint.protocol === 'https:' || (endpoint.protocol === 'http:' && ['localhost', '127.0.0.1', '[::1]'].includes(endpoint.hostname))) || endpoint.username || endpoint.password || endpoint.search || endpoint.hash) throw new Error('Use an explicit HTTPS or loopback HTTP endpoint without inline credentials');\n const requestId = tool.mode === 'write' ? args.requestId : randomUUID();\n if (tool.mode === 'write' && !requestId) throw new Error('Mutation requires a stable requestId');\n let response;\n try {\n response = await fetch(endpoint, {\n method: 'POST', redirect: 'error', signal: AbortSignal.timeout(30000),\n headers: { 'content-type': 'application/json', ...(process.env.SCIENCEEVOLVE_TASK_BACKEND_TOKEN ? { authorization: `Bearer ${process.env.SCIENCEEVOLVE_TASK_BACKEND_TOKEN}` } : {}) },\n body: JSON.stringify({ schemaVersion: 1, method: spec.method, scopeId, actor: spec.actor, operation: tool.name, requestId, arguments: args })\n });\n } catch {\n // Never retry a possibly accepted training/physical job automatically.\n return { isError: true, content: [{ type: 'text', text: JSON.stringify({ status: tool.mode === 'write' ? 'outcome_unknown' : 'unavailable', requestId, operation: tool.name, reason: 'Transport failed; reconcile this exact requestId using get_request. Do not create a replacement job.' }) }] };\n }\n if (!response.ok) return { isError: true, content: [{ type: 'text', text: JSON.stringify({ status: tool.mode === 'write' ? 'outcome_unknown' : 'unavailable', requestId, operation: tool.name, httpStatus: response.status, reason: 'Reconcile before replaying any mutation.' }) }] };\n const body = await response.text();\n if (Buffer.byteLength(body) > 2 * 1024 * 1024) throw new Error('Backend response too large; use paged evidence');\n const result = JSON.parse(body);\n if (result.schemaVersion !== 1 || result.method !== spec.method || result.scopeId !== scopeId || result.operation !== tool.name || result.requestId !== requestId) throw new Error(`Mismatched backend receipt; mutation outcome remains unknown: ${requestId}`);\n if (!['ok', 'blocked', 'failed', 'unknown'].includes(result.status)) throw new Error(`Invalid receipt status: ${requestId}`);\n if (!Array.isArray(result.evidence)) throw new Error(`Receipt requires an evidence array: ${requestId}`);\n for (const evidence of result.evidence) {\n if (!evidence || typeof evidence.id !== 'string' || typeof evidence.uri !== 'string' || typeof evidence.kind !== 'string' || !/^[a-f0-9]{64}$/.test(evidence.sha256)) throw new Error(`Malformed evidence reference: ${requestId}`);\n }\n if (tool.mode === 'write' && result.status === 'ok' && result.evidence.length === 0) throw new Error(`Successful mutation requires a durable receipt: ${requestId}`);\n if (tool.name === 'read_artifact' && result.status === 'ok') {\n if (typeof result.data?.text !== 'string' || createHash('sha256').update(result.data.text, 'utf8').digest('hex') !== result.data.sha256) throw new Error('Artifact bytes do not match the claimed SHA-256');\n }\n // Evidence references and an HTTP OK are not a scientific pass. Agents audit actual bytes/results.\n return { isError: result.status !== 'ok', content: [{ type: 'text', text: JSON.stringify(result) }] };\n}\n\nconst server = new Server({ name: `${spec.method}-${spec.actor}-atomic-tools`, version: '1.0.0' }, { capabilities: { tools: {} } });\nserver.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: spec.tools.map(({ mode, ...tool }) => tool) }));\nserver.setRequestHandler(CallToolRequestSchema, async request => {\n const tool = spec.tools.find(item => item.name === request.params.name);\n if (!tool) throw new Error('Tool is not assigned to this role');\n try { return await dispatch(tool, request.params.arguments || {}); }\n catch (error) { return { isError: true, content: [{ type: 'text', text: error.message }] }; }\n});\nserver.connect(new StdioServerTransport());\nprocess.stdin.on('end', () => { server.close().finally(() => process.exit()); });\n\n",
"tools.json": "{\n \"method\": \"internagent-1-5\",\n \"actor\": \"verification\",\n \"tools\": [\n {\n \"name\": \"get_capabilities\",\n \"description\": \"Read actual method/tool versions, resources, scope budget, provenance and capability limitations. A design declaration is not a resource probe.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [],\n \"properties\": {}\n }\n },\n {\n \"name\": \"get_state\",\n \"description\": \"Read durable current scope revision, budgets, jobs, graph/memory/weight versions and accepted evidence. Do not infer current tasks from an old predecessor handoff.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [],\n \"properties\": {}\n }\n },\n {\n \"name\": \"get_request\",\n \"description\": \"Reconcile the original durable request without submitting another job; preserve unknown until authoritative evidence exists.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"originalRequestId\"\n ],\n \"properties\": {\n \"originalRequestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"get_job\",\n \"description\": \"Read actual job status, input/output hashes, error or measurement receipts. Accepted/queued is not completed.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"jobId\"\n ],\n \"properties\": {\n \"jobId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"read_artifact\",\n \"description\": \"Read a small retained UTF-8 artifact and verify its SHA-256 bytes; paginate large evidence at the backend.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"artifactId\"\n ],\n \"properties\": {\n \"artifactId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"query_knowledge\",\n \"description\": \"Retrieve typed cross-domain graph paths plus dense-vector results, ranking and exact supporting source spans.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"query\"\n ],\n \"properties\": {\n \"query\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"export_evidence\",\n \"description\": \"Create an immutable scope evidence manifest for this actor. Export receipt does not commit SDK branch files or complete a group.\",\n \"mode\": \"write\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"selection\",\n \"requestId\",\n \"expectedRevision\"\n ],\n \"properties\": {\n \"selection\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"minItems\": 1,\n \"maxItems\": 100\n },\n \"requestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 128\n },\n \"expectedRevision\": {\n \"type\": \"integer\",\n \"minimum\": 0\n }\n }\n }\n },\n {\n \"name\": \"reevaluate_candidate\",\n \"description\": \"Enqueue an independent repeat of exact retained candidate bytes with locked task/split/scorer and predeclared seeds.\",\n \"mode\": \"write\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"candidateId\",\n \"taskManifestId\",\n \"repeatPlanId\",\n \"requestId\",\n \"expectedRevision\"\n ],\n \"properties\": {\n \"candidateId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"taskManifestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"repeatPlanId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"requestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"expectedRevision\": {\n \"type\": \"integer\",\n \"minimum\": 0\n }\n }\n }\n }\n ]\n}\n"
}
},
"task-evolution": {
"command": "node",
"entrypoint": "task-bridge.cjs",
"args": [],
"envFrom": {
"SCIENCEEVOLVE_TASK_BACKEND_URL": "SCIENCEEVOLVE_INTERNAGENT_BACKEND_URL",
"SCIENCEEVOLVE_TASK_BACKEND_TOKEN": "SCIENCEEVOLVE_INTERNAGENT_BACKEND_TOKEN",
"SCIENCEEVOLVE_TASK_SCOPE_ID": "SCIENCEEVOLVE_INTERNAGENT_SCOPE_ID"
},
"files": {
"task-bridge.cjs": "'use strict';\n// Transport only. Scientific decisions stay in SCIENCEEVOLVE agents; backends expose atomic tools.\nconst { Server } = require('@modelcontextprotocol/sdk/server/index.js');\nconst { StdioServerTransport } = require('@modelcontextprotocol/sdk/server/stdio.js');\nconst { ListToolsRequestSchema, CallToolRequestSchema } = require('@modelcontextprotocol/sdk/types.js');\nconst { randomUUID, createHash } = require('node:crypto');\nconst spec = require('./tools.json');\n\nfunction check(schema, value, at = 'arguments') {\n if (schema.enum && !schema.enum.includes(value)) throw new Error(`${at}: unsupported enum`);\n if (schema.type === 'object') {\n if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error(`${at}: object required`);\n for (const key of schema.required || []) if (!(key in value)) throw new Error(`${at}.${key}: required`);\n for (const [key, item] of Object.entries(value)) {\n if (schema.properties?.[key]) check(schema.properties[key], item, `${at}.${key}`);\n else if (schema.additionalProperties === false) throw new Error(`${at}.${key}: unknown field`);\n }\n } else if (schema.type === 'array') {\n if (!Array.isArray(value)) throw new Error(`${at}: array required`);\n if (schema.minItems !== undefined && value.length < schema.minItems) throw new Error(`${at}: too few items`);\n if (schema.maxItems !== undefined && value.length > schema.maxItems) throw new Error(`${at}: too many items`);\n for (const item of value) check(schema.items, item, `${at}[]`);\n } else if (schema.type === 'string') {\n if (typeof value !== 'string' || value.length < (schema.minLength ?? 0) || value.length > (schema.maxLength ?? Infinity)) throw new Error(`${at}: invalid string`);\n if (schema.pattern && !new RegExp(schema.pattern).test(value)) throw new Error(`${at}: invalid pattern`);\n } else if (schema.type === 'integer') {\n if (!Number.isSafeInteger(value) || value < (schema.minimum ?? -Infinity) || value > (schema.maximum ?? Infinity)) throw new Error(`${at}: invalid integer`);\n } else if (schema.type === 'boolean') {\n if (typeof value !== 'boolean') throw new Error(`${at}: boolean required`);\n }\n}\n\nasync function dispatch(tool, args) {\n check(tool.inputSchema, args);\n const raw = process.env.SCIENCEEVOLVE_TASK_BACKEND_URL;\n const scopeId = process.env.SCIENCEEVOLVE_TASK_SCOPE_ID;\n if (!raw || !scopeId) return { isError: true, content: [{ type: 'text', text: JSON.stringify({ status: 'blocked', reason: 'Configure the method-specific backend URL and a fresh scope ID; no backend is bundled.' }) }] };\n const endpoint = new URL(raw);\n if (!(endpoint.protocol === 'https:' || (endpoint.protocol === 'http:' && ['localhost', '127.0.0.1', '[::1]'].includes(endpoint.hostname))) || endpoint.username || endpoint.password || endpoint.search || endpoint.hash) throw new Error('Use an explicit HTTPS or loopback HTTP endpoint without inline credentials');\n const requestId = tool.mode === 'write' ? args.requestId : randomUUID();\n if (tool.mode === 'write' && !requestId) throw new Error('Mutation requires a stable requestId');\n let response;\n try {\n response = await fetch(endpoint, {\n method: 'POST', redirect: 'error', signal: AbortSignal.timeout(30000),\n headers: { 'content-type': 'application/json', ...(process.env.SCIENCEEVOLVE_TASK_BACKEND_TOKEN ? { authorization: `Bearer ${process.env.SCIENCEEVOLVE_TASK_BACKEND_TOKEN}` } : {}) },\n body: JSON.stringify({ schemaVersion: 1, method: spec.method, scopeId, actor: spec.actor, operation: tool.name, requestId, arguments: args })\n });\n } catch {\n // Never retry a possibly accepted training/physical job automatically.\n return { isError: true, content: [{ type: 'text', text: JSON.stringify({ status: tool.mode === 'write' ? 'outcome_unknown' : 'unavailable', requestId, operation: tool.name, reason: 'Transport failed; reconcile this exact requestId using get_request. Do not create a replacement job.' }) }] };\n }\n if (!response.ok) return { isError: true, content: [{ type: 'text', text: JSON.stringify({ status: tool.mode === 'write' ? 'outcome_unknown' : 'unavailable', requestId, operation: tool.name, httpStatus: response.status, reason: 'Reconcile before replaying any mutation.' }) }] };\n const body = await response.text();\n if (Buffer.byteLength(body) > 2 * 1024 * 1024) throw new Error('Backend response too large; use paged evidence');\n const result = JSON.parse(body);\n if (result.schemaVersion !== 1 || result.method !== spec.method || result.scopeId !== scopeId || result.operation !== tool.name || result.requestId !== requestId) throw new Error(`Mismatched backend receipt; mutation outcome remains unknown: ${requestId}`);\n if (!['ok', 'blocked', 'failed', 'unknown'].includes(result.status)) throw new Error(`Invalid receipt status: ${requestId}`);\n if (!Array.isArray(result.evidence)) throw new Error(`Receipt requires an evidence array: ${requestId}`);\n for (const evidence of result.evidence) {\n if (!evidence || typeof evidence.id !== 'string' || typeof evidence.uri !== 'string' || typeof evidence.kind !== 'string' || !/^[a-f0-9]{64}$/.test(evidence.sha256)) throw new Error(`Malformed evidence reference: ${requestId}`);\n }\n if (tool.mode === 'write' && result.status === 'ok' && result.evidence.length === 0) throw new Error(`Successful mutation requires a durable receipt: ${requestId}`);\n if (tool.name === 'read_artifact' && result.status === 'ok') {\n if (typeof result.data?.text !== 'string' || createHash('sha256').update(result.data.text, 'utf8').digest('hex') !== result.data.sha256) throw new Error('Artifact bytes do not match the claimed SHA-256');\n }\n // Evidence references and an HTTP OK are not a scientific pass. Agents audit actual bytes/results.\n return { isError: result.status !== 'ok', content: [{ type: 'text', text: JSON.stringify(result) }] };\n}\n\nconst server = new Server({ name: `${spec.method}-${spec.actor}-atomic-tools`, version: '1.0.0' }, { capabilities: { tools: {} } });\nserver.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: spec.tools.map(({ mode, ...tool }) => tool) }));\nserver.setRequestHandler(CallToolRequestSchema, async request => {\n const tool = spec.tools.find(item => item.name === request.params.name);\n if (!tool) throw new Error('Tool is not assigned to this role');\n try { return await dispatch(tool, request.params.arguments || {}); }\n catch (error) { return { isError: true, content: [{ type: 'text', text: error.message }] }; }\n});\nserver.connect(new StdioServerTransport());\nprocess.stdin.on('end', () => { server.close().finally(() => process.exit()); });\n\n",
"tools.json": "{\n \"method\": \"internagent-1-5\",\n \"actor\": \"evolution\",\n \"tools\": [\n {\n \"name\": \"get_capabilities\",\n \"description\": \"Read actual method/tool versions, resources, scope budget, provenance and capability limitations. A design declaration is not a resource probe.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [],\n \"properties\": {}\n }\n },\n {\n \"name\": \"get_state\",\n \"description\": \"Read durable current scope revision, budgets, jobs, graph/memory/weight versions and accepted evidence. Do not infer current tasks from an old predecessor handoff.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [],\n \"properties\": {}\n }\n },\n {\n \"name\": \"get_request\",\n \"description\": \"Reconcile the original durable request without submitting another job; preserve unknown until authoritative evidence exists.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"originalRequestId\"\n ],\n \"properties\": {\n \"originalRequestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"get_job\",\n \"description\": \"Read actual job status, input/output hashes, error or measurement receipts. Accepted/queued is not completed.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"jobId\"\n ],\n \"properties\": {\n \"jobId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"read_artifact\",\n \"description\": \"Read a small retained UTF-8 artifact and verify its SHA-256 bytes; paginate large evidence at the backend.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"artifactId\"\n ],\n \"properties\": {\n \"artifactId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"retrieve_memory\",\n \"description\": \"Retrieve an actual SPM, TEM or SKM record with query, similarity, record IDs and injected context; report empty/unavailable explicitly.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"query\",\n \"memoryType\"\n ],\n \"properties\": {\n \"query\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"memoryType\": {\n \"type\": \"string\",\n \"enum\": [\n \"SPM\",\n \"TEM\",\n \"SKM\"\n ]\n }\n }\n }\n },\n {\n \"name\": \"save_memory\",\n \"description\": \"Append evidence-derived SPM/TEM/SKM with real experiment/source IDs and baseline-relative labels; online save and retrieval are independent controls.\",\n \"mode\": \"write\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"memoryType\",\n \"record\",\n \"requestId\",\n \"expectedRevision\"\n ],\n \"properties\": {\n \"memoryType\": {\n \"type\": \"string\",\n \"enum\": [\n \"SPM\",\n \"TEM\",\n \"SKM\"\n ]\n },\n \"record\": {\n \"type\": \"object\",\n \"additionalProperties\": true\n },\n \"requestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 128\n },\n \"expectedRevision\": {\n \"type\": \"integer\",\n \"minimum\": 0\n }\n }\n }\n },\n {\n \"name\": \"update_research_objective\",\n \"description\": \"Persist an Agent-authored task generation-prompt/objective revision and IdeaGraph links from actual paired results, insight and novelty; does not edit SDK workflow.\",\n \"mode\": \"write\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"objective\",\n \"evidenceIds\",\n \"requestId\",\n \"expectedRevision\"\n ],\n \"properties\": {\n \"objective\": {\n \"type\": \"object\",\n \"additionalProperties\": true\n },\n \"evidenceIds\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"minItems\": 1,\n \"maxItems\": 100\n },\n \"requestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 128\n },\n \"expectedRevision\": {\n \"type\": \"integer\",\n \"minimum\": 0\n }\n }\n }\n },\n {\n \"name\": \"export_evidence\",\n \"description\": \"Create an immutable scope evidence manifest for this actor. Export receipt does not commit SDK branch files or complete a group.\",\n \"mode\": \"write\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"selection\",\n \"requestId\",\n \"expectedRevision\"\n ],\n \"properties\": {\n \"selection\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"minItems\": 1,\n \"maxItems\": 100\n },\n \"requestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 128\n },\n \"expectedRevision\": {\n \"type\": \"integer\",\n \"minimum\": 0\n }\n }\n }\n }\n ]\n}\n"
}
},
"task-audit": {
"command": "node",
"entrypoint": "task-bridge.cjs",
"args": [],
"envFrom": {
"SCIENCEEVOLVE_TASK_BACKEND_URL": "SCIENCEEVOLVE_INTERNAGENT_BACKEND_URL",
"SCIENCEEVOLVE_TASK_BACKEND_TOKEN": "SCIENCEEVOLVE_INTERNAGENT_BACKEND_TOKEN",
"SCIENCEEVOLVE_TASK_SCOPE_ID": "SCIENCEEVOLVE_INTERNAGENT_SCOPE_ID"
},
"files": {
"task-bridge.cjs": "'use strict';\n// Transport only. Scientific decisions stay in SCIENCEEVOLVE agents; backends expose atomic tools.\nconst { Server } = require('@modelcontextprotocol/sdk/server/index.js');\nconst { StdioServerTransport } = require('@modelcontextprotocol/sdk/server/stdio.js');\nconst { ListToolsRequestSchema, CallToolRequestSchema } = require('@modelcontextprotocol/sdk/types.js');\nconst { randomUUID, createHash } = require('node:crypto');\nconst spec = require('./tools.json');\n\nfunction check(schema, value, at = 'arguments') {\n if (schema.enum && !schema.enum.includes(value)) throw new Error(`${at}: unsupported enum`);\n if (schema.type === 'object') {\n if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error(`${at}: object required`);\n for (const key of schema.required || []) if (!(key in value)) throw new Error(`${at}.${key}: required`);\n for (const [key, item] of Object.entries(value)) {\n if (schema.properties?.[key]) check(schema.properties[key], item, `${at}.${key}`);\n else if (schema.additionalProperties === false) throw new Error(`${at}.${key}: unknown field`);\n }\n } else if (schema.type === 'array') {\n if (!Array.isArray(value)) throw new Error(`${at}: array required`);\n if (schema.minItems !== undefined && value.length < schema.minItems) throw new Error(`${at}: too few items`);\n if (schema.maxItems !== undefined && value.length > schema.maxItems) throw new Error(`${at}: too many items`);\n for (const item of value) check(schema.items, item, `${at}[]`);\n } else if (schema.type === 'string') {\n if (typeof value !== 'string' || value.length < (schema.minLength ?? 0) || value.length > (schema.maxLength ?? Infinity)) throw new Error(`${at}: invalid string`);\n if (schema.pattern && !new RegExp(schema.pattern).test(value)) throw new Error(`${at}: invalid pattern`);\n } else if (schema.type === 'integer') {\n if (!Number.isSafeInteger(value) || value < (schema.minimum ?? -Infinity) || value > (schema.maximum ?? Infinity)) throw new Error(`${at}: invalid integer`);\n } else if (schema.type === 'boolean') {\n if (typeof value !== 'boolean') throw new Error(`${at}: boolean required`);\n }\n}\n\nasync function dispatch(tool, args) {\n check(tool.inputSchema, args);\n const raw = process.env.SCIENCEEVOLVE_TASK_BACKEND_URL;\n const scopeId = process.env.SCIENCEEVOLVE_TASK_SCOPE_ID;\n if (!raw || !scopeId) return { isError: true, content: [{ type: 'text', text: JSON.stringify({ status: 'blocked', reason: 'Configure the method-specific backend URL and a fresh scope ID; no backend is bundled.' }) }] };\n const endpoint = new URL(raw);\n if (!(endpoint.protocol === 'https:' || (endpoint.protocol === 'http:' && ['localhost', '127.0.0.1', '[::1]'].includes(endpoint.hostname))) || endpoint.username || endpoint.password || endpoint.search || endpoint.hash) throw new Error('Use an explicit HTTPS or loopback HTTP endpoint without inline credentials');\n const requestId = tool.mode === 'write' ? args.requestId : randomUUID();\n if (tool.mode === 'write' && !requestId) throw new Error('Mutation requires a stable requestId');\n let response;\n try {\n response = await fetch(endpoint, {\n method: 'POST', redirect: 'error', signal: AbortSignal.timeout(30000),\n headers: { 'content-type': 'application/json', ...(process.env.SCIENCEEVOLVE_TASK_BACKEND_TOKEN ? { authorization: `Bearer ${process.env.SCIENCEEVOLVE_TASK_BACKEND_TOKEN}` } : {}) },\n body: JSON.stringify({ schemaVersion: 1, method: spec.method, scopeId, actor: spec.actor, operation: tool.name, requestId, arguments: args })\n });\n } catch {\n // Never retry a possibly accepted training/physical job automatically.\n return { isError: true, content: [{ type: 'text', text: JSON.stringify({ status: tool.mode === 'write' ? 'outcome_unknown' : 'unavailable', requestId, operation: tool.name, reason: 'Transport failed; reconcile this exact requestId using get_request. Do not create a replacement job.' }) }] };\n }\n if (!response.ok) return { isError: true, content: [{ type: 'text', text: JSON.stringify({ status: tool.mode === 'write' ? 'outcome_unknown' : 'unavailable', requestId, operation: tool.name, httpStatus: response.status, reason: 'Reconcile before replaying any mutation.' }) }] };\n const body = await response.text();\n if (Buffer.byteLength(body) > 2 * 1024 * 1024) throw new Error('Backend response too large; use paged evidence');\n const result = JSON.parse(body);\n if (result.schemaVersion !== 1 || result.method !== spec.method || result.scopeId !== scopeId || result.operation !== tool.name || result.requestId !== requestId) throw new Error(`Mismatched backend receipt; mutation outcome remains unknown: ${requestId}`);\n if (!['ok', 'blocked', 'failed', 'unknown'].includes(result.status)) throw new Error(`Invalid receipt status: ${requestId}`);\n if (!Array.isArray(result.evidence)) throw new Error(`Receipt requires an evidence array: ${requestId}`);\n for (const evidence of result.evidence) {\n if (!evidence || typeof evidence.id !== 'string' || typeof evidence.uri !== 'string' || typeof evidence.kind !== 'string' || !/^[a-f0-9]{64}$/.test(evidence.sha256)) throw new Error(`Malformed evidence reference: ${requestId}`);\n }\n if (tool.mode === 'write' && result.status === 'ok' && result.evidence.length === 0) throw new Error(`Successful mutation requires a durable receipt: ${requestId}`);\n if (tool.name === 'read_artifact' && result.status === 'ok') {\n if (typeof result.data?.text !== 'string' || createHash('sha256').update(result.data.text, 'utf8').digest('hex') !== result.data.sha256) throw new Error('Artifact bytes do not match the claimed SHA-256');\n }\n // Evidence references and an HTTP OK are not a scientific pass. Agents audit actual bytes/results.\n return { isError: result.status !== 'ok', content: [{ type: 'text', text: JSON.stringify(result) }] };\n}\n\nconst server = new Server({ name: `${spec.method}-${spec.actor}-atomic-tools`, version: '1.0.0' }, { capabilities: { tools: {} } });\nserver.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: spec.tools.map(({ mode, ...tool }) => tool) }));\nserver.setRequestHandler(CallToolRequestSchema, async request => {\n const tool = spec.tools.find(item => item.name === request.params.name);\n if (!tool) throw new Error('Tool is not assigned to this role');\n try { return await dispatch(tool, request.params.arguments || {}); }\n catch (error) { return { isError: true, content: [{ type: 'text', text: error.message }] }; }\n});\nserver.connect(new StdioServerTransport());\nprocess.stdin.on('end', () => { server.close().finally(() => process.exit()); });\n\n",
"tools.json": "{\n \"method\": \"internagent-1-5\",\n \"actor\": \"audit\",\n \"tools\": [\n {\n \"name\": \"get_capabilities\",\n \"description\": \"Read actual method/tool versions, resources, scope budget, provenance and capability limitations. A design declaration is not a resource probe.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [],\n \"properties\": {}\n }\n },\n {\n \"name\": \"get_state\",\n \"description\": \"Read durable current scope revision, budgets, jobs, graph/memory/weight versions and accepted evidence. Do not infer current tasks from an old predecessor handoff.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [],\n \"properties\": {}\n }\n },\n {\n \"name\": \"get_request\",\n \"description\": \"Reconcile the original durable request without submitting another job; preserve unknown until authoritative evidence exists.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"originalRequestId\"\n ],\n \"properties\": {\n \"originalRequestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"get_job\",\n \"description\": \"Read actual job status, input/output hashes, error or measurement receipts. Accepted/queued is not completed.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"jobId\"\n ],\n \"properties\": {\n \"jobId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"read_artifact\",\n \"description\": \"Read a small retained UTF-8 artifact and verify its SHA-256 bytes; paginate large evidence at the backend.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"artifactId\"\n ],\n \"properties\": {\n \"artifactId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"retrieve_memory\",\n \"description\": \"Retrieve an actual SPM, TEM or SKM record with query, similarity, record IDs and injected context; report empty/unavailable explicitly.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"query\",\n \"memoryType\"\n ],\n \"properties\": {\n \"query\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"memoryType\": {\n \"type\": \"string\",\n \"enum\": [\n \"SPM\",\n \"TEM\",\n \"SKM\"\n ]\n }\n }\n }\n },\n {\n \"name\": \"query_knowledge\",\n \"description\": \"Retrieve typed cross-domain graph paths plus dense-vector results, ranking and exact supporting source spans.\",\n \"mode\": \"read\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"query\"\n ],\n \"properties\": {\n \"query\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n }\n }\n }\n },\n {\n \"name\": \"export_evidence\",\n \"description\": \"Create an immutable scope evidence manifest for this actor. Export receipt does not commit SDK branch files or complete a group.\",\n \"mode\": \"write\",\n \"inputSchema\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\n \"selection\",\n \"requestId\",\n \"expectedRevision\"\n ],\n \"properties\": {\n \"selection\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 4000\n },\n \"minItems\": 1,\n \"maxItems\": 100\n },\n \"requestId\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 128\n },\n \"expectedRevision\": {\n \"type\": \"integer\",\n \"minimum\": 0\n }\n }\n }\n }\n ]\n}\n"
}
}
},
"orchestration": {
"schemaVersion": 3,
"agents": [
{
"name": "main",
"template": "main"
},
{
"name": "preflight",
"template": "general"
},
{
"name": "flow_planner",
"template": "general"
},
{
"name": "research_a",
"template": "general"
},
{
"name": "research_b",
"template": "general"
},
{
"name": "generation",
"template": "general"
},
{
"name": "optimizer_a",
"template": "general"
},
{
"name": "optimizer_b",
"template": "general"
},
{
"name": "verification",
"template": "general"
},
{
"name": "evolution",
"template": "general"
},
{
"name": "audit",
"template": "general"
}
],
"collaborations": [
{
"id": "knowledge",
"displayName": "FlowGraph evidence collection",
"memberAgentIds": [],
"renamePolicy": "editable"
},
{
"id": "optimization",
"displayName": "Graph augmented Monte Carlo branches",
"memberAgentIds": [],
"renamePolicy": "editable"
}
],
"scopedWorkflow": {
"schemaVersion": 1,
"rootAgentIds": [
"main",
"preflight",
"flow_planner",
"generation",
"verification",
"evolution",
"audit"
],
"groups": [
{
"id": "knowledge",
"leaderAgentId": "flow_planner",
"allowLeaderReconfiguration": false,
"workflow": {
"nodes": [
{
"kind": "agent",
"nodeId": "evidence_a",
"agentId": "research_a"
},
{
"kind": "agent",
"nodeId": "evidence_b",
"agentId": "research_b"
}
],
"input": {
"source": "input",
"edges": [
{
"kind": "parallel",
"target": "evidence_a"
},
{
"kind": "parallel",
"target": "evidence_b"
}
]
},
"routes": {
"evidence_a": [
{
"kind": "strong",
"target": "finish"
}
],
"evidence_b": [
{
"kind": "strong",
"target": "finish"
}
]
}
}
},
{
"id": "optimization",
"leaderAgentId": "generation",
"allowLeaderReconfiguration": false,
"workflow": {
"nodes": [
{
"kind": "agent",
"nodeId": "search_a",
"agentId": "optimizer_a"
},
{
"kind": "agent",
"nodeId": "search_b",
"agentId": "optimizer_b"
}
],
"input": {
"source": "input",
"edges": [
{
"kind": "parallel",
"target": "search_a"
},
{
"kind": "parallel",
"target": "search_b"
}
]
},
"routes": {
"search_a": [
{
"kind": "strong",
"target": "finish"
}
],
"search_b": [
{
"kind": "strong",
"target": "finish"
}
]
}
}
}
]
},
"input": {
"source": "input",
"target": "preflight"
},
"routes": {
"main": [
{
"kind": "weak",
"target": "preflight"
},
{
"kind": "weak",
"target": "audit"
}
],
"preflight": [
{
"kind": "weak",
"target": "flow_planner"
},
{
"kind": "weak",
"target": "main"
}
],
"flow_planner": [
{
"kind": "weak",
"target": "knowledge"
},
{
"kind": "weak",
"target": "generation"
}
],
"knowledge": [
{
"kind": "strong",
"target": "flow_planner"
}
],
"generation": [
{
"kind": "strong",
"target": "optimization"
}
],
"optimization": [
{
"kind": "strong",
"target": "verification"
}
],
"verification": [
{
"kind": "strong",
"target": "evolution"
}
],
"evolution": [
{
"kind": "weak",
"target": "generation"
},
{
"kind": "weak",
"target": "flow_planner"
},
{
"kind": "weak",
"target": "audit"
}
],
"audit": [
{
"kind": "weak",
"target": "evolution"
},
{
"kind": "weak",
"target": "finish"
}
]
},
"decisionPlans": {
"preflight": "全部关键原子能力真实可用才 flow_planner;否则 Main 请求介入并暂停,不开始付费/物理任务。",
"flow_planner": "依赖满足且仍缺证据则 knowledge;知识覆盖、矛盾处理与来源核验后 generation。跨批次 graph revision/预算保留。",
"evolution": "核对累计轮次和真实 memory 保存/消费;继续实验选 generation,知识缺口选 flow_planner;达到明确停止策略选 audit。不能 silent disable memory。",
"audit": "仅全方法与交付成立才能 finish;未达证据且仍有授权预算交 evolution,缺服务/预算则 Main 请求介入暂停。"
},
"allowMainReconfiguration": false,
"allowUserIntervention": true,
"termination": {
"agent": "audit",
"condition": "真实 Generation→Verification→Evolution 至少两轮;带依赖/来源的知识流、四扩展算子及真实数值回传、三层记忆保存与后续消费、可复核实际评测、独立审核和正式集成交付全部成立。批次调度限制已披露;不宣称原论文全域数值复现。",
"decisionBy": "main",
"automatic": false
},
"resultFormat": {
"presets": [
"markdown",
"code"
],
"custom": "交付 report.md、acceptance.json、evidence-index.json、真实源码/结果/失败回执、版本摘要与 SDK/Git/原目录交付证据。完整方法与缩小/受限模式分开;不以配置校验代替方法验收。"
}
}
}