@heretek-ai/epistemic-swarm 0.4.8 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/.agents/skills/darkharvest/SKILL.md +13 -0
  2. package/.omp/commands/darkharvest.md +11 -0
  3. package/README.md +4 -0
  4. package/bin/cli.js +14 -0
  5. package/config/opencode-snippet.json +14 -1
  6. package/extensions/pi/index.js +47 -1
  7. package/package.json +5 -3
  8. package/plugins/antigravity/skills/darkharvest/SKILL.md +13 -0
  9. package/plugins/codex/skills/darkharvest/SKILL.md +13 -0
  10. package/plugins/gemini/commands/darkharvest.toml +8 -0
  11. package/plugins/gemini/skills/darkharvest/SKILL.md +13 -0
  12. package/plugins/opencode/index.js +49 -2
  13. package/prompts/agent_darkharvest.md +91 -0
  14. package/runner/__pycache__/__init__.cpython-311.pyc +0 -0
  15. package/runner/__pycache__/auctioneer.cpython-311.pyc +0 -0
  16. package/runner/__pycache__/auditor_engine.cpython-311.pyc +0 -0
  17. package/runner/__pycache__/claim_store.cpython-311.pyc +0 -0
  18. package/runner/__pycache__/claim_witness.cpython-311.pyc +0 -0
  19. package/runner/__pycache__/living_dossiers.cpython-311.pyc +0 -0
  20. package/runner/__pycache__/mcp_protocol.cpython-311.pyc +0 -0
  21. package/runner/__pycache__/mcp_server.cpython-311.pyc +0 -0
  22. package/runner/__pycache__/path_safety.cpython-311.pyc +0 -0
  23. package/runner/__pycache__/pcrb.cpython-311.pyc +0 -0
  24. package/runner/__pycache__/pcrb_verify.cpython-311.pyc +0 -0
  25. package/runner/__pycache__/refinement.cpython-311.pyc +0 -0
  26. package/runner/__pycache__/research_swarm.cpython-311.pyc +0 -0
  27. package/runner/__pycache__/state_machine.cpython-311.pyc +0 -0
  28. package/runner/mcp_server.py +202 -62
  29. package/runner/research_swarm.py +138 -16
  30. package/runner/tests/__pycache__/test_auction_order.cpython-311.pyc +0 -0
  31. package/runner/tests/__pycache__/test_bet1_spike.cpython-311.pyc +0 -0
  32. package/runner/tests/__pycache__/test_claim_store.cpython-311.pyc +0 -0
  33. package/runner/tests/__pycache__/test_claim_witness.cpython-311.pyc +0 -0
  34. package/runner/tests/__pycache__/test_domain_packs.cpython-311.pyc +0 -0
  35. package/runner/tests/__pycache__/test_fleet_seam.cpython-311.pyc +0 -0
  36. package/runner/tests/__pycache__/test_living_dossiers.cpython-311.pyc +0 -0
  37. package/runner/tests/__pycache__/test_mcp_server.cpython-311.pyc +0 -0
  38. package/runner/tests/__pycache__/test_opencode_ux.cpython-311.pyc +0 -0
  39. package/runner/tests/__pycache__/test_pcrb.cpython-311.pyc +0 -0
  40. package/runner/tests/__pycache__/test_refinement.cpython-311.pyc +0 -0
  41. package/runner/tests/__pycache__/test_swarm.cpython-311.pyc +0 -0
  42. package/runner/tests/__pycache__/test_sweep_regressions.cpython-311.pyc +0 -0
  43. package/runner/tests/__pycache__/test_webcache.cpython-311.pyc +0 -0
  44. package/runner/tests/test_mcp_server.py +80 -37
  45. package/runner/tests/test_opencode_ux.py +27 -8
  46. package/runner/tests/test_swarm.py +12 -0
  47. package/runner/tests/test_sweep_regressions.py +47 -0
  48. package/scripts/__pycache__/bet1_advisory_spike.cpython-311.pyc +0 -0
  49. package/scripts/__pycache__/build_adapters.cpython-311.pyc +0 -0
  50. package/scripts/__pycache__/divergence_experiment.cpython-311.pyc +0 -0
  51. package/scripts/build_adapters.py +9 -2
  52. package/skills/darkharvest/SKILL.md +70 -0
  53. package/skills/darkharvest/scripts/harvest.py +252 -0
  54. package/skills/epistemic_search/scripts/__pycache__/search.cpython-311.pyc +0 -0
  55. package/skills/research_cache/__pycache__/__init__.cpython-311.pyc +0 -0
  56. package/skills/research_cache/__pycache__/hasher.cpython-311.pyc +0 -0
  57. package/skills/swarm_config/__pycache__/__init__.cpython-311.pyc +0 -0
  58. package/skills/swarm_config/__pycache__/configure.cpython-311.pyc +0 -0
  59. package/skills/swarm_config/configure.py +12 -2
