research-diff 0.1.0__tar.gz → 0.2.0__tar.gz
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.
- research_diff-0.2.0/.claude-plugin/marketplace.json +16 -0
- research_diff-0.2.0/.github/workflows/research-diff.yml +44 -0
- research_diff-0.2.0/PKG-INFO +224 -0
- research_diff-0.2.0/README.md +201 -0
- research_diff-0.2.0/docs/evidence.svg +128 -0
- {research_diff-0.1.0 → research_diff-0.2.0}/docs/research.svg +38 -17
- research_diff-0.2.0/examples/batch-size/configs/e2.yaml +12 -0
- {research_diff-0.1.0 → research_diff-0.2.0}/examples/batch-size/notes/ideas.md +7 -0
- research_diff-0.2.0/examples/batch-size/notes/results.md +16 -0
- research_diff-0.2.0/examples/batch-size/out/e2.json +1 -0
- research_diff-0.2.0/examples/batch-size/paper/main.tex +27 -0
- research_diff-0.2.0/mods/research-diff/.claude-plugin/plugin.json +11 -0
- research_diff-0.2.0/mods/research-diff/.mcp.json +8 -0
- research_diff-0.2.0/mods/research-diff/hooks/hooks.json +64 -0
- research_diff-0.2.0/mods/research-diff/hooks/page.tsx +223 -0
- research_diff-0.2.0/mods/research-diff/hooks/register.tsx +662 -0
- research_diff-0.2.0/mods/research-diff/scripts/run.sh +16 -0
- research_diff-0.2.0/mods/research-diff/skills/research-diff-explain/SKILL.md +22 -0
- research_diff-0.2.0/mods/research-diff/types/index.d.ts +49 -0
- {research_diff-0.1.0 → research_diff-0.2.0}/pyproject.toml +4 -4
- research_diff-0.2.0/src/research_diff/__init__.py +3 -0
- research_diff-0.2.0/src/research_diff/activity.py +91 -0
- research_diff-0.2.0/src/research_diff/agent.py +326 -0
- research_diff-0.2.0/src/research_diff/agents.py +280 -0
- research_diff-0.2.0/src/research_diff/cli.py +343 -0
- {research_diff-0.1.0 → research_diff-0.2.0}/src/research_diff/compare.py +42 -8
- {research_diff-0.1.0 → research_diff-0.2.0}/src/research_diff/config.py +6 -2
- {research_diff-0.1.0 → research_diff-0.2.0}/src/research_diff/diff.py +15 -3
- research_diff-0.2.0/src/research_diff/doctor.py +105 -0
- research_diff-0.2.0/src/research_diff/evgraph.py +423 -0
- research_diff-0.2.0/src/research_diff/evidence.py +295 -0
- {research_diff-0.1.0 → research_diff-0.2.0}/src/research_diff/extract.py +34 -5
- {research_diff-0.1.0 → research_diff-0.2.0}/src/research_diff/graph.py +10 -3
- research_diff-0.2.0/src/research_diff/history.py +102 -0
- research_diff-0.2.0/src/research_diff/mcp_server.py +210 -0
- research_diff-0.2.0/src/research_diff/narrate.py +30 -0
- research_diff-0.2.0/src/research_diff/objectives.py +160 -0
- research_diff-0.2.0/src/research_diff/page.py +372 -0
- research_diff-0.2.0/src/research_diff/rank.py +88 -0
- research_diff-0.2.0/src/research_diff/readme.py +55 -0
- research_diff-0.2.0/src/research_diff/statusline.py +48 -0
- research_diff-0.2.0/src/research_diff/store.py +67 -0
- {research_diff-0.1.0 → research_diff-0.2.0}/src/research_diff/suggest.py +109 -5
- research_diff-0.2.0/src/research_diff/tui.py +130 -0
- research_diff-0.2.0/src/research_diff/watch.py +237 -0
- research_diff-0.2.0/tests/test_evidence_and_agents.py +185 -0
- {research_diff-0.1.0 → research_diff-0.2.0}/tests/test_research_diff.py +39 -8
- research_diff-0.1.0/PKG-INFO +0 -111
- research_diff-0.1.0/README.md +0 -88
- research_diff-0.1.0/examples/batch-size/notes/results.md +0 -7
- research_diff-0.1.0/examples/batch-size/paper/main.tex +0 -7
- research_diff-0.1.0/src/research_diff/__init__.py +0 -2
- research_diff-0.1.0/src/research_diff/agent.py +0 -141
- research_diff-0.1.0/src/research_diff/cli.py +0 -153
- research_diff-0.1.0/src/research_diff/mcp_server.py +0 -112
- research_diff-0.1.0/src/research_diff/readme.py +0 -38
- research_diff-0.1.0/src/research_diff/watch.py +0 -69
- {research_diff-0.1.0 → research_diff-0.2.0}/.gitattributes +0 -0
- {research_diff-0.1.0 → research_diff-0.2.0}/.github/workflows/ci.yml +0 -0
- {research_diff-0.1.0 → research_diff-0.2.0}/.github/workflows/release.yml +0 -0
- {research_diff-0.1.0 → research_diff-0.2.0}/.gitignore +0 -0
- {research_diff-0.1.0 → research_diff-0.2.0}/LICENSE +0 -0
- {research_diff-0.1.0 → research_diff-0.2.0}/examples/batch-size/configs/e1.yaml +0 -0
- {research_diff-0.1.0 → research_diff-0.2.0}/examples/batch-size/out/e1.json +0 -0
- {research_diff-0.1.0 → research_diff-0.2.0}/research-diff.toml +0 -0
- {research_diff-0.1.0 → research_diff-0.2.0}/src/research_diff/__main__.py +0 -0
- {research_diff-0.1.0 → research_diff-0.2.0}/src/research_diff/trackers.py +0 -0
- {research_diff-0.1.0 → research_diff-0.2.0}/tests/conftest.py +0 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "research-diff",
|
|
3
|
+
"owner": {
|
|
4
|
+
"name": "simplifiedmachine"
|
|
5
|
+
},
|
|
6
|
+
"metadata": {
|
|
7
|
+
"description": "research-diff for Claude Code: what supports and what contradicts each claim of your paper, live, while Claude and its agents run experiments and write."
|
|
8
|
+
},
|
|
9
|
+
"plugins": [
|
|
10
|
+
{
|
|
11
|
+
"name": "research-diff",
|
|
12
|
+
"source": "./mods/research-diff",
|
|
13
|
+
"description": "A Research diff pane beside the chat: the paper's claims with their evidence and contradictions, what changed since you last looked, and a team of agents on one study."
|
|
14
|
+
}
|
|
15
|
+
]
|
|
16
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
name: research diff
|
|
2
|
+
|
|
3
|
+
# What a pull request does to the research, and above all to the evidence of the paper's claims (supported, contested,
|
|
4
|
+
# contradicted), as a comment on it and in the run's summary; the pictures (diff.svg, evidence.svg and the interactive
|
|
5
|
+
# evidence.html) are the run's "research-diff" artifact. Copy this file into another repository to get the same there
|
|
6
|
+
# (replace `pip install -e .` with `pip install research-diff`).
|
|
7
|
+
on:
|
|
8
|
+
pull_request:
|
|
9
|
+
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
pull-requests: write
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
diff:
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
with:
|
|
20
|
+
fetch-depth: 0
|
|
21
|
+
- uses: actions/setup-python@v5
|
|
22
|
+
with:
|
|
23
|
+
python-version: "3.12"
|
|
24
|
+
- run: python -m pip install -e .
|
|
25
|
+
- name: What this pull request does to the research and its evidence
|
|
26
|
+
run: |
|
|
27
|
+
research-diff diff --base "origin/${{ github.base_ref }}" --head HEAD --out research-diff-out
|
|
28
|
+
research-diff evidence --at HEAD --out research-diff-out
|
|
29
|
+
research-diff comment --base "origin/${{ github.base_ref }}" --head HEAD --out research-diff-out/comment.md
|
|
30
|
+
echo >> research-diff-out/comment.md
|
|
31
|
+
echo "The pictures: the **research-diff** artifact of [this run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})." >> research-diff-out/comment.md
|
|
32
|
+
cat research-diff-out/comment.md >> "$GITHUB_STEP_SUMMARY"
|
|
33
|
+
- uses: actions/upload-artifact@v4
|
|
34
|
+
with:
|
|
35
|
+
name: research-diff
|
|
36
|
+
path: research-diff-out
|
|
37
|
+
- name: Comment on the pull request
|
|
38
|
+
# A pull request from a fork gets a read-only token: it has the summary and the artifact instead.
|
|
39
|
+
if: github.event.pull_request.head.repo.full_name == github.repository
|
|
40
|
+
env:
|
|
41
|
+
GH_TOKEN: ${{ github.token }}
|
|
42
|
+
run: |
|
|
43
|
+
gh pr comment "${{ github.event.pull_request.number }}" --body-file research-diff-out/comment.md --edit-last \
|
|
44
|
+
|| gh pr comment "${{ github.event.pull_request.number }}" --body-file research-diff-out/comment.md
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: research-diff
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Maps your research from its notes, experiment configs, results and paper, draws which evidence supports and which contradicts each claim of the paper, and shows what each iteration (and each agent) changed. Built for doing research with AI coding agents.
|
|
5
|
+
Project-URL: Homepage, https://github.com/simplifiedmachine/research-diff
|
|
6
|
+
Project-URL: Documentation, https://github.com/simplifiedmachine/research-diff/wiki
|
|
7
|
+
Author: simplifiedmachine
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: ai-agents,argument-map,claude-code,contradictions,evidence,experiment-tracking,hypotheses,mcp,multi-agent,reproducibility,research
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
14
|
+
Classifier: Topic :: Scientific/Engineering
|
|
15
|
+
Requires-Python: >=3.11
|
|
16
|
+
Requires-Dist: system-diff==0.8.0
|
|
17
|
+
Provides-Extra: dev
|
|
18
|
+
Requires-Dist: mcp>=1.10; extra == 'dev'
|
|
19
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
20
|
+
Provides-Extra: mcp
|
|
21
|
+
Requires-Dist: mcp>=1.10; extra == 'mcp'
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# research-diff
|
|
25
|
+
|
|
26
|
+
### `git diff` shows you lines. **research-diff shows you what your evidence says about your paper.**
|
|
27
|
+
|
|
28
|
+
When you run experiments and write a paper with Claude, and more so with a team of agents each on its own experiments
|
|
29
|
+
and sections, the paper's claims drift away from its evidence faster than anyone can re-read it. A new run quietly
|
|
30
|
+
weakens a hypothesis that three claims rely on; one agent's discussion contradicts another agent's results section; a
|
|
31
|
+
number in the paper no longer matches the results file.
|
|
32
|
+
|
|
33
|
+
**research-diff draws the paper's argument as a graph and keeps it current**: which findings and conclusions are
|
|
34
|
+
supported by which evidence, and above all **which evidence contradicts your own claims**, including where the paper
|
|
35
|
+
contradicts itself and where one agent's work contradicts another's. In plain colours: green supports, red contradicts.
|
|
36
|
+
|
|
37
|
+
<!-- research-map:begin -->
|
|
38
|
+

