Open source · AGPL-3.0 · self-hostable

By the time you write it, you won’t remember why.

Research — a nine-month thesis, a four-year PhD, a postdoc that outlives both — is reading, runs and decisions scattered across six tools that each forget the other five. WeaveForge is the one workspace that keeps the thread, so the paper you read in week three is still attached to the run it inspired and the section it ends up in.

one projectlibraryin Zoteronotesin Obsidianplanin a task appexperimentsin Weights & Biasesreportin Overleaflabin screenshots in chat
00

Six products, and none of them talk.

Every one of these is good at its job. The problem is not any of them — it is that the thread between them only ever existed in your head, and you are going to need it in two years.

01

Library goes in.

Papers arrive with their metadata, annotations and tags — and stay attached to everything they touch.

02

Notes goes in.

A markdown vault with wikilinks, where an excerpt is a real object pointing back at page four of the PDF.

03

Plan goes in.

Milestones that carry dependencies and compute estimates, and know which note they came out of.

04

Experiments goes in.

Runs land in the same database as the paper they implement, pinned to the branch and commit that produced them.

05

Report goes in.

The outline is the project. Figures and citations are already resolved, so the LaTeX export needs no fixing.

06

Lab goes in.

Your collaborators open the object itself — the run, the section, the paper — scoped by the database.

07

One project.

One database, one graph, one export. Not six tools with integrations bolted between them — one workspace where the paper, the note, the run and the section are rows that know about each other.

Why it exists

Research is mostly reasoning you will not remember having done.

The writing is the last stretch. The thinking is everything before it — a term or a decade — and almost none of the tools involved were built to keep that part.

“Why did you rule that out?”

You had a good reason early on. It was a margin note in a PDF, or a message to yourself, or nowhere at all. Someone asks two years later — a supervisor, a reviewer, the version of you writing the paper.

excerpts and notes stay attached to the paper

“Which run produced that number?”

The figure is in your draft. The number is in the caption. The code that made it has been rewritten twice and you are no longer certain which commit it was.

runs are pinned to branch and commit

“Hasn’t someone already done this?”

You read it near the start. You remember the shape of the argument and not the title, and it is somewhere in four hundred PDFs.

typed relations and a searchable graph

“Send me an update.”

So you screenshot a chart, paste a paragraph, and describe the rest from memory — every fortnight, for as long as the project runs.

share the objects themselves

How it works · the through-line

A paper becomes a note. A note becomes a plan.

Every other research tool holds one link of that chain and loses the rest at its boundary. Here is one paper from a real project, all the way through.

papers

β-VAE: Learning Basic Visual Concepts with a Constrained Variational Framework

Higgins et al. · ICLR 2017

#vae#disentanglement#latent-variables+1
to read

vault

Disentanglement reading cluster

vault page · linked to β-VAE

#to-verify#disentanglement

“…a single hyperparameter β that balances latent channel capacity against reconstruction accuracy.”

Does β survive a structured prior? Locatello argues unsupervised disentanglement is impossible without inductive bias — a graph prior is exactly that bias. See [[Variational Graph Auto-Encoders]].

plan

  • Reproduce β-VAE baseline

    40 GPU-hours · finished 6d ago

    done
  • Graph-prior module

    blocked by: β-VAE baseline · 60 GPU-hours

    in progress
  • Disentanglement ablation

    from note · Disentanglement reading cluster

    not started

experiments

β-VAE sweep — seed 42

main @ a1b2c3d · implements β-VAE

val_loss
0.1826
recon_loss
0.0912
config
β=4 · lr=1e-3 · seed=42
done

report

3.2 Graph-prior module

0 / 2,400 words · 1 run · 1 figure

We extend the capacity-constrained objective of [[β-VAE]] with a graph prior over latent factors, reaching val_loss 0.1826 at β=4.

exports as
\cite{higgins2017betavae}
not started
01 · Paper