@@ -0,0 +1,13 @@
1
+ # Darkharvest (thin adapter stub)
2
+
3
+ This file is a POINTER, not the implementation. It exists so harness skill
4
+ discovery finds an entry; the real skill lives in the IUMBTEMS repo.
5
+
6
+ - Canonical prose & scripts: `skills/darkharvest/`
7
+ - Canonical programmatic surface: `python3 runner/mcp_server.py` (stdio MCP),
8
+ or one-shot: `python3 runner/mcp_server.py call <tool> '{...json...}'`
9
+ - MCP tools for this skill: `iumbtems_darkharvest`
10
+
11
+ Epistemic rules apply regardless of harness: tag claims as
12
+ `[VERIFIED: <hash>]`, `[INFERRED: <reasoning>]`, `[HYPOTHESIS: <test>]`, or
13
+ `[NEGATIVE_KNOWLEDGE: <query>]`. Writes go only to `.research/`.
@@ -0,0 +1,11 @@
1
+ ---
2
+ description: Product competitor teardown with per-feature harvest verdicts
3
+ ---
4
+
5
+ Run a product competitor teardown for `$1`:
6
+
7
+ `python3 runner/research_swarm.py --mode darkharvest --objective "$1"`
8
+
9
+ Seeds may be embedded as repo URLs; cap live runs at `--max-repos 6`.
10
+ Permissive-only vendor; GPL/AGPL clean-room-rebuild only; workflows clonable, assets never.
11
+ Report: `.research/darkharvest_report.md` (matrix + white-space gaps + SPDX backlog).
package/README.md CHANGED
@@ -146,6 +146,9 @@ iumbtems run "Sub-millisecond ZK state updates on L1 rollups"
146
146
  # Run lateral brainstorming (divergent what-if ideation, never bug fixes)
147
147
  iumbtems brainstorm "Where do we go from here?"
148
148
 
149
+ # Product competitor teardown with per-feature harvest verdicts
150
+ iumbtems darkharvest "Paseo-class agent harness competitor" --seeds https://github.com/a/b,https://github.com/c/d --max-repos 6 --mock-claude
151
+
149
152
  # Run Socratic grilling and decision frontier calculation
150
153
  iumbtems grill --objective "L1 vs L2 state verification trade-offs"
151
154
 
@@ -160,6 +163,7 @@ iumbtems test
160
163
  - **`/swarm-config`**: Interactive tuning of search engines (DuckDuckGo, Brave, Firecrawl, SearXNG), iteration depth, divergence thresholds, and operating modes.
161
164
  - **`/code-audit`**: Dialectic codebase review pairing a Structural Architect (thesis) with a Vulnerability Red-Teamer (antithesis) enforcing line-number proofs (`file:///path#L10-25`).
162
165
  - **`/oss-scout`**: Evaluates GitHub repositories, package ecosystems (npm, crates.io, PyPI), license contamination (GPL/AGPL copyleft vs MIT/Apache), and outputs clean-room re-implementation blueprints.
166
+ - **`/darkharvest`**: Product competitor teardown (seed inspirations + prompt, expand to adjacents). Competitor × capability matrix, both-ways white-space gaps, per-feature `depend|vendor|clean-room-rebuild|skip` verdicts with SPDX attribution. Permissive-only vendoring; GPL/AGPL spec-rebuild only.
163
167
  - **`/grilling`**: Socratic assumption-inversion and Matt Pocock-style design tree frontier discovery.
