mindforge-cc 11.8.0 → 11.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "pattern-library.jsonl": {
3
- "lastSync": "2026-06-24T05:48:11.891Z",
3
+ "lastSync": "2026-07-01T05:23:03.053Z",
4
4
  "localCount": 1
5
5
  }
6
6
  }
package/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # Changelog
2
2
 
3
+ ## [11.8.1] — 2026-07-01 — First Stable Release
4
+
5
+ ### Security
6
+ - **mcp-server:** Patched hono to >=4.12.25 — fixes CORS credential reflection, path traversal (Windows), body-limit bypass, Set-Cookie merging, Lambda@Edge header drop
7
+ - **sdk:** Patched picomatch — fixes ReDoS via extglob quantifiers and Method Injection via POSIX character classes
8
+ - **ztai:** Added SECURITY_TIER_3_SIMULATED disclosure constant and startup warning for in-process key simulation
9
+
10
+ ### Fixes
11
+ - `bin/sre/sli-verifier.js`: `simulateShadowWave()` now throws in non-simulate mode — gate with `MINDFORGE_SRE_SIMULATE=true`
12
+ - `bin/spawn-agent.js`: spawn stub now exits 1 with actionable error instead of silently succeeding
13
+ - `bin/memory/eis-client.js`: `resolveRemoteNode()` now throws explicitly instead of returning null
14
+ - `bin/browser/session-manager.js`: added `capabilities.importFromBrowser=false` export
15
+ - `.mindforge/config.json`: `mesh.node_id` changed from "beta-node" placeholder to "auto"
16
+
17
+ ### Docs
18
+ - README: fixed stale version refs (11.5.1→11.8.1), corrected workflow count to 32, added Node.js >=18 prerequisite and Hello World section
19
+ - SECURITY.md: documented Tier-3 simulation scope, audit-hash replay boundary, spawn dispatch status
20
+ - docs/troubleshooting.md: added spawn stub, importFromBrowser, and test cwd entries
21
+ - docs/sdk-reference.md: updated version to 11.8.1, marked unimplemented methods
22
+ - docs/enterprise-setup.md: documented mesh.node_id configuration requirement
23
+
24
+ ### Tests
25
+ - install.test.js + production.test.js: added cwd guard, scoped secrets scan to MindForge root only
26
+
27
+ ---
28
+
3
29
  ## [11.8.0] - 2026-06-24 — Workflow Forge II
4
30
 
5
31
  Expands the Dynamic Workflow Library from 12 to 33 workflows across 5 tiers, adding a new **Beast tier** for compound multi-phase multi-agent workflows with adversarial verification. 21 new workflows added. 92/92 tests pass.
package/MINDFORGE.md CHANGED
@@ -3,10 +3,10 @@
3
3
  ## 1. IDENTITY & VERSIONING
4
4
 
5
5
  [NAME] = MindForge
6
- [VERSION] = 11.8.0
6
+ [VERSION] = 11.8.1
7
7
  [STABLE] = true
8
8
  [MODE] = "Platform Sovereign"
9
- [REQUIRED_CORE_VERSION] = 11.8.0
9
+ [REQUIRED_CORE_VERSION] = 11.8.1
10
10
  [SOVEREIGN_IDENTITY] = true
11
11
  [SRE_LAYER_ENABLED] = true
12
12
 
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  ## Latest: v11.8.0
8
8
 
9
- - **v11.8.0 — "Workflow Forge II".** Expands the Dynamic Workflow Library from 12 to 33 workflows across 5 tiers — adds a new **Beast tier** for compound 5-phase adversarial workflows (security-hardening, accessibility-audit, security-threat-model), plus 18 more across Dev/Ops/Intelligence/Research. 21 new `/mindforge:wf-*` commands. Total: 219 commands.
9
+ - **v11.8.0 — "Workflow Forge II".** Expands the Dynamic Workflow Library from 12 to 32 workflows across 5 tiers — adds a new **Beast tier** for compound 5-phase adversarial workflows (security-hardening, accessibility-audit, security-threat-model), plus 18 more across Dev/Ops/Intelligence/Research. 21 new `/mindforge:wf-*` commands. Total: 219 commands.
10
10
  - **v11.7.0 — "Workflow Forge".** Ships the first Dynamic Workflow Library — 12 pre-built multi-agent workflow scripts that run via Claude Code's `Workflow` tool with true parallel agent execution. Four tiers: Research (deep-research, competitive-analysis, tech-evaluation), Dev (code-audit, feature-planner, pr-review, tdd-sprint, refactor-plan), Ops (incident-response, release-prep), Intelligence (onboard-codebase, perf-optimize). 13 new `/mindforge:wf-*` commands. Total: 198 commands.