You read Higgins et al., 2017.

Imported from a DOI in one paste. Metadata, abstract and your Zotero annotations arrive with it, tagged and dropped into a reading list.

02 · Note

A highlight becomes something you can argue with.

The excerpt is an object, not text stranded in a PDF. You quote it in a vault note, disagree with it, and that note stays attached to the paper.

03 · Plan

The disagreement becomes a milestone.

Milestones carry dependencies and compute estimates, so the plan already knows this one cannot start until the baseline lands.

04 · Experiment

The milestone becomes a run that remembers its source.

One decorator in the training script. The run lands in the same database as the paper it implements, pinned to the branch and commit that produced it.

05 · Section

And the run becomes section 3.2.

The outline is the project. The figure and the citation are already resolved, so the LaTeX export does not need you to fix a single reference.

Literature

Every paper you have read, and how they hold together.

One library, one graph, and a reference manager that stays in sync instead of being replaced.

graph

Your Methodβ-VAEKingma 2014VGAEKipf 2017reading cluster#disentanglement#graph-priorFactorVAELocatello 20193.2 graph-priornew citation
Relationscitesextendscontradictssimilarbuilds onuses method
01

Import from anywhere, once.

A URL, an arXiv ID, a DOI, or your whole Zotero library. Metadata, abstract and annotations arrive together, tagged and dropped into nested reading lists.

02

Concepts bridge the clusters.

Tags are nodes in their own right, so the graph shows how a method you borrowed from one literature reaches the one you are writing in.

03

Relations are typed, not vibes.

cites, extends, contradicts, builds on, uses method. A contradiction you recorded once is still visible the week you write the related work.

04

And it tells you when the field moves.

Semantic Scholar watches what you track and flags new work citing it — including work that cites you.

Reading & annotations

The highlight is the object, not a stripe on a page.

A PDF reader inside the workspace, where every highlight carries its page locus, its use in your argument, and the section it is destined for.

reader · Vaswani et al., 2017 · arXiv:1706.03762

Fetching the paper from arXiv…

reader · higgins et al. · annotations

annotation types

  • highlight · underline · note

    text annotations, with colour and comment

  • image · ink · text

    figures, margin scrawl and typed boxes — Zotero’s full set

  • direct · paraphrase · summary

    how you intend to use it, decided while reading

report · pinned excerpts

2.1.2 Disentanglement literature

3 excerpts pinned · 0 / 700 words

“…balances latent channel capacity against reconstruction accuracy.”

from
Higgins et al. · p. 4
exports as
\cite{higgins2017betavae}
not started

zotero · write-back

  • Higgins et al. · 14 annotations

    imported from Zotero

    synced
  • Your highlight, p. 4

    made here · queued for Zotero

    pending
  • Edited on both sides

    surfaced, never silently overwritten

    conflict
01

Read the paper where you keep it.

The PDF opens in the workspace, beside the library and the graph. Your Zotero annotations are already there, and anything you highlight here is a first-class row rather than a scribble in a viewer’s private store.

02

Anchored so it survives the file.

Every annotation stores both the rectangles and a text locus. Re-download the PDF, get a different build of it, and the highlight still lands on the sentence it was about.

03

Say how you will use it, while you still know.

Direct quote, paraphrase, or summary — the Citavi taxonomy, chosen at reading time. At writing time that one field is the difference between citing it correctly and re-reading the paper.

04

Pin it to the section it belongs to.

An excerpt can be placed in a report section the moment you meet it, and it syncs to a vault note as well. When you write that section, the evidence is already sitting in it, with the citation resolved.

05

And it goes back to Zotero.

Write-back is tracked per annotation — local, synced, pending, conflict. Zotero stays the reference manager it already is for you; nothing is trapped here.

Experiments

Runs that know which paper they came from.

Tracking that lives beside the literature and the plan, instead of in a third place you reconcile later.

train.py