164
168
  - **`epistemic_search`**: Zero-key DuckDuckGo Lite search and content-addressed fetch with automatic SHA-256 caching.
165
169
 
package/bin/cli.js CHANGED
@@ -49,6 +49,7 @@ Commands:
49
49
  scout "<feature>" Scout open-source software, libraries & clean-room blueprints
50
50
  run "<objective>" Run the dialectic multi-agent research swarm
51
51
  brainstorm "<prompt>" Run lateral brainstorming (feature vectors + spikes)
52
+ darkharvest "<arena>" Product competitor teardown with harvest verdicts
52
53
  grill Launch interactive Socratic decision tree framing
53
54
  adapters Rebuild harness adapter mirrors (skills -> plugins/*, .agents)
54
55
  install Install skills & MCP servers into ~/.claude/
@@ -80,6 +81,7 @@ Examples:
80
81
  iumbtems scout "Zero-dependency Raft consensus in Rust"
81
82
  iumbtems run "Verify sub-millisecond ZK prover latency"
82
83
  iumbtems brainstorm "Where do we go from here?"
84
+ iumbtems darkharvest "Paseo-class agent harness competitor" --seeds https://github.com/a/b,https://github.com/c/d --max-repos 6 --mock-claude
83
85
  iumbtems grill --objective "Rollup architecture trade-offs"
84
86
  iumbtems doctor
85
87
  `);
@@ -160,6 +162,18 @@ switch (command) {
160
162
  break;
161
163
  }
162
164
 
165
+ case 'darkharvest': {
166
+ const objective = args[1];
167
+ if (!objective || objective.startsWith('--')) {
168
+ console.error('Error: Please provide a product arena to tear down.');
169
+ console.error('Example: npx @heretek-ai/epistemic-swarm darkharvest "Paseo-class harness" --seeds https://github.com/a/b --max-repos 6');
170
+ process.exit(1);
171
+ }
172
+ const forwardArgs = ['--mode', 'darkharvest', '--objective', objective, ...args.slice(2)];
173
+ runPython('runner/research_swarm.py', forwardArgs);
174
+ break;
175
+ }
176
+
163
177
  case 'grill': {
164
178
  runPython('skills/grilling/socratic_tree.py', args.slice(1));
165
179
  break;
@@ -87,6 +87,18 @@
87
87
  "iumbtems_brainstorm": true,
88
88
  "iumbtems_config": true
89
89
  }
90
+ },
91
+ "darkharvester": {
92
+ "description": "IUMBTEMS Competitor Teardown: seed plus expand, product plus code matrix, per-feature harvest verdicts with SPDX attribution.",
93
+ "tools": {
94
+ "read": true,
95
+ "write": true,
96
+ "grep": true,
97
+ "glob": true,
98
+ "iumbtems_darkharvest": true,
99
+ "iumbtems_verify_quote": true,
100
+ "iumbtems_config": true
101
+ }
90
102
  }
91
103
  },
92
104
  "skills": {
@@ -97,7 +109,8 @@
97
109
  "./skills/swarm_config",
98
110
  "./skills/code_audit",
99
111
  "./skills/oss_scout",
100
- "./skills/brainstorming"
112
+ "./skills/brainstorming",
113
+ "./skills/darkharvest"
101
114
  ]
102
115
  }
103
116
  }
@@ -202,6 +202,27 @@ export default function initPiExtension(pi) {
202
202
  }
203
203
  });
204
204
  } catch { /* alias is best-effort across pi/omp versions */ }
205
+
206
+ // /darkharvest: Product competitor teardown with harvest verdicts
207
+ pi.registerCommand('darkharvest', {
208
+ description: 'Product competitor teardown: seed inspirations, expand to adjacents, emit harvest verdicts',
209
+ usage: '/darkharvest <product-arena> [--seeds <urls>]',
210
+ handler: async (args, ctx) => {
211
+ const objective = args.trim();
212
+ if (!objective) {
213
+ ctx.output?.('⚠️ Please provide a product arena. Example: /darkharvest "Paseo-class agent harness" --seeds https://github.com/a/b');
214
+ return;
215
+ }
216
+ ctx.output?.(`🌑 [IUMBTEMS Darkharvest] Tearing down: "${objective}"...`);
217
+ const r = callMcp('iumbtems_darkharvest', { objective }, ctx);
218
+ if (r.ok) {
219
+ ctx.output?.(r.text);
220
+ ctx.output?.('\n✅ Darkharvest complete! Matrix written to .research/darkharvest_report.md');
221
+ } else {
222
+ ctx.output?.(`❌ Darkharvest failed:\n${r.text}`);
223
+ }
224
+ }
225
+ });
205
226
  }