11
11
  - **v11.6.0 — "Skill Forge".** Adds 80 community-sourced skills across 8 domains (software-development, github, devops, research, security, creative, data-science, note-taking) — 30 promoted to engine tier for automatic trigger-matching, 50 in the extended tier for explicit activation. Three new slash commands: `/mindforge:systematic-debug`, `/mindforge:skill-tdd`, `/mindforge:skills-index`. Total: 153 skills, 232 engine-tier entries, 185 commands.
12
12
  - **v11.5.1 — Standalone MCP server.** The MindForge MCP server now ships as its own npm package, `mindforge-mcp-server@11.5.1`, listed on the official MCP Registry as `io.github.sairam0424/mindforge`. Add it to Claude Code with one command (see [Use the MCP server](#-use-the-mcp-server-standalone)); it exposes 7 tools over stdio (6 read-only + 1 guarded write).
@@ -14,6 +14,9 @@
14
14
 
15
15
  See [CHANGELOG.md](./CHANGELOG.md) for full release history.
16
16
 
17
+ <details>
18
+ <summary>v11.0.0 — Sovereign Stability highlights</summary>
19
+
17
20
  ## v11.0.0 — Sovereign Stability
18
21
 
19
22
  MindForge v11.0.0 "Sovereign Stability" is a production-hardening release focused on reliability, performance, and real-world deployment readiness. Key highlights:
@@ -27,6 +30,8 @@ MindForge v11.0.0 "Sovereign Stability" is a production-hardening release focuse
27
30
 
28
31
  This release ships 211 personas, 153 skills, 154 specialized subagents, 198 commands, 18 pillars, and 49 swarm templates across 12 engineering domains.
29
32
 
33
+ </details>
34
+
30
35
 
31
36
  ## Installation & Setup
32
37
 
@@ -46,6 +51,8 @@ for all 11 plugins, token-budget guidance, and team setup.
46
51
 
47
52
  ### 🚀 Quick Start (npx — full framework engine)
48
53
 
54
+ **Prerequisites:** Node.js >= 18.0.0
55
+
49
56
  The npx installer also writes the complete `.mindforge/` engine (governance, memory,
50
57
  planning) into your project:
51
58
 
@@ -80,7 +87,7 @@ npx mindforge-cc@latest --antigravity --local
80
87
  ### 🔗 Use the MCP server (standalone)
81
88
 
82
89
  The MindForge MCP server is published as its own npm package,
83
- **`mindforge-mcp-server`** (`11.5.1`), and is listed on the official
90
+ **`mindforge-mcp-server`** (`11.8.1`), and is listed on the official
84
91
  [MCP Registry](https://registry.modelcontextprotocol.io) as
85
92
  `io.github.sairam0424/mindforge`. Wire it into Claude Code with one command:
86
93
 
@@ -102,6 +109,14 @@ It exposes **7 tools over stdio** — 6 read-only plus 1 guarded write:
102
109
 
103
110
  ---
104
111
 
112
+ ## Quick Verification
113
+
114
+ After install, open Claude Code and type:
115
+ - `/mindforge:status` — verify installation and show project health
116
+ - `/mindforge:next` — auto-discover your first task
117
+
118
+ ---
119
+
105
120
  - **Production Hardening (v11.0.0)** — LRU caches, atomic JSON writes, log rotation, HANDOFF validation, and temporal snapshot GC for crash-safe long-running sessions.
106
121
  - **True Wave Parallelism (v11.0.0)** — Semaphore-based concurrent wave execution with configurable max concurrency replaces sequential dispatch.
107
122
  - **Streaming SDK (v11.0.0)** — WebSocket event streaming, `streamExecution()` AsyncIterable, `batchExecute()`, model streaming across Anthropic/OpenAI/Gemini providers.
@@ -383,7 +398,7 @@ See `.mindforge/production/token-optimiser.md`.
383
398
 
384
399
  ## 🚀 Dynamic Workflow Library
385
400
 
386
- 33 pre-built multi-agent workflow scripts that run via Claude Code's `Workflow` tool. Each workflow fans out concurrent agents, synthesizes results, and returns structured output.
401
+ 32 pre-built multi-agent workflow scripts that run via Claude Code's `Workflow` tool. Each workflow fans out concurrent agents, synthesizes results, and returns structured output.
387
402
 
388
403
  **Discover:** `/mindforge:wf-catalog` or `node bin/mindforge-cli.js workflow list`
389
404
 
package/SECURITY.md CHANGED
@@ -136,3 +136,12 @@ narrow disposable memory · scan skills/hooks/MCP/agents as supply-chain artifac
136
136
  ## Contact
137
137
 
138
138
  For security questions that are not vulnerability reports, open a GitHub Discussion with the "security" label.
139
+
140
+ ## Tier-3 Trust (ZTAI Secure Enclave)
141
+ Tier-3 trust in v1.0 uses **in-process key simulation** (`bin/governance/ztai-manager.js` `SecureEnclaveProvider`). Key material resides in the Node.js heap — it is NOT hardware-isolated. A real TPM/HSM provider is planned for v1.2. **Do not use Tier-3 trust for production credential workflows in v1.0.**
142
+
143
+ ## Audit Log Tamper Evidence
144
+ The Merkle chain (`bin/governance/audit-hash.js`) provides tamper-evidence for content and ordering but does not prevent replay of identical entries. Restrict OS-level write access to `.planning/AUDIT.jsonl` to prevent replay attacks.
145
+
146
+ ## Agent Dispatch (spawn mode)
147
+ `bin/spawn-agent.js` spawn mode exits with an error in v1.0 — real agent dispatch is not yet implemented at the shell level. Use Claude Code slash commands (`/mindforge:auto`, `/mindforge:next`) to dispatch agents. Direct shell-level dispatch is planned for v1.1.
@@ -776,8 +776,14 @@ class AutoRunner {
776
776
  const mirrorPath = await this.mirror.replicate(incident);
777
777
  const decision = await this.adversary.runDebate(incident, mirrorPath);
778
778
  if (decision.verdict === 'APPROVED' || decision.verdict === 'AMENDED') {
779
- const baseline = this.verifier.simulateShadowWave(false);
780
- const postFix = this.verifier.simulateShadowWave(true);
779
+ let baseline, postFix;
780
+ try {
781
+ baseline = this.verifier.simulateShadowWave(false);
782
+ postFix = this.verifier.simulateShadowWave(true);
783
+ } catch (e) {
784
+ this.writeAudit({ event: 'sre_sli_unavailable', rid: incident.remediation_id, reason: e.message });
785
+ return;
786
+ }
781
787
  const verification = await this.verifier.verify(baseline, postFix);
782
788
  if (verification.isHealthy) {
783
789
  this.writeAudit({ event: 'sre_remediation_applied', rid: incident.remediation_id, verdict: decision.verdict });
@@ -4,7 +4,7 @@
4
4
  * Kahn topological sort + cycle detection.
5
5
  * Ported from the previously test-only implementation into the real engine.
6
6
  *
7
- * TODO(UC-xx): same-wave file-conflict detection once tasks carry file lists.
7
+ * TODO(UC-xx): same-wave file-conflict detection deferred until handoff schema carries per-task file lists. See docs/architecture/ for scope.
8
8
  * Handoff tasks (see normalizeTask in wave-executor.js and validateHandoff in
9
9
  * state-manager.js) currently expose only id/name/plan/depends_on — there is
10
10
  * no `files` field to compare. A `findFileConflicts(plans)` check (two tasks
@@ -94,4 +94,6 @@ function importFromBrowser(source) {
94
94
  );
95
95
  }
96
96
 
97
- module.exports = { saveSession, loadSession, importFromBrowser };
97
+ const capabilities = { importFromBrowser: false };
98
+
99
+ module.exports = { saveSession, loadSession, importFromBrowser, capabilities };
@@ -9,6 +9,8 @@ const configManager = require('./config-manager');
9
9
 
10
10
  const generateKeyPair = promisify(crypto.generateKeyPair);
11
11
 
12
+ const SECURITY_TIER_3_SIMULATED = true;
13
+
12
14
  /**
13
15
  * Abstract Base Class for Key Providers
14
16
  */
@@ -61,6 +63,9 @@ class LocalKeyProvider extends KeyProvider {
61
63
  class SecureEnclaveProvider extends KeyProvider {
62
64
  constructor() {
63
65
  super();
66
+ console.warn('[ZTAI] WARNING: Tier-3 trust using simulated in-process key storage. ' +
67
+ 'Key material resides in the Node.js heap — not hardware-isolated. ' +
68
+ 'Do not use Tier-3 trust for production credential workflows in v1.0.');
64
69
  this.enclaveStore = new Map(); // DID -> { privateKey, metadata }
65
70
  }
66
71
 
@@ -307,3 +312,4 @@ class ZTAIManager {
307
312
  }
308
313
 
309
314
  module.exports = new ZTAIManager();
315
+ module.exports.SECURITY_TIER_3_SIMULATED = SECURITY_TIER_3_SIMULATED;
@@ -144,9 +144,13 @@ class EISClient {
144
144
  }
145
145
  }
146
146
 
147
- // TODO: implement when remote nodes are available
147
+ // TODO(EIS-remote): implement cross-node context resolution in v1.1
148
148
  async resolveRemoteNode(nodeId) {
149
- return null;
149
+ // TODO(EIS-remote): implement cross-node context resolution in v1.1
150
+ throw new Error(
151
+ `EIS remote node resolution not implemented (nodeId: ${nodeId}). ` +
152
+ 'Cross-node context is local-only in v1.0.'
153
+ );
150
154
  }
151
155
 
152
156
  /**
@@ -125,13 +125,16 @@ async function run() {
125
125
  process.exit(0);
126
126
  }
127
127
 
128
- // Future: Integration with Antigravity / Claude Code runtime
129
- console.log('🛠️ Dispatching to agent runtime...');
130
- // For now, we simulate the environment preparation
131
- setTimeout(() => {
132
- console.log(' Agent environment active.');
133
- process.exit(0);
134
- }, 500);
128
+ // Agent dispatch to Claude Code runtime is not yet implemented.
129
+ // Use Claude Code slash commands to dispatch agents instead.
130
+ console.error(
131
+ 'Agent spawn dispatch not implemented in v1.0.\n' +
132
+ ' Use Claude Code slash commands instead:\n' +
133
+ ' /mindforge:auto — reactive engine start\n' +
134
+ ' /mindforge:next — primary auto-discovery\n' +
135
+ ' See docs/troubleshooting.md for details.'
136
+ );
137
+ process.exit(1);
135
138
  }
136
139
 
137
140
  run().catch(err => {
@@ -66,9 +66,17 @@ class SLIVerifier {
66
66
 
67
67
  /**
68
68
  * Heuristic simulation of a "Shadow Wave" to generate metrics.
69
+ * Gated behind MINDFORGE_SRE_SIMULATE=true — must not run in production
70
+ * without explicit opt-in.
69
71
  */
70
72
  simulateShadowWave(isFixApplied = false) {
71
- // Generate jittery but realistic metrics
73
+ if (process.env.MINDFORGE_SRE_SIMULATE !== 'true') {
74
+ throw new Error(
75
+ '[SRE] simulateShadowWave() called outside simulate mode. ' +
76
+ 'Set MINDFORGE_SRE_SIMULATE=true to enable SLI simulation, ' +
77
+ 'or implement real metric collection from /api/v1/system.'
78
+ );
79
+ }
72
80
  return {
73
81
  latency: 120 + (Math.random() * 20),
74
82
  error_rate: isFixApplied ? 0.001 : 0.05,
@@ -14,7 +14,7 @@ import {
14
14
  } from '@mindforge/sdk';
15
15
  ```
16
16
 
17
- Current SDK version: `10.0.1`
17
+ Current SDK version: `11.8.1`
18
18
 
19
19
  ---
20
20
 
@@ -93,6 +93,18 @@ Returns `true` if the unified SQLite knowledge database (`celestial.db`) exists
93
93
 
94
94
  Returns the absolute path to the project's `celestial.db` SQLite database file.
95
95
 
96
+ #### `importFromBrowser(sessionData: unknown): Promise<void>`
97
+
98
+ Imports a session snapshot captured from a browser environment into the local session store.
99
+
100
+ > **[NOT IMPLEMENTED — v1.0]** This method always throws. Check `sessionManager.capabilities.importFromBrowser === false` before calling. Use `saveSession`/`loadSession` instead.
101
+
102
+ #### `resolveRemoteNode(nodeId: string): Promise<unknown>`
103
+
104
+ Resolves context for a node residing on a remote EIS (Edge Intelligence Shard) instance.
105
+
106
+ > **[NOT IMPLEMENTED — v1.0]** `resolveRemoteNode(nodeId)` always throws. Cross-node context resolution is local-only in v1.0. Planned for v1.1.
107
+
96
108
  ---
97
109
 
98
110
  ## `MindForgeMemory`
@@ -137,3 +137,12 @@ If the above doesn’t resolve it:
137
137
  - **Architecture**: `docs/architecture/V5-ENTERPRISE.md`
138
138
  - **Commands**: `docs/commands-reference.md`
139
139
  - **Personas**: `docs/PERSONAS.md`
140
+
141
+ ## Agent spawn returns immediately with no action
142
+ `spawn` mode in `bin/spawn-agent.js` exits with an error in v1.0. Real agent dispatch requires Claude Code slash commands. Use `/mindforge:auto` or `/mindforge:next` to dispatch agents.
143
+
144
+ ## `importFromBrowser` crashes
145
+ Browser cookie import from native browser profiles is not implemented in v1.0. Use `saveSession`/`loadSession` instead. Check `sessionManager.capabilities.importFromBrowser` before calling.
146
+
147
+ ## Tests fail when run from a parent directory
148
+ All tests must be run from the MindForge project root: `cd /path/to/MindForge && npm test`. Running from the parent workspace will produce false failures.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mindforge-cc",
3
- "version": "11.8.0",
3
+ "version": "11.8.1",
4
4
  "description": "MindForge \u2014 Sovereign Agentic Intelligence Framework. Sovereign Stability: Production-Hardened Agentic Intelligence (v11)",
5
5
  "bin": {
6
6
  "mindforge-cc": "bin/install.js",
@@ -1,32 +0,0 @@
1
- ---
2
- description: "Fan-out web research with adversarial claim verification and cited synthesis"
3
- ---
4
- # /mindforge:wf-deep-research
5
-
6
- Runs the **Deep Research** dynamic workflow.
7
-
8
- ## Usage
9
- `/mindforge:wf-deep-research <your research question>`
10
-
11
- ## What it does
12
- - **Scope**: Decomposes your question into 5 independent search angles
13
- - **Search**: 5 parallel web search agents, one per angle (~30s)
14
- - **Fetch**: Deduplicates URLs, fetches top 15 sources, extracts falsifiable claims
15
- - **Verify**: 3-vote adversarial verification per claim — 2/3 refutes kills a claim
16
- - **Synthesize**: Merges confirmed findings, ranks by confidence, cites all sources
17
-
18
- ## Running
19
-
20
- Invoke via Claude Code's Workflow tool:
21
-
22
- ```
23
- Workflow({
24
- scriptPath: ".mindforge/dynamic-workflows/scripts/deep-research.js",
25
- args: "<your input>"
26
- })
27
- ```
28
-
29
- Or discover via CLI:
30
- ```bash
31
- node bin/mindforge-cli.js workflow info deep-research
32
- ```
@@ -1,32 +0,0 @@
1
- ---
2
- description: "Fan-out web research with adversarial claim verification and cited synthesis"
3
- ---
4
- # /mindforge:wf-deep-research
5
-
6
- Runs the **Deep Research** dynamic workflow.
7
-
8
- ## Usage
9
- `/mindforge:wf-deep-research <your research question>`
10
-
11
- ## What it does
12
- - **Scope**: Decomposes your question into 5 independent search angles
13
- - **Search**: 5 parallel web search agents, one per angle (~30s)
14
- - **Fetch**: Deduplicates URLs, fetches top 15 sources, extracts falsifiable claims
15
- - **Verify**: 3-vote adversarial verification per claim — 2/3 refutes kills a claim
16
- - **Synthesize**: Merges confirmed findings, ranks by confidence, cites all sources
17
-
18
- ## Running
19
-
20
- Invoke via Claude Code's Workflow tool:
21
-
22
- ```
23
- Workflow({
24
- scriptPath: ".mindforge/dynamic-workflows/scripts/deep-research.js",
25
- args: "<your input>"
26
- })
27
- ```
28
-
29
- Or discover via CLI:
30
- ```bash
31
- node bin/mindforge-cli.js workflow info deep-research
32
- ```
@@ -1,151 +0,0 @@
1
- export const meta = {
2
- name: 'deep-research',
3
- description: 'Fan-out web research with adversarial claim verification and cited synthesis',
4
- whenToUse: 'When you need a deep, multi-source, fact-checked research report on any topic',
5
- phases: [
6
- { title: 'Scope', detail: 'Decompose question into 5 search angles' },
7
- { title: 'Search', detail: '5 parallel web search agents, one per angle' },
8
- { title: 'Fetch', detail: 'Dedup URLs, fetch top 15 sources, extract falsifiable claims' },
9
- { title: 'Verify', detail: '3-vote adversarial verification per claim (need 2/3 to kill)' },
10
- { title: 'Synthesize', detail: 'Merge semantic dupes, rank by confidence, cite sources' },
11
- ],
12
- };
13
-
14
- export default async function run({ agent, parallel, pipeline, phase, log, args, budget }) {
15
- const ANGLES_SCHEMA = {
16
- type: 'object',
17
- properties: {
18
- angles: {
19
- type: 'array',
20
- items: { type: 'object', properties: { label: { type: 'string' }, query: { type: 'string' } }, required: ['label', 'query'] },
21
- minItems: 5, maxItems: 5,
22
- },
23
- },
24
- required: ['angles'],
25
- };
26
-
27
- const SEARCH_SCHEMA = {
28
- type: 'object',
29
- properties: {
30
- results: {
31
- type: 'array',
32
- items: { type: 'object', properties: { title: { type: 'string' }, url: { type: 'string' }, snippet: { type: 'string' } }, required: ['title', 'url', 'snippet'] },
33
- },
34
- },
35
- required: ['results'],
36
- };
37
-
38
- const CLAIMS_SCHEMA = {
39
- type: 'object',
40
- properties: {
41
- claims: {
42
- type: 'array',
43
- items: { type: 'object', properties: { claim: { type: 'string' }, source: { type: 'string' }, evidence: { type: 'string' } }, required: ['claim', 'source', 'evidence'] },
44
- },
45
- },
46
- required: ['claims'],
47
- };
48
-
49
- const VERDICT_SCHEMA = {
50
- type: 'object',
51
- properties: { refuted: { type: 'boolean' }, reason: { type: 'string' } },
52
- required: ['refuted', 'reason'],
53
- };
54
-
55
- const SYNTH_SCHEMA = {
56
- type: 'object',
57
- properties: {
58
- summary: { type: 'string' },
59
- findings: {
60
- type: 'array',
61
- items: { type: 'object', properties: { claim: { type: 'string' }, confidence: { type: 'string' }, sources: { type: 'array', items: { type: 'string' } }, evidence: { type: 'string' } }, required: ['claim', 'confidence', 'sources', 'evidence'] },
62
- },
63
- },
64
- required: ['summary', 'findings'],
65
- };
66
-
67
- const question = args || 'No question provided — please pass your research question as args.';
68
-
69
- phase('Scope');
70
- log(`Q: ${question.slice(0, 60)}…`);
71
- const scoped = await agent(
72
- `Decompose this research question into exactly 5 independent search angles. Each angle should approach the topic from a different perspective (e.g., implementation, theory, examples, trade-offs, contrarian view). Question: "${question}"`,
73
- { schema: ANGLES_SCHEMA, label: 'decompose' }
74
- );
75
- const angles = scoped.angles;
76
- log(`Decomposed into ${angles.length} angles: ${angles.map(a => a.label).join(', ')}`);
77
-
78
- phase('Search');
79
- const searchResults = await parallel(
80
- angles.map(angle => () => agent(
81
- `Web search for: "${angle.query}". Return the top 6 most relevant results with title, URL, and a brief snippet explaining why each is relevant to: "${angle.query}"`,
82
- { schema: SEARCH_SCHEMA, label: angle.label }
83
- ))
84
- );
85
-
86
- phase('Fetch');
87
- const allUrls = new Map();
88
- for (const res of searchResults.filter(Boolean)) {
89
- for (const r of res.results) {
90
- if (!allUrls.has(r.url)) allUrls.set(r.url, r);
91
- }
92
- }
93
- const uniqueUrls = [...allUrls.values()].slice(0, 15);
94
- log(`Fetched ${searchResults.filter(Boolean).length * 6} results → ${uniqueUrls.length} unique sources → extracting claims`);
95
-
96
- const claimBatches = await parallel(
97
- uniqueUrls.map(src => () => agent(
98
- `Read this source and extract up to 5 specific, falsifiable factual claims from it. Only extract claims that are directly relevant to: "${question}". Source URL: ${src.url}\nSnippet: ${src.snippet}`,
99
- { schema: CLAIMS_SCHEMA, label: `claims:${src.url.slice(8, 40)}` }
100
- ))
101
- );
102
- const allClaims = claimBatches.filter(Boolean).flatMap(b => b.claims).slice(0, 25);
103
- log(`Extracted ${allClaims.length} claims → verifying top 25`);
104
-
105
- phase('Verify');
106
- const verified = await parallel(
107
- allClaims.map(c => () =>
108
- parallel([
109
- () => agent(`Try to REFUTE this claim. Default to refuted=true if uncertain or unverifiable. Claim: "${c.claim}"`, { schema: VERDICT_SCHEMA, label: `verify-1:${c.claim.slice(0, 30)}` }),
110
- () => agent(`Adversarially challenge this claim from a different angle. Default to refuted=true if you cannot confirm it. Claim: "${c.claim}"`, { schema: VERDICT_SCHEMA, label: `verify-2:${c.claim.slice(0, 30)}` }),
111
- () => agent(`As a skeptical fact-checker, evaluate this claim. Default to refuted=true if evidence is weak. Claim: "${c.claim}"`, { schema: VERDICT_SCHEMA, label: `verify-3:${c.claim.slice(0, 30)}` }),
112
- ]).then(votes => {
113
- const refutes = votes.filter(Boolean).filter(v => v.refuted).length;
114
- return { ...c, survives: refutes <= 1, votes: `${3 - refutes}-${refutes}` };
115
- })
116
- )
117
- );
118
- const confirmed = verified.filter(Boolean).filter(c => c.survives);
119
- const killed = verified.filter(Boolean).filter(c => !c.survives);
120
- log(`Verify done: ${allClaims.length} claims → ${confirmed.length} confirmed, ${killed.length} killed`);
121
-
122
- phase('Synthesize');
123
- const synthesis = await agent(
124
- `Synthesize these verified research findings into a comprehensive report answering: "${question}"
125
-
126
- Confirmed findings (${confirmed.length}):
127
- ${confirmed.map((c, i) => `${i + 1}. [${c.votes}] ${c.claim} (source: ${c.source})`).join('\n')}
128
-
129
- Killed findings (${killed.length}):
130
- ${killed.map(c => `- [${c.votes}] ${c.claim}`).join('\n')}
131
-
132
- Produce a clear summary and a ranked findings list. For each finding, state the claim, confidence level (high/medium/low), sources, and evidence.`,
133
- { schema: SYNTH_SCHEMA, label: 'synthesize' }
134
- );
135
-
136
- return {
137
- question,
138
- summary: synthesis.summary,
139
- findings: synthesis.findings,
140
- refuted: killed.map(c => ({ claim: c.claim, vote: c.votes, source: c.source })),
141
- sources: uniqueUrls.map(u => u.url),
142
- stats: {
143
- angles: angles.length,
144
- sourcesFetched: uniqueUrls.length,
145
- claimsExtracted: allClaims.length,
146
- claimsVerified: allClaims.length,
147
- confirmed: confirmed.length,
148
- killed: killed.length,
149
- },
150
- };
151
- }