|
|
39
|
+
|
|
40
|
+

|
|
41
|
+
|
|
42
|
+
<details><summary>3 open warnings</summary>
|
|
43
|
+
|
|
44
|
+
- C1 is contradicted by C2
|
|
45
|
+
- C3 expects E2.results acc.batch512 < 0.85, but it is 0.872
|
|
46
|
+
- H2 is open and no experiment tests it
|
|
47
|
+
|
|
48
|
+
</details>
|
|
49
|
+
<!-- research-map:end -->
|
|
50
|
+
|
|
51
|
+
The graph above is this repository's own example (`examples/batch-size`), regenerated from its files on every change:
|
|
52
|
+
two agents, `batch-agent` and `lr-agent`; the Discussion's C2 contradicts the Results' C1, and C3 expects a number
|
|
53
|
+
(batch 512 below 85%) that the experiment E2 does not give.
|
|
54
|
+
|
|
55
|
+
## The evidence graph
|
|
56
|
+
|
|
57
|
+
Left to right: **evidence** (results, tracker runs, an experiment's numbers, optionally citations), **hypotheses**,
|
|
58
|
+
**findings**, **claims**, the paper's statements in a band per paper section. Every statement gets a verdict:
|
|
59
|
+
|
|
60
|
+
| | Verdict | Means |
|
|
61
|
+
|---|---|---|
|
|
62
|
+
| ✓ | supported | evidence for it, none against it |
|
|
63
|
+
| ◐ | contested | evidence for it and against it |
|
|
64
|
+
| ✗ | contradicted | evidence against it and none for it, or you marked it refuted |
|
|
65
|
+
| ○ | no evidence | nothing backs it, or only what has no evidence itself (an *ungrounded* support) |
|
|
66
|
+
|
|
67
|
+
A support only counts while its source holds. When a hypothesis is refuted, or a result is itself contradicted, the
|
|
68
|
+
support it gave becomes a **broken support** (dashed red), with why: *"C1 relies on H1, which R4 contradicts"*. So a
|
|
69
|
+
contradiction reaches every claim built on what it contradicts. A number a claim `expects:` supports it while it holds
|
|
70
|
+
and contradicts it when it does not.
|
|
71
|
+
|
|
72
|
+
```sh
|
|
73
|
+
research-diff evidence --out docs # evidence.svg (README, appendix, slides), evidence.html (interactive),
|
|
74
|
+
# evidence.mmd (Mermaid), evidence.md (a table), evidence.json
|
|
75
|
+
research-diff evidence --strict # exit 1 while a statement is contradicted or contested (for CI)
|
|
76
|
+
research-diff show # the same, in any terminal; `research-diff show C3` for one claim's chain
|
|
77
|
+
research-diff suggest --links # your LLM proposes supports/contradicts links nobody wrote, as a patch
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The interactive page: click a claim and its evidence chain lights up; *Only contradictions* hides everything else; one
|
|
81
|
+
agent's work at a time.
|
|
82
|
+
|
|
83
|
+
## What it reads
|
|
84
|
+
|
|
85
|
+
Markers in your own files, in one grammar: an id (`Q` question, `H` hypothesis, `E` experiment, `R` result, `F`
|
|
86
|
+
finding, `C` claim, and a number) and a title, then links and a status on the lines after it.
|
|
87
|
+
|
|
88
|
+
```markdown
|
|
89
|
+
## H2: Learning-rate warm-up removes the gap <- notes (Markdown): a heading or a list item
|
|
90
|
+
answers: Q1
|
|
91
|
+
status: open <- open | supported | refuted | anything you like
|
|
92
|
+
by: lr-agent <- who owns it (an agent of a team, or a person)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
```latex
|
|
96
|
+
\section{Discussion} % the paper's sections become the graph's bands
|
|
97
|
+
% C2: Batch size does not matter once the learning rate is scaled
|
|
98
|
+
% relies on: F1, H3
|
|
99
|
+
% contradicts: C1 <- the paper contradicting itself, said out loud
|
|
100
|
+
% expects: E2.results acc.batch512 > 0.86 <- a number it needs; checked on every change
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
| Where | How |
|
|
104
|
+
|---|---|
|
|
105
|
+
| Notes (`.md`) | definitions as above; `tests:`, `of:`, `supports:`, `weakens:`, `contradicts:`, `relies on:`, `metrics: acc=0.91`, `by:` |
|
|
106
|
+
| The paper (LaTeX, or Markdown) | a comment: `% C1: Small batches win` with the same lines; the paragraph's `\cite{…}` become its sources; its `\section{}` its band |
|
|
107
|
+
| Experiment configs (YAML, JSON, TOML) | a `research:` block: `id`, `title`, `tests`, `status`, and `results: out/e1.json`, whose numbers become the result `E1.results` |
|
|
108
|
+
| Scripts and notebooks | a comment: `# research-diff: E2 tests H2` |
|
|
109
|
+
| Either end of a link | `supported by: R1`, `contradicted by: R4`, `weakened by: R2` are the same links written on the claim |
|
|
110
|
+
|
|
111
|
+
The graph is built from markers only, so the same files always give the same graph. It warns when a claim relies on
|
|
112
|
+
nothing or on a refuted hypothesis, when a number no longer meets what a claim `expects:`, when an open hypothesis has
|
|
113
|
+
no experiment, and when a link points at nothing.
|
|
114
|
+
|
|
115
|
+
## Install
|
|
116
|
+
|
|
117
|
+
1. The engine (Python 3.11+):
|
|
118
|
+
```sh
|
|
119
|
+
pip install "research-diff[mcp]" # or: pipx install "research-diff[mcp]"
|
|
120
|
+
```
|
|
121
|
+
2. The plugin, in Claude Code (the pane beside the chat, the hooks and the MCP server):
|
|
122
|
+
```
|
|
123
|
+
/plugin marketplace add simplifiedmachine/research-diff
|
|
124
|
+
/plugin install research-diff
|
|
125
|
+
```
|
|
126
|
+
Or without the pane: `research-diff setup claude` (hooks, status line, a skill and the MCP server; `--undo`).
|
|
127
|
+
3. Restart Claude Code. The pane opens beside the chat; `/research-diff` opens it again.
|
|
128
|
+
|
|
129
|
+
## In Claude Code
|
|
130
|
+
|
|
131
|
+
- **The pane**: `n` Now · `r` Review · `e` Evidence · `a` Agents · `h` History. Arrows pick a claim (its evidence
|
|
132
|
+
lights up), Enter zooms into its evidence chain, `b` goes back, `f` follows Claude. `/research-diff tui` opens the
|
|
133
|
+
same in a terminal of its own, and `research-diff watch` in a browser at `http://127.0.0.1:8766/`.
|
|
134
|
+
- **Now**: where Claude (or which agent) is working, every statement worst first, and what is **worth a look** since
|
|
135
|
+
you last looked, ranked by consequence (the paper contradicting itself first) and each with why it matters.
|
|
136
|
+
- **Review**: everything since your checkpoint, exactly, with a picture of only what changed.
|
|
137
|
+
- **Evidence**: every statement by paper section with what supports it and what contradicts it.
|
|
138
|
+
- **Agents**: the team, what each agent owns, its verdicts, where it contradicts another agent, and the bus.
|
|
139
|
+
- **History**: how the research got here: *"You asked: run the LR ablation → it got: R2, H1 supported → contested,
|
|
140
|
+
1 new contradiction (C2 contradicts C1)"*, for the whole study or one claim.
|
|
141
|
+
- **In the chat**: one line when an edit or a run moves a claim's verdict or makes a contradiction, and one at the end
|
|
142
|
+
of the turn. The status line keeps the count of contradictions in view.
|
|
143
|
+
- **Ask Claude** "does C3 still hold?" or "what contradicts the paper?": it answers from the MCP tools
|
|
144
|
+
(`research_evidence`, `explain`, `research_diff`, `research_map`), with the picture.
|
|
145
|
+
- **Objectives**: research-diff learns what you keep asking for ("three seeds for every number", "don't claim beyond
|
|
146
|
+
the 8k split"), shows it, keeps it in front of Claude and every agent, and marks changes that touch it. `x` clears
|
|
147
|
+
one you disagree with; `research-diff objectives add TEXT` states one.
|
|
148
|
+
|
|
149
|
+
## Teams of agents
|
|
150
|
+
|
|
151
|
+
For work across the study, Claude plans a team with `plan_agents`: one agent per paper section, or per hypothesis
|
|
152
|
+
(its experiments and their results), or as you say. Each agent gets a brief: what it owns, the evidence its work
|
|
153
|
+
relies on (owned by others), the contradictions already open on its nodes, and the rules.
|
|
154
|
+
|
|
155
|
+
- Each agent **claims** its nodes (`claim`) and writes `by: <name>` under its markers: the graph colours every box by
|
|
156
|
+
its agent.
|
|
157
|
+
- The **bus** has a topic per node. The hooks publish every change on the topic of the node it touched, as it happens;
|
|
158
|
+
a **new contradiction goes to the owner of the contradicted node**, naming both agents: *"CONTRADICTION: R4
|
|
159
|
+
contradicts C1 (R4 is lr-agent's, C1 is batch-agent's)"*. Agents `publish` their own notes too.
|
|
160
|
+
- Each agent hears the nodes it owns and everything upstream of them in the evidence graph, and its unread messages
|
|
161
|
+
reach it with its next tool result (the PostToolUse hook), without waiting on anyone.
|
|
162
|
+
- The Agents tab and the graph's *across agents* list show where one agent's work contradicts another's.
|
|
163
|
+
|
|
164
|
+
```sh
|
|
165
|
+
research-diff agents plan "write the batch-size paper" # the same from a terminal: the briefs
|
|
166
|
+
research-diff agents # the team and the bus
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Use without Claude Code
|
|
170
|
+
|
|
171
|
+
```sh
|
|
172
|
+
research-diff map --out docs # research.svg and research.json: the whole map
|
|
173
|
+
research-diff diff --base HEAD # what your uncommitted iteration did (--narrate: in plain words, by your LLM)
|
|
174
|
+
research-diff sync # MLflow / W&B runs into research/runs.json
|
|
175
|
+
research-diff checkpoint # mark what you have understood
|
|
176
|
+
research-diff diff # only what came after that (--base turn: this turn of your agent)
|
|
177
|
+
research-diff history --commits 50 # the research's history, from git too
|
|
178
|
+
research-diff readme # keep the README's evidence graph and map current (--check in CI)
|
|
179
|
+
research-diff doctor # why it is quiet, slow or wrong here
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
A diff reads like: *1 new contradiction (C1 relies on H1, which is refuted); C1: no evidence → contradicted; adds 1
|
|
183
|
+
hypothesis (H3); H1: open → refuted; E1.results acc.b32: 0.874 → 0.881 (+0.8%); 1 new link.* It comes with the exact
|
|
184
|
+
list (`plan.txt`) and a picture of only what changed (`diff.svg`).
|
|
185
|
+
|
|
186
|
+
**Pull requests**: every pull request gets its research diff and the evidence table as a comment, with the evidence
|
|
187
|
+
graph in Mermaid, which GitHub draws (`.github/workflows/research-diff.yml`, which you can copy;
|
|
188
|
+
`research-diff comment` writes the comment).
|
|
189
|
+
|
|
190
|
+
## Experiment trackers
|
|
191
|
+
|
|
192
|
+
Runs logged to MLflow (its local `mlruns/` store) or W&B (its local `wandb/` folders) become results of the experiment
|
|
193
|
+
they are tagged with: `research-diff.experiment` (or `research_id`) as an MLflow tag or param, `research_id` in the W&B
|
|
194
|
+
config. Tracker folders are usually git-ignored, so `research-diff sync` copies their runs into `research/runs.json`,
|
|
195
|
+
which is tracked: the runs are then on the map, in git and in the next diff. The hooks, the live page and the MCP tools
|
|
196
|
+
sync on their own.
|
|
197
|
+
|
|
198
|
+
## Markers suggested by your LLM
|
|
199
|
+
|
|
200
|
+
```sh
|
|
201
|
+
research-diff suggest # notes and paper files with no marker yet, or name the files
|
|
202
|
+
git apply .git/research-diff/suggest.patch
|
|
203
|
+
research-diff suggest --links # supports / contradicts / weakens links between the nodes you have
|
|
204
|
+
git apply .git/research-diff/links.patch
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Your LLM (the one your Claude Code uses) proposes markers for what the text already says, and links (above all the
|
|
208
|
+
contradictions) that the text and the numbers show. Each proposal is checked before it reaches the patch: a real line
|
|
209
|
+
of a file it was shown, a marker in that file's own form, ids that exist (or, for a new marker, are not used yet), a
|
|
210
|
+
link not already written. Nothing is written until you apply the patch.
|
|
211
|
+
|
|
212
|
+
## Privacy
|
|
213
|
+
|
|
214
|
+
Everything stays on your machine, under `.git/research-diff/`: never committed, never sent anywhere. The only exception
|
|
215
|
+
is the optional LLM features (objectives, `suggest`, `--narrate`), which send your requests or the text of the files
|
|
216
|
+
you name to the LLM your own Claude Code already uses. `RESEARCH_DIFF_LLM=off` turns them off;
|
|
217
|
+
`RESEARCH_DIFF_WEB=off` keeps the hooks from starting the web page.
|
|
218
|
+
|
|
219
|
+
The pictures, git reading and LLM discovery are [system-diff](https://github.com/simplifiedmachine/system-diff)'s; the
|
|
220
|
+
pane is system-diff's pane, showing the research.
|
|
221
|
+
|
|
222
|
+
## License
|
|
223
|
+
|
|
224
|
+
MIT
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# research-diff
|
|
2
|
+
|
|
3
|
+
### `git diff` shows you lines. **research-diff shows you what your evidence says about your paper.**
|
|
4
|
+
|
|
5
|
+
When you run experiments and write a paper with Claude, and more so with a team of agents each on its own experiments
|
|
6
|
+
and sections, the paper's claims drift away from its evidence faster than anyone can re-read it. A new run quietly
|
|
7
|
+
weakens a hypothesis that three claims rely on; one agent's discussion contradicts another agent's results section; a
|
|
8
|
+
number in the paper no longer matches the results file.
|
|
9
|
+
|
|
10
|
+
**research-diff draws the paper's argument as a graph and keeps it current**: which findings and conclusions are
|
|
11
|
+
supported by which evidence, and above all **which evidence contradicts your own claims**, including where the paper
|
|
12
|
+
contradicts itself and where one agent's work contradicts another's. In plain colours: green supports, red contradicts.
|
|
13
|
+
|
|
14
|
+
<!-- research-map:begin -->
|
|
15
|
+

|
|
16
|
+
|
|
17
|
+

|
|
18
|
+
|
|
19
|
+
<details><summary>3 open warnings</summary>
|
|
20
|
+
|
|
21
|
+
- C1 is contradicted by C2
|
|
22
|
+
- C3 expects E2.results acc.batch512 < 0.85, but it is 0.872
|
|
23
|
+
- H2 is open and no experiment tests it
|
|
24
|
+
|
|
25
|
+
</details>
|
|
26
|
+
<!-- research-map:end -->
|
|
27
|
+
|
|
28
|
+
The graph above is this repository's own example (`examples/batch-size`), regenerated from its files on every change:
|
|
29
|
+
two agents, `batch-agent` and `lr-agent`; the Discussion's C2 contradicts the Results' C1, and C3 expects a number
|
|
30
|
+
(batch 512 below 85%) that the experiment E2 does not give.
|
|
31
|
+
|
|
32
|
+
## The evidence graph
|
|
33
|
+
|
|
34
|
+
Left to right: **evidence** (results, tracker runs, an experiment's numbers, optionally citations), **hypotheses**,
|
|
35
|
+
**findings**, **claims**, the paper's statements in a band per paper section. Every statement gets a verdict:
|
|
36
|
+
|
|
37
|
+
| | Verdict | Means |
|
|
38
|
+
|---|---|---|
|
|
39
|
+
| ✓ | supported | evidence for it, none against it |
|
|
40
|
+
| ◐ | contested | evidence for it and against it |
|
|
41
|
+
| ✗ | contradicted | evidence against it and none for it, or you marked it refuted |
|
|
42
|
+
| ○ | no evidence | nothing backs it, or only what has no evidence itself (an *ungrounded* support) |
|
|
43
|
+
|
|
44
|
+
A support only counts while its source holds. When a hypothesis is refuted, or a result is itself contradicted, the
|
|
45
|
+
support it gave becomes a **broken support** (dashed red), with why: *"C1 relies on H1, which R4 contradicts"*. So a
|
|
46
|
+
contradiction reaches every claim built on what it contradicts. A number a claim `expects:` supports it while it holds
|
|
47
|
+
and contradicts it when it does not.
|
|
48
|
+
|
|
49
|
+
```sh
|
|
50
|
+
research-diff evidence --out docs # evidence.svg (README, appendix, slides), evidence.html (interactive),
|
|
51
|
+
# evidence.mmd (Mermaid), evidence.md (a table), evidence.json
|
|
52
|
+
research-diff evidence --strict # exit 1 while a statement is contradicted or contested (for CI)
|
|
53
|
+
research-diff show # the same, in any terminal; `research-diff show C3` for one claim's chain
|
|
54
|
+
research-diff suggest --links # your LLM proposes supports/contradicts links nobody wrote, as a patch
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
The interactive page: click a claim and its evidence chain lights up; *Only contradictions* hides everything else; one
|
|
58
|
+
agent's work at a time.
|
|
59
|
+
|
|
60
|
+
## What it reads
|
|
61
|
+
|
|
62
|
+
Markers in your own files, in one grammar: an id (`Q` question, `H` hypothesis, `E` experiment, `R` result, `F`
|
|
63
|
+
finding, `C` claim, and a number) and a title, then links and a status on the lines after it.
|
|
64
|
+
|
|
65
|
+
```markdown
|
|
66
|
+
## H2: Learning-rate warm-up removes the gap <- notes (Markdown): a heading or a list item
|
|
67
|
+
answers: Q1
|
|
68
|
+
status: open <- open | supported | refuted | anything you like
|
|
69
|
+
by: lr-agent <- who owns it (an agent of a team, or a person)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
```latex
|
|
73
|
+
\section{Discussion} % the paper's sections become the graph's bands
|
|
74
|
+
% C2: Batch size does not matter once the learning rate is scaled
|
|
75
|
+
% relies on: F1, H3
|
|
76
|
+
% contradicts: C1 <- the paper contradicting itself, said out loud
|
|
77
|
+
% expects: E2.results acc.batch512 > 0.86 <- a number it needs; checked on every change
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
| Where | How |
|
|
81
|
+
|---|---|
|
|
82
|
+
| Notes (`.md`) | definitions as above; `tests:`, `of:`, `supports:`, `weakens:`, `contradicts:`, `relies on:`, `metrics: acc=0.91`, `by:` |
|
|
83
|
+
| The paper (LaTeX, or Markdown) | a comment: `% C1: Small batches win` with the same lines; the paragraph's `\cite{…}` become its sources; its `\section{}` its band |
|
|
84
|
+
| Experiment configs (YAML, JSON, TOML) | a `research:` block: `id`, `title`, `tests`, `status`, and `results: out/e1.json`, whose numbers become the result `E1.results` |
|
|
85
|
+
| Scripts and notebooks | a comment: `# research-diff: E2 tests H2` |
|
|
86
|
+
| Either end of a link | `supported by: R1`, `contradicted by: R4`, `weakened by: R2` are the same links written on the claim |
|
|
87
|
+
|
|
88
|
+
The graph is built from markers only, so the same files always give the same graph. It warns when a claim relies on
|
|
89
|
+
nothing or on a refuted hypothesis, when a number no longer meets what a claim `expects:`, when an open hypothesis has
|
|
90
|
+
no experiment, and when a link points at nothing.
|
|
91
|
+
|
|
92
|
+
## Install
|
|
93
|
+
|
|
94
|
+
1. The engine (Python 3.11+):
|
|
95
|
+
```sh
|
|
96
|
+
pip install "research-diff[mcp]" # or: pipx install "research-diff[mcp]"
|
|
97
|
+
```
|
|
98
|
+
2. The plugin, in Claude Code (the pane beside the chat, the hooks and the MCP server):
|
|
99
|
+
```
|
|
100
|
+
/plugin marketplace add simplifiedmachine/research-diff
|
|
101
|
+
/plugin install research-diff
|
|
102
|
+
```
|
|
103
|
+
Or without the pane: `research-diff setup claude` (hooks, status line, a skill and the MCP server; `--undo`).
|
|
104
|
+
3. Restart Claude Code. The pane opens beside the chat; `/research-diff` opens it again.
|
|
105
|
+
|
|
106
|
+
## In Claude Code
|
|
107
|
+
|
|
108
|
+
- **The pane**: `n` Now · `r` Review · `e` Evidence · `a` Agents · `h` History. Arrows pick a claim (its evidence
|
|
109
|
+
lights up), Enter zooms into its evidence chain, `b` goes back, `f` follows Claude. `/research-diff tui` opens the
|
|
110
|
+
same in a terminal of its own, and `research-diff watch` in a browser at `http://127.0.0.1:8766/`.
|
|
111
|
+
- **Now**: where Claude (or which agent) is working, every statement worst first, and what is **worth a look** since
|
|
112
|
+
you last looked, ranked by consequence (the paper contradicting itself first) and each with why it matters.
|
|
113
|
+
- **Review**: everything since your checkpoint, exactly, with a picture of only what changed.
|
|
114
|
+
- **Evidence**: every statement by paper section with what supports it and what contradicts it.
|
|
115
|
+
- **Agents**: the team, what each agent owns, its verdicts, where it contradicts another agent, and the bus.
|
|
116
|
+
- **History**: how the research got here: *"You asked: run the LR ablation → it got: R2, H1 supported → contested,
|
|
117
|
+
1 new contradiction (C2 contradicts C1)"*, for the whole study or one claim.
|
|
118
|
+
- **In the chat**: one line when an edit or a run moves a claim's verdict or makes a contradiction, and one at the end
|
|
119
|
+
of the turn. The status line keeps the count of contradictions in view.
|
|
120
|
+
- **Ask Claude** "does C3 still hold?" or "what contradicts the paper?": it answers from the MCP tools
|
|
121
|
+
(`research_evidence`, `explain`, `research_diff`, `research_map`), with the picture.
|
|
122
|
+
- **Objectives**: research-diff learns what you keep asking for ("three seeds for every number", "don't claim beyond
|
|
123
|
+
the 8k split"), shows it, keeps it in front of Claude and every agent, and marks changes that touch it. `x` clears
|
|
124
|
+
one you disagree with; `research-diff objectives add TEXT` states one.
|
|
125
|
+
|
|
126
|
+
## Teams of agents
|
|
127
|
+
|
|
128
|
+
For work across the study, Claude plans a team with `plan_agents`: one agent per paper section, or per hypothesis
|
|
129
|
+
(its experiments and their results), or as you say. Each agent gets a brief: what it owns, the evidence its work
|
|
130
|
+
relies on (owned by others), the contradictions already open on its nodes, and the rules.
|
|
131
|
+
|
|
132
|
+
- Each agent **claims** its nodes (`claim`) and writes `by: <name>` under its markers: the graph colours every box by
|
|
133
|
+
its agent.
|
|
134
|
+
- The **bus** has a topic per node. The hooks publish every change on the topic of the node it touched, as it happens;
|
|
135
|
+
a **new contradiction goes to the owner of the contradicted node**, naming both agents: *"CONTRADICTION: R4
|
|
136
|
+
contradicts C1 (R4 is lr-agent's, C1 is batch-agent's)"*. Agents `publish` their own notes too.
|
|
137
|
+
- Each agent hears the nodes it owns and everything upstream of them in the evidence graph, and its unread messages
|
|
138
|
+
reach it with its next tool result (the PostToolUse hook), without waiting on anyone.
|
|
139
|
+
- The Agents tab and the graph's *across agents* list show where one agent's work contradicts another's.
|
|
140
|
+
|
|
141
|
+
```sh
|
|
142
|
+
research-diff agents plan "write the batch-size paper" # the same from a terminal: the briefs
|
|
143
|
+
research-diff agents # the team and the bus
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Use without Claude Code
|
|
147
|
+
|
|
148
|
+
```sh
|
|
149
|
+
research-diff map --out docs # research.svg and research.json: the whole map
|
|
150
|
+
research-diff diff --base HEAD # what your uncommitted iteration did (--narrate: in plain words, by your LLM)
|
|
151
|
+
research-diff sync # MLflow / W&B runs into research/runs.json
|
|
152
|
+
research-diff checkpoint # mark what you have understood
|
|
153
|
+
research-diff diff # only what came after that (--base turn: this turn of your agent)
|
|
154
|
+
research-diff history --commits 50 # the research's history, from git too
|
|
155
|
+
research-diff readme # keep the README's evidence graph and map current (--check in CI)
|
|
156
|
+
research-diff doctor # why it is quiet, slow or wrong here
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
A diff reads like: *1 new contradiction (C1 relies on H1, which is refuted); C1: no evidence → contradicted; adds 1
|
|
160
|
+
hypothesis (H3); H1: open → refuted; E1.results acc.b32: 0.874 → 0.881 (+0.8%); 1 new link.* It comes with the exact
|
|
161
|
+
list (`plan.txt`) and a picture of only what changed (`diff.svg`).
|
|
162
|
+
|
|
163
|
+
**Pull requests**: every pull request gets its research diff and the evidence table as a comment, with the evidence
|
|
164
|
+
graph in Mermaid, which GitHub draws (`.github/workflows/research-diff.yml`, which you can copy;
|
|
165
|
+
`research-diff comment` writes the comment).
|
|
166
|
+
|
|
167
|
+
## Experiment trackers
|
|
168
|
+
|
|
169
|
+
Runs logged to MLflow (its local `mlruns/` store) or W&B (its local `wandb/` folders) become results of the experiment
|
|
170
|
+
they are tagged with: `research-diff.experiment` (or `research_id`) as an MLflow tag or param, `research_id` in the W&B
|
|
171
|
+
config. Tracker folders are usually git-ignored, so `research-diff sync` copies their runs into `research/runs.json`,
|
|
172
|
+
which is tracked: the runs are then on the map, in git and in the next diff. The hooks, the live page and the MCP tools
|
|
173
|
+
sync on their own.
|
|
174
|
+
|
|
175
|
+
## Markers suggested by your LLM
|
|
176
|
+
|
|
177
|
+
```sh
|
|
178
|
+
research-diff suggest # notes and paper files with no marker yet, or name the files
|
|
179
|
+
git apply .git/research-diff/suggest.patch
|
|
180
|
+
research-diff suggest --links # supports / contradicts / weakens links between the nodes you have
|
|
181
|
+
git apply .git/research-diff/links.patch
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Your LLM (the one your Claude Code uses) proposes markers for what the text already says, and links (above all the
|
|
185
|
+
contradictions) that the text and the numbers show. Each proposal is checked before it reaches the patch: a real line
|
|
186
|
+
of a file it was shown, a marker in that file's own form, ids that exist (or, for a new marker, are not used yet), a
|
|
187
|
+
link not already written. Nothing is written until you apply the patch.
|
|
188
|
+
|
|
189
|
+
## Privacy
|
|
190
|
+
|
|
191
|
+
Everything stays on your machine, under `.git/research-diff/`: never committed, never sent anywhere. The only exception
|
|
192
|
+
is the optional LLM features (objectives, `suggest`, `--narrate`), which send your requests or the text of the files
|
|
193
|
+
you name to the LLM your own Claude Code already uses. `RESEARCH_DIFF_LLM=off` turns them off;
|
|
194
|
+
`RESEARCH_DIFF_WEB=off` keeps the hooks from starting the web page.
|
|
195
|
+
|
|
196
|
+
The pictures, git reading and LLM discovery are [system-diff](https://github.com/simplifiedmachine/system-diff)'s; the
|
|
197
|
+
pane is system-diff's pane, showing the research.
|
|
198
|
+
|
|
199
|
+
## License
|
|
200
|
+
|
|
201
|
+
MIT
|