@cluesmith/codev 3.0.0-rc.11 → 3.0.0-rc.12
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.
- package/dashboard-dist/dist/assets/index-Coe88ldB.css +32 -0
- package/dashboard-dist/dist/assets/index-JRKA6Mfr.js +195 -0
- package/dashboard-dist/dist/assets/index-JRKA6Mfr.js.map +1 -0
- package/dashboard-dist/dist/index.html +2 -2
- package/dist/agent-farm/servers/tower-instances.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-instances.js +3 -2
- package/dist/agent-farm/servers/tower-instances.js.map +1 -1
- package/dist/agent-farm/servers/tower-routes.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-routes.js +10 -0
- package/dist/agent-farm/servers/tower-routes.js.map +1 -1
- package/dist/lib/team-github.d.ts +47 -0
- package/dist/lib/team-github.d.ts.map +1 -1
- package/dist/lib/team-github.js +111 -2
- package/dist/lib/team-github.js.map +1 -1
- package/package.json +4 -3
- package/scripts/postinstall.mjs +51 -0
- package/skeleton/protocols/research/builder-prompt.md +85 -0
- package/skeleton/protocols/research/protocol.json +118 -0
- package/skeleton/protocols/research/protocol.md +169 -0
- package/skeleton/templates/AGENTS.md +1 -0
- package/skeleton/templates/CLAUDE.md +1 -0
- package/skeleton/templates/cheatsheet.md +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"team-github.d.ts","sourceRoot":"","sources":["../../src/lib/team-github.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAQnE,MAAM,WAAW,oBAAoB;IACnC,cAAc,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACjE,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC1D,cAAc,EAAE;QACd,SAAS,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAC9E,YAAY,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;KAClF,CAAC;
|
|
1
|
+
{"version":3,"file":"team-github.d.ts","sourceRoot":"","sources":["../../src/lib/team-github.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/team-github.js
CHANGED
|
@@ -67,7 +67,19 @@ export function buildTeamGraphQLQuery(members, owner, name) {
|
|
|
67
67
|
nodes { ... on Issue { number title url } }
|
|
68
68
|
}
|
|
69
69
|
${alias}_prs: search(query: "repo:${repo} author:${m.github} is:pr is:open", type: ISSUE, first: 20) {
|
|
70
|
-
nodes {
|
|
70
|
+
nodes {
|
|
71
|
+
... on PullRequest {
|
|
72
|
+
number
|
|
73
|
+
title
|
|
74
|
+
url
|
|
75
|
+
isDraft
|
|
76
|
+
createdAt
|
|
77
|
+
reviewDecision
|
|
78
|
+
reviewRequests(first: 20) {
|
|
79
|
+
nodes { requestedReviewer { ... on User { login } } }
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
71
83
|
}
|
|
72
84
|
${alias}_merged: search(query: "repo:${repo} author:${m.github} is:pr is:merged merged:>=${since}", type: ISSUE, first: 20) {
|
|
73
85
|
nodes { ... on PullRequest { number title url mergedAt } }
|
|
@@ -81,11 +93,99 @@ export function buildTeamGraphQLQuery(members, owner, name) {
|
|
|
81
93
|
${fragments}
|
|
82
94
|
}`;
|
|
83
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* Derive review-blocking relationships from every team member's authored PRs.
|
|
98
|
+
*
|
|
99
|
+
* Two-pass algorithm:
|
|
100
|
+
* 1. Collect (author, reviewer, pr) tuples by iterating each author's PRs
|
|
101
|
+
* and cross-referencing requested reviewers against the team roster.
|
|
102
|
+
* 2. Distribute each tuple into the author's `reviewBlocking` array (as
|
|
103
|
+
* `direction: 'authored'`) and the reviewer's (as `direction: 'reviewing'`).
|
|
104
|
+
*
|
|
105
|
+
* Rules are documented in spec 694:
|
|
106
|
+
* - Open, not draft.
|
|
107
|
+
* - reviewDecision !== 'APPROVED'.
|
|
108
|
+
* - Requested reviewer must resolve to a User (not Team) and match the team roster.
|
|
109
|
+
* - Author is guaranteed to be a team member by construction (query scope).
|
|
110
|
+
*/
|
|
111
|
+
export function deriveReviewBlocking(prsByAuthor, members) {
|
|
112
|
+
// Case-insensitive lookup: lower-case github handle → TeamMember.
|
|
113
|
+
const roster = new Map();
|
|
114
|
+
for (const m of members) {
|
|
115
|
+
if (!isValidGitHubHandle(m.github))
|
|
116
|
+
continue;
|
|
117
|
+
roster.set(m.github.toLowerCase(), m);
|
|
118
|
+
}
|
|
119
|
+
const displayName = (m) => m.name || m.github;
|
|
120
|
+
const perMember = new Map();
|
|
121
|
+
const entriesFor = (handle) => {
|
|
122
|
+
const existing = perMember.get(handle);
|
|
123
|
+
if (existing)
|
|
124
|
+
return existing;
|
|
125
|
+
const fresh = [];
|
|
126
|
+
perMember.set(handle, fresh);
|
|
127
|
+
return fresh;
|
|
128
|
+
};
|
|
129
|
+
for (const [authorHandle, prs] of prsByAuthor) {
|
|
130
|
+
const author = roster.get(authorHandle.toLowerCase());
|
|
131
|
+
if (!author)
|
|
132
|
+
continue;
|
|
133
|
+
for (const pr of prs) {
|
|
134
|
+
if (pr.isDraft)
|
|
135
|
+
continue;
|
|
136
|
+
if (pr.reviewDecision === 'APPROVED')
|
|
137
|
+
continue;
|
|
138
|
+
const requestedNodes = pr.reviewRequests?.nodes ?? [];
|
|
139
|
+
for (const node of requestedNodes) {
|
|
140
|
+
const login = node?.requestedReviewer?.login;
|
|
141
|
+
if (!login)
|
|
142
|
+
continue; // Team-based requests resolve to undefined login.
|
|
143
|
+
const reviewer = roster.get(login.toLowerCase());
|
|
144
|
+
if (!reviewer)
|
|
145
|
+
continue; // External reviewer.
|
|
146
|
+
if (reviewer.github.toLowerCase() === author.github.toLowerCase())
|
|
147
|
+
continue; // Self-review edge.
|
|
148
|
+
const prMeta = {
|
|
149
|
+
number: pr.number,
|
|
150
|
+
title: pr.title,
|
|
151
|
+
url: pr.url,
|
|
152
|
+
createdAt: pr.createdAt ?? '',
|
|
153
|
+
};
|
|
154
|
+
entriesFor(author.github).push({
|
|
155
|
+
direction: 'authored',
|
|
156
|
+
otherName: displayName(reviewer),
|
|
157
|
+
otherGithub: reviewer.github,
|
|
158
|
+
pr: prMeta,
|
|
159
|
+
});
|
|
160
|
+
entriesFor(reviewer.github).push({
|
|
161
|
+
direction: 'reviewing',
|
|
162
|
+
otherName: displayName(author),
|
|
163
|
+
otherGithub: author.github,
|
|
164
|
+
pr: prMeta,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
// Sort each member's entries oldest-first (stable, with PR number as tiebreaker).
|
|
170
|
+
for (const list of perMember.values()) {
|
|
171
|
+
list.sort((a, b) => {
|
|
172
|
+
const byDate = (a.pr.createdAt ?? '').localeCompare(b.pr.createdAt ?? '');
|
|
173
|
+
if (byDate !== 0)
|
|
174
|
+
return byDate;
|
|
175
|
+
return a.pr.number - b.pr.number;
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
return perMember;
|
|
179
|
+
}
|
|
180
|
+
// =============================================================================
|
|
181
|
+
// Response Parser
|
|
182
|
+
// =============================================================================
|
|
84
183
|
/**
|
|
85
184
|
* Parse the GraphQL response into a map of github handle → TeamMemberGitHubData.
|
|
86
185
|
*/
|
|
87
186
|
export function parseTeamGraphQLResponse(data, members) {
|
|
88
187
|
const result = new Map();
|
|
188
|
+
const prsByAuthor = new Map();
|
|
89
189
|
for (const member of members) {
|
|
90
190
|
if (!isValidGitHubHandle(member.github))
|
|
91
191
|
continue;
|
|
@@ -94,15 +194,24 @@ export function parseTeamGraphQLResponse(data, members) {
|
|
|
94
194
|
const prs = data[`${alias}_prs`];
|
|
95
195
|
const merged = data[`${alias}_merged`];
|
|
96
196
|
const closed = data[`${alias}_closed`];
|
|
197
|
+
const openPrNodes = prs?.nodes ?? [];
|
|
198
|
+
prsByAuthor.set(member.github, openPrNodes);
|
|
97
199
|
result.set(member.github, {
|
|
98
200
|
assignedIssues: (assigned?.nodes ?? []).map(n => ({ number: n.number, title: n.title, url: n.url })),
|
|
99
|
-
openPRs:
|
|
201
|
+
openPRs: openPrNodes.map(n => ({ number: n.number, title: n.title, url: n.url })),
|
|
100
202
|
recentActivity: {
|
|
101
203
|
mergedPRs: (merged?.nodes ?? []).map(n => ({ number: n.number, title: n.title, url: n.url, mergedAt: n.mergedAt })),
|
|
102
204
|
closedIssues: (closed?.nodes ?? []).map(n => ({ number: n.number, title: n.title, url: n.url, closedAt: n.closedAt })),
|
|
103
205
|
},
|
|
206
|
+
reviewBlocking: [],
|
|
104
207
|
});
|
|
105
208
|
}
|
|
209
|
+
const perMemberBlocking = deriveReviewBlocking(prsByAuthor, members);
|
|
210
|
+
for (const [handle, entries] of perMemberBlocking) {
|
|
211
|
+
const bucket = result.get(handle);
|
|
212
|
+
if (bucket)
|
|
213
|
+
bucket.reviewBlocking = entries;
|
|
214
|
+
}
|
|
106
215
|
return result;
|
|
107
216
|
}
|
|
108
217
|
// =============================================================================
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"team-github.js","sourceRoot":"","sources":["../../src/lib/team-github.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAEhD,OAAO,EAAE,mBAAmB,EAAoB,MAAM,YAAY,CAAC;AAEnE,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"team-github.js","sourceRoot":"","sources":["../../src/lib/team-github.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cluesmith/codev",
|
|
3
|
-
"version": "3.0.0-rc.
|
|
3
|
+
"version": "3.0.0-rc.12",
|
|
4
4
|
"description": "Codev CLI - AI-assisted software development framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
"skeleton",
|
|
19
19
|
"templates",
|
|
20
20
|
"dashboard-dist",
|
|
21
|
-
"scripts/forge"
|
|
21
|
+
"scripts/forge",
|
|
22
|
+
"scripts/postinstall.mjs"
|
|
22
23
|
],
|
|
23
24
|
"dependencies": {
|
|
24
25
|
"@anthropic-ai/claude-agent-sdk": "^0.2.41",
|
|
@@ -82,6 +83,6 @@
|
|
|
82
83
|
"test:e2e:watch": "vitest --config vitest.e2e.config.ts",
|
|
83
84
|
"test:e2e:playwright": "pnpm exec playwright test",
|
|
84
85
|
"test:e2e:cli": "pnpm build && vitest run --config vitest.cli.config.ts",
|
|
85
|
-
"postinstall": "node
|
|
86
|
+
"postinstall": "node ./scripts/postinstall.mjs"
|
|
86
87
|
}
|
|
87
88
|
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// Restores executable bits that pnpm pack/publish strips from files outside
|
|
4
|
+
// the `bin` field. See issue #693 — without this, `afx spawn` fails with
|
|
5
|
+
// Permission denied when invoking forge concept scripts.
|
|
6
|
+
|
|
7
|
+
import { chmodSync, readdirSync } from 'node:fs';
|
|
8
|
+
import { createRequire } from 'node:module';
|
|
9
|
+
import { dirname, join } from 'node:path';
|
|
10
|
+
import { fileURLToPath } from 'node:url';
|
|
11
|
+
|
|
12
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
13
|
+
const forgeRoot = join(here, 'forge');
|
|
14
|
+
|
|
15
|
+
function chmodForgeScripts(root) {
|
|
16
|
+
let providers;
|
|
17
|
+
try {
|
|
18
|
+
providers = readdirSync(root, { withFileTypes: true });
|
|
19
|
+
} catch {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
for (const provider of providers) {
|
|
23
|
+
if (!provider.isDirectory()) continue;
|
|
24
|
+
const providerDir = join(root, provider.name);
|
|
25
|
+
for (const entry of readdirSync(providerDir, { withFileTypes: true })) {
|
|
26
|
+
if (!entry.isFile() || !entry.name.endsWith('.sh')) continue;
|
|
27
|
+
chmodSync(join(providerDir, entry.name), 0o755);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function chmodNodePtySpawnHelper() {
|
|
33
|
+
try {
|
|
34
|
+
const require = createRequire(import.meta.url);
|
|
35
|
+
const ptyEntry = require.resolve('node-pty');
|
|
36
|
+
const helper = join(
|
|
37
|
+
ptyEntry,
|
|
38
|
+
'..',
|
|
39
|
+
'..',
|
|
40
|
+
'prebuilds',
|
|
41
|
+
`${process.platform}-${process.arch}`,
|
|
42
|
+
'spawn-helper'
|
|
43
|
+
);
|
|
44
|
+
chmodSync(helper, 0o755);
|
|
45
|
+
} catch {
|
|
46
|
+
// node-pty may not ship a prebuild for this platform; harmless.
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
chmodForgeScripts(forgeRoot);
|
|
51
|
+
chmodNodePtySpawnHelper();
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# {{protocol_name}} Builder ({{mode}} mode)
|
|
2
|
+
|
|
3
|
+
You are conducting multi-agent research.
|
|
4
|
+
|
|
5
|
+
{{#if mode_soft}}
|
|
6
|
+
## Mode: SOFT
|
|
7
|
+
You are running in SOFT mode. This means:
|
|
8
|
+
- You follow the RESEARCH protocol yourself (no porch orchestration)
|
|
9
|
+
- The architect monitors your work and verifies you're adhering to the protocol
|
|
10
|
+
- Use `consult` for the 3-way investigation and critique phases
|
|
11
|
+
{{/if}}
|
|
12
|
+
|
|
13
|
+
{{#if mode_strict}}
|
|
14
|
+
## Mode: STRICT
|
|
15
|
+
You are running in STRICT mode. This means:
|
|
16
|
+
- Porch orchestrates your work
|
|
17
|
+
- Run: `porch next` to get your next tasks
|
|
18
|
+
- Follow porch signals and gate approvals
|
|
19
|
+
|
|
20
|
+
### ABSOLUTE RESTRICTIONS (STRICT MODE)
|
|
21
|
+
- **NEVER edit `status.yaml` directly** — only porch commands may modify project state
|
|
22
|
+
- **NEVER call `porch approve` without explicit human approval** — only run it after the architect says to
|
|
23
|
+
- **NEVER skip the 3-way consultation** — always follow porch next → porch done cycle
|
|
24
|
+
{{/if}}
|
|
25
|
+
|
|
26
|
+
## Protocol
|
|
27
|
+
Follow the RESEARCH protocol: `codev/protocols/research/protocol.md`
|
|
28
|
+
|
|
29
|
+
## RESEARCH Overview
|
|
30
|
+
|
|
31
|
+
The RESEARCH protocol produces a high-confidence research report through triangulation:
|
|
32
|
+
|
|
33
|
+
1. **Scope** — Define the precise question, scope, and acceptance criteria. Write a research brief. Gate: architect approval before proceeding.
|
|
34
|
+
2. **Investigate** — Dispatch the brief to 3 models (Gemini, Codex, Claude) in parallel. Each investigates independently. No anchoring — they don't see each other's work.
|
|
35
|
+
3. **Synthesize** — Read all 3 reports. Identify consensus, disagreements, and unique contributions. Write a single synthesis report organized by topic (not by model).
|
|
36
|
+
4. **Critique** — Send the synthesis back to all 3 models for critique. Incorporate valid feedback. Document rejected critique. Finalize the report.
|
|
37
|
+
|
|
38
|
+
## Output Location
|
|
39
|
+
|
|
40
|
+
All artifacts go to `codev/research/`:
|
|
41
|
+
- `<topic>-brief.md` — the scoped question (Phase 1)
|
|
42
|
+
- `<topic>-gemini.md`, `<topic>-codex.md`, `<topic>-claude.md` — individual investigations (Phase 2)
|
|
43
|
+
- `<topic>.md` — the final synthesis report (Phase 3+4, this is the deliverable)
|
|
44
|
+
- `<topic>-critique-rebuttals.md` — critique responses (Phase 4)
|
|
45
|
+
|
|
46
|
+
{{#if task}}
|
|
47
|
+
## Research Topic
|
|
48
|
+
{{task_text}}
|
|
49
|
+
{{/if}}
|
|
50
|
+
|
|
51
|
+
## Key Principles
|
|
52
|
+
|
|
53
|
+
- **Triangulate**: consensus across 3 models > any single model's claim
|
|
54
|
+
- **Cite sources**: tell investigators to provide sources where possible
|
|
55
|
+
- **Be candid about uncertainty**: "I don't know" > confabulation
|
|
56
|
+
- **Organize by topic, not by model**: the synthesis is a standalone document
|
|
57
|
+
- **Note surprises**: the most valuable findings are often unexpected
|
|
58
|
+
- **Keep it concise**: the synthesis should be shorter than the sum of the investigations
|
|
59
|
+
|
|
60
|
+
## Using consult for 3-way Investigation
|
|
61
|
+
|
|
62
|
+
For the investigate phase, use the `consult` CLI to dispatch to each model:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# Phase 2: parallel investigation
|
|
66
|
+
consult -m gemini --prompt-file codev/research/<topic>-brief.md --output codev/research/<topic>-gemini.md &
|
|
67
|
+
consult -m codex --prompt-file codev/research/<topic>-brief.md --output codev/research/<topic>-codex.md &
|
|
68
|
+
consult -m claude --prompt-file codev/research/<topic>-brief.md --output codev/research/<topic>-claude.md &
|
|
69
|
+
wait
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
For the critique phase:
|
|
73
|
+
```bash
|
|
74
|
+
# Phase 4: parallel critique
|
|
75
|
+
consult -m gemini --prompt "Critique this research synthesis for gaps, errors, and bias:" --prompt-file codev/research/<topic>.md --output codev/research/<topic>-critique-gemini.md &
|
|
76
|
+
consult -m codex --prompt "Critique this research synthesis for gaps, errors, and bias:" --prompt-file codev/research/<topic>.md --output codev/research/<topic>-critique-codex.md &
|
|
77
|
+
consult -m claude --prompt "Critique this research synthesis for gaps, errors, and bias:" --prompt-file codev/research/<topic>.md --output codev/research/<topic>-critique-claude.md &
|
|
78
|
+
wait
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Getting Started
|
|
82
|
+
1. Read the RESEARCH protocol document
|
|
83
|
+
2. Understand the research question from the architect
|
|
84
|
+
3. Write the research brief (Phase 1)
|
|
85
|
+
4. Wait for scope-approval before proceeding to investigation
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "../../protocol-schema.json",
|
|
3
|
+
"name": "research",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"description": "Multi-agent research with 3-way investigation, synthesis, and critique",
|
|
6
|
+
"input": {
|
|
7
|
+
"type": "none",
|
|
8
|
+
"required": false,
|
|
9
|
+
"default_for": []
|
|
10
|
+
},
|
|
11
|
+
"hooks": {
|
|
12
|
+
"pre-spawn": {}
|
|
13
|
+
},
|
|
14
|
+
"phases": [
|
|
15
|
+
{
|
|
16
|
+
"id": "scope",
|
|
17
|
+
"name": "Scope",
|
|
18
|
+
"description": "Define the research question, scope, and acceptance criteria",
|
|
19
|
+
"type": "once",
|
|
20
|
+
"steps": [
|
|
21
|
+
"clarify_question",
|
|
22
|
+
"define_scope",
|
|
23
|
+
"define_acceptance_criteria",
|
|
24
|
+
"create_research_brief"
|
|
25
|
+
],
|
|
26
|
+
"gate": {
|
|
27
|
+
"name": "scope-approval",
|
|
28
|
+
"description": "Architect confirms the research question is correctly scoped",
|
|
29
|
+
"requires": ["research_brief_exists"],
|
|
30
|
+
"next": "investigate"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": "investigate",
|
|
35
|
+
"name": "Investigate",
|
|
36
|
+
"description": "3-way parallel investigation — each model researches independently",
|
|
37
|
+
"type": "once",
|
|
38
|
+
"steps": [
|
|
39
|
+
"dispatch_gemini_investigation",
|
|
40
|
+
"dispatch_codex_investigation",
|
|
41
|
+
"dispatch_claude_investigation",
|
|
42
|
+
"collect_all_reports"
|
|
43
|
+
],
|
|
44
|
+
"consultation": {
|
|
45
|
+
"enabled": true,
|
|
46
|
+
"models": ["codex"],
|
|
47
|
+
"parallel": true,
|
|
48
|
+
"type": "investigation"
|
|
49
|
+
},
|
|
50
|
+
"transition": {
|
|
51
|
+
"on_complete": "synthesize"
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"id": "synthesize",
|
|
56
|
+
"name": "Synthesize",
|
|
57
|
+
"description": "Merge the 3 investigation reports into a single coherent research document",
|
|
58
|
+
"type": "once",
|
|
59
|
+
"steps": [
|
|
60
|
+
"read_all_investigation_reports",
|
|
61
|
+
"identify_consensus_and_disagreements",
|
|
62
|
+
"resolve_conflicts",
|
|
63
|
+
"write_synthesis_report"
|
|
64
|
+
],
|
|
65
|
+
"transition": {
|
|
66
|
+
"on_complete": "critique"
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"id": "critique",
|
|
71
|
+
"name": "Critique",
|
|
72
|
+
"description": "3-way review of the synthesis — each model critiques for gaps, errors, and bias",
|
|
73
|
+
"type": "once",
|
|
74
|
+
"steps": [
|
|
75
|
+
"dispatch_gemini_critique",
|
|
76
|
+
"dispatch_codex_critique",
|
|
77
|
+
"dispatch_claude_critique",
|
|
78
|
+
"incorporate_feedback",
|
|
79
|
+
"finalize_report"
|
|
80
|
+
],
|
|
81
|
+
"consultation": {
|
|
82
|
+
"enabled": true,
|
|
83
|
+
"models": ["codex"],
|
|
84
|
+
"parallel": true,
|
|
85
|
+
"type": "critique"
|
|
86
|
+
},
|
|
87
|
+
"gate": {
|
|
88
|
+
"name": "research-complete",
|
|
89
|
+
"description": "Research report finalized",
|
|
90
|
+
"requires": ["report_finalized"],
|
|
91
|
+
"next": null
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
],
|
|
95
|
+
"signals": {
|
|
96
|
+
"PHASE_COMPLETE": {
|
|
97
|
+
"description": "Signal current phase is complete",
|
|
98
|
+
"transitions_to": "next_phase"
|
|
99
|
+
},
|
|
100
|
+
"BLOCKED": {
|
|
101
|
+
"description": "Signal research is blocked",
|
|
102
|
+
"requires": "reason"
|
|
103
|
+
},
|
|
104
|
+
"SCOPE_REJECTED": {
|
|
105
|
+
"description": "Architect rejects the scope — rework needed",
|
|
106
|
+
"transitions_to": "scope"
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
"defaults": {
|
|
110
|
+
"mode": "strict",
|
|
111
|
+
"consultation": {
|
|
112
|
+
"enabled": true,
|
|
113
|
+
"models": ["codex"],
|
|
114
|
+
"parallel": true
|
|
115
|
+
},
|
|
116
|
+
"checks": {}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# RESEARCH Protocol
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Multi-agent research with 3-way investigation, synthesis, and critique. Three AI models independently investigate a question, their findings are synthesized into a single report, and then all three models critique the synthesis for gaps, errors, and bias.
|
|
6
|
+
|
|
7
|
+
**Core Principle**: Triangulate. No single model's knowledge is authoritative. Consensus across models is more reliable than any individual output.
|
|
8
|
+
|
|
9
|
+
## When to Use
|
|
10
|
+
|
|
11
|
+
**Use for**: Competitive analysis, technology evaluation, market research, architectural decision support, "what's the state of X?" questions, exploring unfamiliar domains.
|
|
12
|
+
|
|
13
|
+
**Skip for**: Implementation work (use SPIR/ASPIR), quick questions (just ask), experiments (use EXPERIMENT), known-answer lookups (just search).
|
|
14
|
+
|
|
15
|
+
## Output
|
|
16
|
+
|
|
17
|
+
All research artifacts go to `codev/research/`. The final deliverable is a single synthesis report at `codev/research/<topic>.md`.
|
|
18
|
+
|
|
19
|
+
## Phases
|
|
20
|
+
|
|
21
|
+
### Phase 1: Scope
|
|
22
|
+
|
|
23
|
+
**Purpose**: Make sure we're asking the right question before spending 3 models' worth of compute on answering it.
|
|
24
|
+
|
|
25
|
+
The builder:
|
|
26
|
+
1. Reads the architect's research request
|
|
27
|
+
2. Clarifies the question — what specifically are we trying to learn?
|
|
28
|
+
3. Defines the scope — what's in, what's out, what depth is needed
|
|
29
|
+
4. Defines acceptance criteria — what does a good answer look like?
|
|
30
|
+
5. Writes a **research brief** (`codev/research/<topic>-brief.md`) with:
|
|
31
|
+
- The precise question(s)
|
|
32
|
+
- Scope boundaries
|
|
33
|
+
- **Required targets** (when applicable — not all research questions have them). When the user names specific projects, products, or systems, those are exemplars of a CLASS, not an exhaustive list. The brief should:
|
|
34
|
+
- List the named targets as required coverage (each gets a dedicated section)
|
|
35
|
+
- Identify the CLASS they represent (e.g., "open-source always-on agent frameworks")
|
|
36
|
+
- Instruct investigators to find OTHER members of that class the user didn't name — discovering what the user SHOULD be thinking about is often the most valuable part of the research
|
|
37
|
+
- If an investigator cannot find information about a required target, they must say so explicitly — not silently skip it
|
|
38
|
+
- **Optional context** — additional sources that may be useful but are not required
|
|
39
|
+
- What a useful answer looks like
|
|
40
|
+
- Suggested sources or angles for the investigators
|
|
41
|
+
6. Sends the brief to the architect for approval
|
|
42
|
+
|
|
43
|
+
**Gate**: `scope-approval` — the architect confirms the question is correctly scoped before the 3-way investigation begins. This prevents wasting compute on a badly-framed question.
|
|
44
|
+
|
|
45
|
+
### Phase 2: Investigate (3-way parallel)
|
|
46
|
+
|
|
47
|
+
**Purpose**: Get three independent perspectives on the question.
|
|
48
|
+
|
|
49
|
+
The builder dispatches the research brief to three models (Gemini, Codex, Claude) via `consult`. Each model:
|
|
50
|
+
1. Receives the scoped research brief
|
|
51
|
+
2. Independently investigates using web search, its training knowledge, and reasoning
|
|
52
|
+
3. Produces a standalone investigation report with:
|
|
53
|
+
- **A dedicated section for each required target** from the brief. Every required target gets its own heading with specific findings — not mentioned in passing, not substituted with an easier target. If a required target yields no findings, the section must say "No information found" rather than being omitted.
|
|
54
|
+
- Findings (with sources where possible)
|
|
55
|
+
- Confidence levels on key claims
|
|
56
|
+
- Gaps it couldn't fill
|
|
57
|
+
- Surprises or things that contradicted expectations
|
|
58
|
+
|
|
59
|
+
The investigations run in **parallel** — each model works independently without seeing the others' output. This prevents anchoring bias.
|
|
60
|
+
|
|
61
|
+
Investigation reports are saved to:
|
|
62
|
+
- `codev/research/<topic>-gemini.md`
|
|
63
|
+
- `codev/research/<topic>-codex.md`
|
|
64
|
+
- `codev/research/<topic>-claude.md`
|
|
65
|
+
|
|
66
|
+
### Phase 3: Synthesize
|
|
67
|
+
|
|
68
|
+
**Purpose**: Merge three independent reports into one coherent document.
|
|
69
|
+
|
|
70
|
+
The builder:
|
|
71
|
+
1. Reads all three investigation reports
|
|
72
|
+
2. Identifies **consensus** — what all three agree on (highest confidence)
|
|
73
|
+
3. Identifies **disagreements** — where models contradict each other
|
|
74
|
+
4. Resolves conflicts — picks the best-supported position, notes the disagreement
|
|
75
|
+
5. Identifies **unique contributions** — things only one model found that the others missed
|
|
76
|
+
6. Writes the **synthesis report** (`codev/research/<topic>.md`) with:
|
|
77
|
+
- **Scope summary** — a short section (before the executive summary) restating the research question, required targets, and scope boundaries from the brief. A reader should understand what was asked without needing to read the brief separately.
|
|
78
|
+
- Executive summary
|
|
79
|
+
- Findings (organized by topic, not by model)
|
|
80
|
+
- Confidence annotations (consensus vs. single-source)
|
|
81
|
+
- Gaps and limitations
|
|
82
|
+
- Recommendations (if the research brief asked for them)
|
|
83
|
+
|
|
84
|
+
The synthesis is written as a **standalone document** — a reader should never need to reference the individual investigation reports. Those are kept as appendices for traceability.
|
|
85
|
+
|
|
86
|
+
### Phase 4: Critique (3-way review)
|
|
87
|
+
|
|
88
|
+
**Purpose**: Pressure-test the synthesis for gaps, errors, and bias.
|
|
89
|
+
|
|
90
|
+
The builder dispatches the synthesis report back to all three models for critique. Each model:
|
|
91
|
+
1. Reads the synthesis
|
|
92
|
+
2. **Checks coverage against the brief** — does every required target from the research brief have dedicated coverage in the synthesis? Lists any required targets that were named in the brief but have zero or minimal coverage. This is the #1 critique check.
|
|
93
|
+
3. Checks for factual errors or unsupported claims
|
|
94
|
+
4. Identifies gaps — important aspects the synthesis missed
|
|
95
|
+
5. Flags potential bias — did the synthesis over-weight one model's perspective?
|
|
96
|
+
6. Suggests specific improvements
|
|
97
|
+
|
|
98
|
+
The builder then:
|
|
99
|
+
1. Incorporates valid critique
|
|
100
|
+
2. Documents rejected critique with rationale
|
|
101
|
+
3. Finalizes the report
|
|
102
|
+
4. Commits to `codev/research/<topic>.md`
|
|
103
|
+
|
|
104
|
+
## File Structure
|
|
105
|
+
|
|
106
|
+
Only the brief and final report are checked in. Individual investigation reports and full critique outputs are working artifacts — useful during the process but not committed to the repo.
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
codev/research/
|
|
110
|
+
├── <topic>-brief.md # Phase 1: scoped research question (checked in)
|
|
111
|
+
└── <topic>.md # Phase 3+4: final synthesis (the deliverable, checked in)
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
The final report includes:
|
|
115
|
+
- A **"Disagreements and resolution"** section documenting where the three investigators disagreed and how the synthesis resolved each disagreement
|
|
116
|
+
- A **"Changes from critique"** section summarizing what the critique phase changed (not the full critique — just what was added, removed, or corrected and why)
|
|
117
|
+
|
|
118
|
+
Individual investigation reports (`<topic>-gemini.md`, `<topic>-codex.md`, `<topic>-claude.md`) and raw critique outputs are kept locally during the research process but NOT committed. The final report is the deliverable; the process artifacts are disposable.
|
|
119
|
+
|
|
120
|
+
## Best Practices
|
|
121
|
+
|
|
122
|
+
### Scoping
|
|
123
|
+
- A good research question is specific enough to answer in 1500-3000 words per model
|
|
124
|
+
- "What's the state of X?" is too broad — "What are the top 5 players in X, their strengths/weaknesses, and the structural gaps?" is better
|
|
125
|
+
- Include the "so what" — why are we researching this? What decision does it inform?
|
|
126
|
+
|
|
127
|
+
### Investigation
|
|
128
|
+
- Tell each model to cite sources where possible
|
|
129
|
+
- Tell each model to be candid about uncertainty — "I don't know" is better than confabulation
|
|
130
|
+
- Tell each model to note surprises — the most valuable findings are often the unexpected ones
|
|
131
|
+
|
|
132
|
+
### Synthesis
|
|
133
|
+
- Organize by topic, not by model ("here's what we found about X" not "here's what Gemini said")
|
|
134
|
+
- Weight consensus over single-model claims
|
|
135
|
+
- Don't smooth over disagreements — note them explicitly
|
|
136
|
+
- Keep the synthesis shorter than the sum of the investigations
|
|
137
|
+
|
|
138
|
+
### Critique
|
|
139
|
+
- Critiquers should focus on gaps and errors, not style
|
|
140
|
+
- A critique that says "add more about X" is useful; "rewrite the intro" is not
|
|
141
|
+
- The builder should reject critique that's outside the original scope
|
|
142
|
+
|
|
143
|
+
## Integration with Other Protocols
|
|
144
|
+
|
|
145
|
+
### Research → SPIR
|
|
146
|
+
When research informs a feature decision:
|
|
147
|
+
1. Reference the research report in the spec
|
|
148
|
+
2. Link specific findings as evidence for design choices
|
|
149
|
+
|
|
150
|
+
### Research → EXPERIMENT
|
|
151
|
+
When research identifies something worth testing:
|
|
152
|
+
1. Create an experiment to validate the research finding
|
|
153
|
+
2. Reference the research report as motivation
|
|
154
|
+
|
|
155
|
+
## Git Workflow
|
|
156
|
+
|
|
157
|
+
### Commits
|
|
158
|
+
```
|
|
159
|
+
[Research: topic] Scoped research brief
|
|
160
|
+
[Research: topic] 3-way investigation complete
|
|
161
|
+
[Research: topic] Synthesis report
|
|
162
|
+
[Research: topic] Final report (post-critique)
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### What to Commit
|
|
166
|
+
- All investigation reports (for traceability)
|
|
167
|
+
- The final synthesis (the deliverable)
|
|
168
|
+
- The critique rebuttals (for process transparency)
|
|
169
|
+
- Do NOT commit raw web search results or intermediate notes
|
|
@@ -14,6 +14,7 @@ This project uses **Codev** for AI-assisted development.
|
|
|
14
14
|
- **BUGFIX**: Bug fixes from GitHub issues (`codev/protocols/bugfix/protocol.md`)
|
|
15
15
|
- **EXPERIMENT**: Disciplined experimentation (`codev/protocols/experiment/protocol.md`)
|
|
16
16
|
- **MAINTAIN**: Codebase maintenance (`codev/protocols/maintain/protocol.md`)
|
|
17
|
+
- **RESEARCH**: Multi-agent research with 3-way investigation, synthesis, and critique (`codev/protocols/research/protocol.md`)
|
|
17
18
|
|
|
18
19
|
## Key Locations
|
|
19
20
|
|
|
@@ -12,6 +12,7 @@ This project uses **Codev** for AI-assisted development.
|
|
|
12
12
|
- **BUGFIX**: Bug fixes from GitHub issues (`codev/protocols/bugfix/protocol.md`)
|
|
13
13
|
- **EXPERIMENT**: Disciplined experimentation (`codev/protocols/experiment/protocol.md`)
|
|
14
14
|
- **MAINTAIN**: Codebase maintenance (`codev/protocols/maintain/protocol.md`)
|
|
15
|
+
- **RESEARCH**: Multi-agent research with 3-way investigation, synthesis, and critique (`codev/protocols/research/protocol.md`)
|
|
15
16
|
|
|
16
17
|
## Key Locations
|
|
17
18
|
|
|
@@ -63,6 +63,7 @@ A **protocol** is a structured workflow that defines how work progresses from id
|
|
|
63
63
|
| **SPIR** | New features | Specify → Plan → Implement → Review |
|
|
64
64
|
| **MAINTAIN** | Codebase hygiene | Dead code removal, documentation sync |
|
|
65
65
|
| **EXPERIMENT** | Research & prototyping | Hypothesis → Experiment → Conclude |
|
|
66
|
+
| **RESEARCH** | Multi-agent research | Scope → Investigate (3-way) → Synthesize → Critique (3-way) |
|
|
66
67
|
|
|
67
68
|
### Roles
|
|
68
69
|
|