206
227
 
207
228
  // 2. Register Agent Tools (thin forwarders)
@@ -233,7 +254,7 @@ export default function initPiExtension(pi) {
233
254
  properties: {
234
255
  search_engine: { type: 'string', enum: ['duckduckgo', 'brave', 'firecrawl', 'searxng'] },
235
256
  max_iterations: { type: 'integer', minimum: 1, maximum: 4 },
236
- mode: { type: 'string', enum: ['research', 'audit', 'scout', 'hybrid', 'brainstorm'] },
257
+ mode: { type: 'string', enum: ['research', 'audit', 'scout', 'hybrid', 'brainstorm', 'darkharvest'] },
237
258
  divergence_threshold: { type: 'number', minimum: 0, maximum: 1 },
238
259
  show: { type: 'boolean', default: false }
239
260
  }
@@ -264,6 +285,31 @@ export default function initPiExtension(pi) {
264
285
  return { content: [{ type: 'text', text: r.text }] };
265
286
  }
266
287
  });
288
+
289
+ // Tool: iumbtems_darkharvest (competitor teardown)
290
+ pi.registerTool({
291
+ name: 'iumbtems_darkharvest',
292
+ description: 'Product competitor teardown with per-feature harvest verdicts and SPDX attribution',
293
+ parameters: {
294
+ type: 'object',
295
+ properties: {
296
+ objective: { type: 'string', description: 'Product arena to tear down' },
297
+ seeds: { type: 'array', items: { type: 'string' }, description: 'Seed inspiration repo URLs' },
298
+ maxRepos: { type: 'integer', description: 'Cap on total competitors', default: 10 },
299
+ mock_mode: { type: 'boolean', description: 'Mock mode without LLM tokens', default: false }
300
+ },
301
+ required: ['objective']
302
+ },
303
+ execute: async (args = {}) => {
304
+ const r = callMcp('iumbtems_darkharvest', {
305
+ objective: args.objective,
306
+ seeds: args.seeds,
307
+ maxRepos: args.maxRepos,
308
+ mock_claude: Boolean(args.mock_mode)
309
+ }, {});
310
+ return { content: [{ type: 'text', text: r.text }] };
311
+ }
312
+ });
267
313
  }
268
314
  }
269
315
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heretek-ai/epistemic-swarm",
3
- "version": "0.4.8",
3
+ "version": "0.5.0",
4
4
  "description": "IUMBTEMS: I Use My Brain To Express My Self — High-Integrity Dialectic Research Agent Harness for Claude Code, OpenCode V2, Pi, OMP (oh-my-pi), Gemini CLI, Codex CLI, and AntiGravity",
5
5
  "main": "bin/cli.js",
6
6
  "bin": {
@@ -79,7 +79,8 @@
79
79
  "./skills/swarm_config",
80
80
  "./skills/code_audit",
81
81
  "./skills/oss_scout",
82
- "./skills/brainstorming"
82
+ "./skills/brainstorming",
83
+ "./skills/darkharvest"
83
84
  ],
84
85
  "prompts": [
85
86
  "./prompts/*.md"
@@ -96,7 +97,8 @@
96
97
  "./skills/swarm_config",
97
98
  "./skills/code_audit",
98
99
  "./skills/oss_scout",
99
- "./skills/brainstorming"
100
+ "./skills/brainstorming",
101
+ "./skills/darkharvest"
100
102
  ],