from weaveforge import track_experiment

@track_experiment(
    name="β-VAE sweep — seed 42",
    paper="higgins-2017-bvae",
    config={"beta": 4, "seed": 42},
)
def train(run):
    for epoch in range(50):
        run.log(epoch=epoch, val_loss=step())

experiments · git pin

β-VAE sweep — seed 42

Higher β improves disentanglement at cost of reconstruction

branch
main
commit
a1b2c3d4e5f6
config
β=4 · lr=1e-3 · batch=64
implements
higgins-2017-bvae
done

experiments · live

β-VAE sweep — seed 42running
val_loss
epoch
1 / 25
val_loss
0.9400
logged from
run.log(…)

experiments · compare

  • β-VAE sweep — seed 42

    val_loss 0.1826 · recon 0.0912

    done
  • ResNet-18 baseline

    val_loss 0.340 · accuracy 0.912

    done
  • Graph-prior ablation

    train_loss 0.520 · started today

    running

report · figures

fig. 4 Loss by epoch

from run β-VAE sweep — seed 42

exports with
figures/fig4.pdf
screenshot round trips
0
attached
01

One decorator, no new dashboard.

@track_experiment in your training script, and the run lands in the same database as the paper it implements. There is no separate tracking service to keep in sync.

02

Pinned to the commit that produced it.

Branch, commit hash and config travel with the run, so a number in your paper can always be traced back to code that actually existed.

03

Watch it while it runs.

run.log() streams metrics into the workspace, so the curve moves as the job does — in the same screen as the paper the run implements, not in a dashboard on a second monitor.

04

Compare sweeps without exporting anything.

Overlaid curves and a comparison table, beside the papers the runs came from. Lightning and Keras callbacks ship with it, and TensorBoard or W&B histories import rather than re-run.

05

The figure is already the paper’s figure.

Attach a run to a report section and its curve exports with the LaTeX — same numbers, no screenshot round trip.

Plan & writing

The outline is the project, not a document about it.

Sections carry status and word targets. When it is time to submit, the whole thing exports as LaTeX with the bibliography already resolved.

report · outline

  • 2.1.1 VAE variants

    520 / 900 words

    drafting
  • 2.1.2 Disentanglement literature

    0 / 700 words

    not started
  • 3.1 Encoder architecture

    0 / 2,200 words

    not started
  • 3.2 Graph-prior module

    0 / 2,400 words · 3 runs attached

    not started
01

Milestones that know what blocks them.

Dependencies and compute estimates live on the milestone, so the plan understands that the graph-prior module cannot start until the baseline lands.

02

Cite while you write.

Type [[ or @ and pick the paper. It resolves to a real citation on export, not a string you have to go back and fix.

03

Overleaf when you need it.

Export the outline as a LaTeX project with \cite{} keys, the .bib and your figures — or keep a linked Overleaf document in sync.

04

A logbook that is not a chore.

Dated markdown entries with hours and mood. It is the thing you will be grateful for when you write the methods up months after the fact.

Labs & supervision

Your group sees objects, not screenshots.

Collaboration is a permission on a row, not a second product bolted on the side.

people · vision-group

  • dr. m. haddad

    professor · invite code PROF-…

  • you

    PhD · 20 papers · 3 experiments

    owner
  • m. okonkwo

    Master’s · invite code MSC-…

shared · with dr. m. haddad

  • 3.2 Graph-prior module

    report section · can comment

    shared
  • β-VAE sweep — seed 42

    experiment · read only

    shared
  • “Good — but show the ablation before you write this up.”

    dr. m. haddad · 2d ago

postgres · row-level security

-- the access boundary is the database,
-- not a check inside a screen
create policy paper_read on papers
  for select using (
    user_id = auth.uid()
    or exists (select 1 from shares s
       where s.object_id = papers.id
         and s.grantee = auth.uid())
  );

standalone

No lab

Collaboration surface hidden

features withheld
0
external links
opt-in · can expire
end-to-end encrypted
no — at rest only
01

A lab in three codes.

A professor creates the lab and hands out three invite codes — professor, PhD, Master’s. Joining takes one paste. No IT ticket, no admin console to learn.

02

Share objects, not screenshots.

Share a paper, an experiment, a report section, or a whole type. Your labmate pins it into their own library, comments on it, and co-edits where you granted that.

03

Scoped by the database.

Postgres row-level security is the access boundary, not application code. Owner-or-shared is enforced where the data lives, so a bug in a screen cannot leak a row.

04

Or nobody at all.

Standalone is a first-class path: the entire product with the collaboration surface out of the way. Data is encrypted at rest but not end-to-end — the docs say so plainly.

Run it yourself

Clone it, run it, keep it.

Six commands from a fresh checkout to a running workspace on your own machine.

~/weaveforge

$ git clone https://github.com/Satwik-Miyyapuram/weaveforge.git
$ cd weaveforge
$ npm install
$ npm run build:core
$ npm run test:core     # 460+ domain tests, no network
$ npm run dev           # → http://localhost:3000
Next.js PWAPostgres + RLSPython SDKZoteroGitHub / GitLabOverleafSemantic ScholarMattermost
01

The copyleft is the point.

AGPL-3.0-only, and it stays that way. Anyone who takes it and hosts a better version has to publish their source, so the work flows back rather than away.

02

One hundred percent of the software.

No capability is ever hosted-only. Self-hosting is not a stripped tier — it is the same product with your name on the database.

03

Your Postgres, your data.

Supabase or a plain self-hosted Postgres. The schema lives in the repo as migrations, and both the web app and the Python SDK talk to it.

04

Built to be handed over.

A framework-agnostic core with repository contracts and shared test suites, so the domain logic is testable without a browser, a network or a database.

Start with one paper.

Create a project, import the last thing you read, and see where it goes. Nothing to migrate, nothing to configure, and the export is yours whenever you want it.

Side by side

Each of these is good at one link of the chain.

Nothing here is a bad tool — most of them are on this page because they are the best at what they do, and WeaveForge syncs with several rather than replacing them. The gap is that research is the whole chain, and the joins between tools are exactly where the reasoning falls out.

What research needsWeaveForgeZoteroObsidianNotionW&BOverleaf
Reference library & metadataimport by DOI, arXiv, URL or whole Zotero libraryyesyespartlynonopartly
PDF reading with durable annotationslocus anchors, quotation types, Zotero write-backyesyespartlynonono
Excerpts as objects you can argue withan excerpt links to its paper, its note and its sectionyespartlypartlynonono
Markdown vault with wikilinksnested pages, backlinks, imagesyesnoyespartlynono
Typed relations between paperscites, extends, contradicts, builds on, uses methodyesnonononono
One graph over papers, notes, tags and sectionsnot a graph of files — a graph of the workyesnopartlynonono
Plan with dependencies and compute estimatesmilestones that know what blocks themyesnopartlyyesnono
Experiment trackingone decorator, Lightning and Keras callbacksyesnononoyesno
Live metrics while a run is goingcurves stream in beside the paper the run implementsyesnononoyesno
Runs pinned to branch and commita number in a paper traces back to code that existedyesnononoyesno
Run → figure → section, without a screenshotthe figure exports with the LaTeXyesnonononopartly
LaTeX export with the bibliography resolvedoutline, .bib, figures, \cite{} keysyespartlypartlynonoyes
Collaboration: share objects, not screenshotspapers, runs and sections, scoped per personyespartlynoyespartlyyes
Access enforced by the databasePostgres row-level security, not a check in a screenyesnonononono
Self-hostable, all of itAGPL-3.0-only · no hosted-only capabilityyespartlypartlynopartlypartly

● covered◐ partly, or via a plugin○ not its job