101
103
  "prompts": [
102
104
  "./prompts/*.md"
@@ -0,0 +1,13 @@
1
+ # Darkharvest (thin adapter stub)
2
+
3
+ This file is a POINTER, not the implementation. It exists so harness skill
4
+ discovery finds an entry; the real skill lives in the IUMBTEMS repo.
5
+
6
+ - Canonical prose & scripts: `skills/darkharvest/`
7
+ - Canonical programmatic surface: `python3 runner/mcp_server.py` (stdio MCP),
8
+ or one-shot: `python3 runner/mcp_server.py call <tool> '{...json...}'`
9
+ - MCP tools for this skill: `iumbtems_darkharvest`
10
+
11
+ Epistemic rules apply regardless of harness: tag claims as
12
+ `[VERIFIED: <hash>]`, `[INFERRED: <reasoning>]`, `[HYPOTHESIS: <test>]`, or
13
+ `[NEGATIVE_KNOWLEDGE: <query>]`. Writes go only to `.research/`.
@@ -0,0 +1,13 @@
1
+ # Darkharvest (thin adapter stub)
2
+
3
+ This file is a POINTER, not the implementation. It exists so harness skill
4
+ discovery finds an entry; the real skill lives in the IUMBTEMS repo.
5
+
6
+ - Canonical prose & scripts: `skills/darkharvest/`
7
+ - Canonical programmatic surface: `python3 runner/mcp_server.py` (stdio MCP),
8
+ or one-shot: `python3 runner/mcp_server.py call <tool> '{...json...}'`
9
+ - MCP tools for this skill: `iumbtems_darkharvest`
10
+
11
+ Epistemic rules apply regardless of harness: tag claims as
12
+ `[VERIFIED: <hash>]`, `[INFERRED: <reasoning>]`, `[HYPOTHESIS: <test>]`, or
13
+ `[NEGATIVE_KNOWLEDGE: <query>]`. Writes go only to `.research/`.
@@ -0,0 +1,8 @@
1
+ description = "Product competitor teardown with per-feature harvest verdicts"
2
+ prompt = """Run a product competitor teardown for: {{args}}.
3
+
4
+ Execute: python3 runner/research_swarm.py --mode darkharvest --objective "{{args}}"
5
+ Seeds may be embedded as repo URLs in the objective; cap at --max-repos 6 live.
6
+ Legal rule: permissive-only vendor; GPL/AGPL clean-room-rebuild only; workflows clonable, assets never.
7
+ Report: .research/darkharvest_report.md (competitor x capability matrix + harvest backlog + SPDX blocks).
8
+ """
@@ -0,0 +1,13 @@
1
+ # Darkharvest (thin adapter stub)
2
+
3
+ This file is a POINTER, not the implementation. It exists so harness skill
4
+ discovery finds an entry; the real skill lives in the IUMBTEMS repo.
5
+
6
+ - Canonical prose & scripts: `skills/darkharvest/`
7
+ - Canonical programmatic surface: `python3 runner/mcp_server.py` (stdio MCP),
8
+ or one-shot: `python3 runner/mcp_server.py call <tool> '{...json...}'`
9
+ - MCP tools for this skill: `iumbtems_darkharvest`
10
+
11
+ Epistemic rules apply regardless of harness: tag claims as
12
+ `[VERIFIED: <hash>]`, `[INFERRED: <reasoning>]`, `[HYPOTHESIS: <test>]`, or
13
+ `[NEGATIVE_KNOWLEDGE: <query>]`. Writes go only to `.research/`.
@@ -92,6 +92,7 @@ export const IUMBTEMS_TOOL_NAMES = [
92
92
  'iumbtems_code_audit',
93
93
  'iumbtems_oss_scout',
94
94
  'iumbtems_brainstorm',
95
+ 'iumbtems_darkharvest',
95
96
  'iumbtems_verify_quote',
96
97
  'iumbtems_socratic_frontier',
97
98
  'iumbtems_reindex_claims',
@@ -126,8 +127,8 @@ const TOOL_CATALOG = [
126
127
  },
127
128
  mode: {
128
129
  type: 'string',
129
- enum: ['research', 'audit', 'scout', 'hybrid', 'brainstorm'],
130
- description: 'Operating mode: research (literature), audit (codebase), scout (OSS), hybrid, brainstorm (lateral ideation)',
130
+ enum: ['research', 'audit', 'scout', 'hybrid', 'brainstorm', 'darkharvest'],
131
+ description: 'Operating mode: research (literature), audit (codebase), scout (OSS), hybrid, brainstorm (lateral ideation), darkharvest (competitor teardown)',
131
132
  },
132
133
  divergence_threshold: {
133
134
  type: 'number',
@@ -223,6 +224,39 @@ const TOOL_CATALOG = [
223
224
  required: ['objective'],
224
225
  },
225
226
  },
227
+ {
228
+ name: 'iumbtems_darkharvest',
229
+ description:
230
+ 'Product competitor teardown: seed inspirations plus prompt, expand to adjacents, emit per-feature depend/vendor/clean-room/skip verdicts with SPDX attribution.',
231
+ input: {
232
+ type: 'object',
233
+ properties: {
234
+ objective: {
235
+ type: 'string',
236
+ description: 'Product arena to tear down (e.g. Paseo-class agent harness competitor)',
237
+ },
238
+ seeds: {
239
+ type: 'array',
240
+ items: { type: 'string' },
241
+ description: 'Seed inspiration repo URLs',
242
+ },
243
+ maxRepos: {
244
+ type: 'integer',
245
+ description: 'Cap on total competitors (default 10)',
246
+ },
247
+ depth: {
248
+ type: 'integer',
249
+ description: 'Dialectic depth 1-4',
250
+ },
251
+ mock_mode: {
252
+ type: 'boolean',
253
+ description: 'Run in mock mode without invoking LLM tokens',
254
+ default: false,
255
+ },
256
+ },
257
+ required: ['objective'],
258
+ },
259
+ },
226
260
  {
227
261
  name: 'iumbtems_verify_quote',
228
262
  description:
@@ -465,6 +499,19 @@ export const OPENCODE_COMMANDS = [
465
499
  'Execute iumbtems_brainstorm with {"objective": "<prompt>"} and report feature vectors, paradigm inversions, and falsifiable spikes.',
466
500
  ].join('\n'),
467
501
  },
502
+ {
503
+ name: 'darkharvest',
504
+ description: 'Product competitor teardown with per-feature harvest verdicts',
505
+ usage: '/darkharvest <objective> [--seeds <urls>] [--max-repos <n>]',
506
+ template: [
507
+ 'Run a product competitor teardown (seed inspirations plus prompt, expand to adjacents).',
508
+ 'Objective: $ARGUMENTS (product arena; seeds may be embedded as URLs)',
509
+ 'If $ARGUMENTS is empty, ask the user for the product arena and seed URLs first; never call the tool with placeholder arguments.',
510
+ '1. Execute iumbtems_darkharvest with {"objective": "<objective>", "seeds": ["<url>", "..."]} (pass "mock_mode": true only for dry runs).',
511
+ '2. Report the competitor x capability matrix, white-space gaps both ways, and the SPDX-attributed harvest backlog in .research/darkharvest_report.md.',
512
+ '3. Legal rule: permissive-only vendor; GPL/AGPL clean-room-rebuild only; workflows clonable, assets never.',
513
+ ].join('\n'),
514
+ },
468
515
  ];
469
516
 
470
517
  /**
@@ -0,0 +1,91 @@
1
+ # AGENT DARKHARVEST: COMPETITOR TEARDOWN & CLEAN-ROOM HARVEST SPECIFICATION
2
+
3
+ You are the **Darkharvest Engine** within the IUMBTEMS harness. Your job is
4
+ product-level competitor teardown: given a local repo plus seed inspirations
5
+ (e.g. Paseo, OpenChambers) plus prompt guidance, find same-vein projects and
6
+ report what they do well, what white space exists in BOTH directions, and what
7
+ may be harvested per feature as `depend | vendor | clean-room-rebuild |
8
+ skip(reason)`.
9
+
10
+ Trigger: `/darkharvest <objective>` with `--seeds <urls>`.
11
+ Calibration: `temperature 0.2-0.4`, `top_p 0.9`, `max_iterations 2-3`.
12
+ Budget: per-competitor scan MUST respect `--max-repos`, `--per-repo-mb`,
13
+ `--per-repo-timeout`, and the harvest.py allowlist. NEVER full-dump without caps.
14
+
15
+ ---
16
+
17
+ ## 1. SCOPE DECOMPOSITION (one scope per competitor)
18
+
19
+ The Orchestrator emits one scope per competitor (seeds + expanded adjacents,
20
+ capped at `--max-repos`, default 10, recommended 6 live). Direct competitors
21
+ and adjacent inspirations are labeled separately.
22
+
23
+ - `affirmative_targets`: harvest surface Alpha must prove (features, UX flows,
24
+ arch patterns, deps, data model).
25
+ - `adversarial_targets`: Beta must probe (license contamination, transitive
26
+ bloat, CVE/takeover surface, staleness, both-ways missing).
27
+
28
+ ## 2. DIALECTIC ROLES
29
+
30
+ ### Alpha — Harvest Proponent
31
+ For the assigned competitor: capability inventory (present / missing /
32
+ partial per capability), benchmark/API quotes, and per-feature harvest
33
+ proposals. Every cell needs `[VERIFIED: <hash>]` from
34
+ `.research/sources/<sha256>.md` or `file://<path>#L<start>-L<end>`.
35
+
36
+ ### Beta — Red Team
37
+ License gate (LICENSE file + package metadata → SPDX), transitive weight,
38
+ CVE/takeover notes, staleness (`⚠️ STALE` when >12mo or solo-maintainer),
39
+ and white-space gaps BOTH ways (what competitor lacks that we own or could own
40
+ AND what we lack). Gates are warn-only: badge inline, never auto-skip.
41
+
42
+ ## 3. LEGAL HARVEST RULE (FINAL)
43
+
44
+ - Permissive only (MIT, Apache-2.0, BSD-3-Clause, ISC) → `depend` or `vendor`.
45
+ - GPL / AGPL / UNKNOWN → `clean-room-rebuild` spec only. NEVER copy code.
46
+ - Workflows clonable; copy-text, UI assets, brand NEVER copied.
47
+ - Every `vendor` item emits an SPDX attribution block (license + upstream URL
48
+ + files). Closed targets get metadata-only rows +
49
+ `[NEGATIVE_KNOWLEDGE: <query>]`, never a failed run.
50
+
51
+ ## 4. OUTPUT SPECIFICATION
52
+
53
+ Per scope write `alpha_dossier.json` / `beta_dossier.json` with
54
+ `candidate_repositories[]` entries:
55
+
56
+ ```json
57
+ {
58
+ "repo_id": "DH-01",
59
+ "name": "owner/repo",
60
+ "url": "https://github.com/owner/repo",
61
+ "source_hash": "<sha256>",
62
+ "license": "Apache-2.0",
63
+ "license_risk": "SAFE | COPYLEFT_WARNING | PROHIBITIVE",
64
+ "harvest_policy": "depend-or-vendor | clean-room-rebuild-only",
65
+ "verdicts": [
66
+ {
67
+ "feature": "<capability>",
68
+ "verdict": "depend | vendor | clean-room-rebuild | skip",
69
+ "reason": "<evidence-backed>",
70
+ "effort": "S|M|L",
71
+ "impact": "1-5",
72
+ "differentiation": "1-5"
73
+ }
74
+ ],
75
+ "warnings": ["⚠️ LICENSE: ...", "⚠️ STALE: ...", "⚠️ CVE: ..."],
76
+ "attribution": {"spdx": "Apache-2.0", "upstream": "<url>", "files": []}
77
+ }
78
+ ```
79
+
80
+ Master synthesis (`darkharvest_report.md`): competitor × capability matrix +
81
+ white-space gaps + harvest backlog ranked Impact×Effort×Differentiation (top 5)
82
+ + risks + epistemic audit totals. Reruns diff changed cells + new/removed
83
+ candidates.
84
+
85
+ ## 5. HARD BANS
86
+
87
+ 1. No writes outside `.research/`. No dependency installs.
88
+ 2. No GPL/AGPL vendoring, no asset/brand copying, no pixel-clone guidance.
89
+ 3. No unverified harvest verdicts. Metadata ranks; only VERIFIED harvests.
90
+ 4. No unbounded expansion past `--max-repos` or per-repo caps without user
91
+ confirmation. Firecrawl missing → gap note, never abort.