Individuals Teams ML Teams GitHub ↗

Everything you know and everything you have to do, in one place you control.

Nothing slips through the cracks, nothing leaks to a vendor, and your assistant actually remembers. A linked knowledge base, your mail and messaging, a task queue, and durable AI agents, running as one system so the joins stop living in your head.

$ pnpm start  ·  open http://127.0.0.1:4780
MIT Open source Read every line, fork it, self-host it. Host your graph yourself or let us host it so it syncs across your devices, and export any page as a plain file whenever you like. ★ View on GitHub
01 · one graph

Everything is a page

People, meetings, agent definitions, tasks: all outline pages in one graph, all linkable, all searchable. Record something once and it is connected to everything it touches.

02 · one triage

Everything is triaged

Mail, messages, reminders, and agent results flow through one triage engine you configure: what interrupts, what queues, what files silently. Decide once what "urgent" means.

03 · gated agents

Capable, but gated

Agents read your graph, draft replies, run analyses, and remember what they learn, but anything consequential waits for your approval, and every run is recorded and inspectable.

The tool for thought that also answers your email.

You have an outliner, an inbox, a calendar, a to-do app, a CRM you never update, and an AI subscription that forgets you between sessions. Subspace is what happens when those are one system. The demos are live.

The bullet is the primitive

Everything is a bullet, so everything composes

Every line on every page is a bullet, and the bullet is the unit of everything: a note, a table, a code cell, a running workflow, or a whole embedded app. Give it a custom glyph. Fold it to collapse a subtree and navigate a long page by its shape. Write a custom viewer so a workflow task renders as a live status card, not a line of text.

Why it matters: one mental model covers your notes, your data, and your apps. What you learn in the outliner works everywhere, because everywhere is the outliner.
Use it well: combine folds with tabs and panes. Fold a page down to its headings to move around it, then promote the bullet you are working in into its own pane beside it.
Live: fold a bullet, advance the workflow, promote one to a pane
workspace / Project X
⌘Ksynced
Project X · outline
Weekly goals for the Acme rollout
⇱ pane
pipeline rollup · custom viewer● live
$385k
weighted
3
open deals
1
at risk
⇱ pane
Open questions · 3
Which val slice do we promote first?
Do we need the addendum before the pilot?
Who owns the SOC2 evidence pack?
deploy-nightlyrunning
buildtestdeploysmokenotify
⇱ pane
mail · unreadthe full app, embedded inline
Rachel KimAcme, revised terms9:42
Priya Nairingest pipeline sync notesJul 9
⇱ pane
Fold to navigate. Promote any bullet to a pane or tab, and lay out your data and apps however you work.
bullet
Notes that compute

An outliner with a spreadsheet inside it

Pages are bullet outlines with links, backlinks, and tags, plus tables whose formulas reference numbers on other pages. The analysis lives next to the reasoning it supports.

Why it matters: your budget page reads the actual number from the planning page. Change one cell and every dependent view updates, live, sub-second.
Use it well: stop copying numbers between pages. Give a figure a label once and reference it everywhere. Stale copies are how personal dashboards die.
Live: click a cell in column  C  and change it
projects / Q3 planning
⌘Ksynced
Q3 planning
cash:: 812k · runway to March
Revenue plan · the pipeline table below feeds [[acme-account]]
▦ pipeline+ row · + col
A
B
C
account
stage
value
1
Acme
contract
240,000
2
Vertex
pilot
90,000
3
Northwind
lead
55,000
4
weighted total
=SUM(C1:C3)
Committed coverage 47.9% of [[Q3 planning]]:cash, recomputed on every edit.
Build your own

Custom pages, functions, and workflows are just pages

Write a TypeScript function on a page and call it from any bullet. Define your own page types and your own durable workflows. Agents, skills, and tools are all pages too, so the whole system is reshapeable without forking anything.

Why it matters: a live view of your own data, a recurring workflow, a domain page for the thing you actually track, all built in the graph and versioned with it.
Use it well: start from the slash menu. Your functions and agents sit right next to the built-ins, so a one-off script becomes a reusable command.
Live: pick a command from the slash menu
projects / Project X
⌘↵synced
/|
pipelineSummary(live rollup of the pipeline tablefn
runwayGauge(months of runway from cash + burnfn
prep-meeting(brief me before a callagent
weekly-reviewcustom workflow · runs every Fridayworkflow
Your comms, inside the graph

Special pages that are full apps

Mail and IM are not bolted-on integrations. They are pages in the graph that render as complete apps, so a thread files itself against the CRM, an agent can draft a reply grounded in your own notes, and everything an agent does passes through the same gates.

Connected and gated at once: the app is as capable as your email client, but it lives where the rest of your knowledge lives, and an agent cannot send on your behalf without your click.
Use it well: let a draft agent handle your most repetitive reply. It appears on the thread as a proposal you approve or dismiss.
Live: approve or dismiss the drafted reply
mail / Acme, revised terms
rsynced

Acme, revised terms

[[Rachel Kim]]rachel.kim@acme.test · thread of 3 · filed to CRM
Rachel Kim9:42
Can you confirm the SOC2 timeline before we counter-sign? Legal wants the audit window in writing.
mail-draft-reply · proposed reply grounded · 2 sources
Hi Rachel, our SOC2 Type II audit window closes March 14, report expected within three weeks. Happy to put the window in the MSA appendix so Legal has it in writing. Shall I send a redline?
[[Acme SOC2]][[Q3 planning]]
Automation you can read

Rules in plain language, with receipts

Mail rules are plain-language prompts, not sieve syntax, and each one shows how many messages it has caught. A rule can label, skip the inbox, and trigger an agent.

Use it well: the follow-up nudge is a favorite. It sends (gated), waits three days durably, checks for a reply, and only nudges if there has been silence.
Live: toggle "skip inbox" on a rule
mail / rules
synced
3 rules · edited on the Rules tab
invoicesmatched 47 e-mails
whenAnything that looks like an invoice or a payment receipt from a vendor
thenlabel · skip inbox · run agent: invoice-filer
newslettersmatched 213 e-mails
whenNewsletters, product updates, and marketing announcements
thenlabel · skip inbox
One triage for everything

Decide once what "urgent" means

Every event, mail, message, agent result, or reminder, flows through triage you configure once: what interrupts, what queues, what files silently. Only the level you mark critical pierces focus mode.

The alternative is what you have now: triaging the same noise over and over, all day, across a dozen notification streams.
Use it well: define "urgent" narrowly and in writing. Everything else queues, and you check it on your own schedule because you trust the wall.
Live: pick an event and watch it route
settings / triage
synced
Event triage
Incoming event:
silentfiles quietly to the page inbox, no interruption
normalinto the task queue for later
importanttask queue plus a notification
ultranotifies immediately, pierces focus mode
Deterministic rules run first (outage → ultra never waits on the classifier). Ultra delivery never blocks on a third-party API.
An assistant with memory and manners

It remembers day 3 on day 300, and asks before it acts

Press one key on any bullet and an agent takes it as an instruction, answering from your whole graph. It remembers what it learns, and that memory feeds every future run.

Anything consequential pauses. Sending mail, running a command: the run stops and waits, and every step is a record you can inspect, so you can always see exactly what it did.
Use it well: agents are pages you can read and edit. Narrow the tools, sharpen the prompt for one job, put it on a schedule.
Live: approve the gated step to let the run finish
agents / run ⌁
⌘↵synced
Draft a reply to Rachel about the SOC2 window and send it run ⌁
default-agent paused · awaiting approval
✻ llmplanned 3 steps
⚒ kb.search"Acme SOC2 timeline" · 2 hits
⚒ mail.proposeReplydrafted · ungated
⚒ mail.sendawaiting approval
mail.send → rachel.kim@acme.test "Re: revised terms"
Auditable by construction

"We use AI" versus "we can say exactly what the AI did"

Agent definitions are readable pages: prompt, allowed tools, approval policy, schedule. Review a change to an agent like a change to a document, with history. Every run is a step-by-step record anyone can inspect.

Consequential actions are gated, and an approved send happens exactly once. A crash mid-call refuses the silent re-run, so your agent will not double-email a customer.
Use it well: start agents in propose-only mode. As trust builds, auto-approve the routine and keep interrupting the consequential. The gates are per action.
Live: deny or approve; the audit line is permanent either way
agents / invoice-filer
⌘Ksynced
invoice-filer paused · 1 approval
⚒ kb.appendfiled to [[Vendors/Northwind]] · ungated
mail.send → billing@northwind.test "Invoice received"
Attention you can enforce

Mail, chat, and feeds open on your terms

The failure mode you know: check "real quick", lose forty minutes. Subspace enforces the rules you set. Mail and IM open once every couple of hours; social feeds lock after a quota. Enforcement is central, so reloading the page or switching devices does not help.

Truly urgent still gets through as a triaged notification, which is exactly what makes it safe to keep the rest closed.
Use it well: genuinely need in? An override asks what you need and reminds you it is your third this week. Friction, not a wall.
Live: the countdown ticks
/ mail
synced
frequency rule · once every 2h
MAIL OPENS IN
1:47:12
"The ability to concentrate and to use your time well is everything if you want to succeed."
attributed to Lee Iacocca
I actually need access
Remember what is worth revisiting

Spaced repetition, for knowledge and for ideas

Flag a page or a directory as remember this and Subspace derives flashcards and schedules them. It is not only for facts. It resurfaces the ideas you meant to come back to: a business idea, a scientific approach, a design you shelved.

Why it matters: a good idea you had eight months ago is worthless if it never resurfaces. The review deck brings it back at the moment you might act on it.
Use it well: the not-now screen offers your due cards instead of a locked feed, so an enforced pause becomes time spent with your own best thinking.
Live: click the card to reveal, then grade it
/ flashcards
synced
Review queue1 / 3 due
idea to revisit
Local-first RAG as a paid plugin: who would buy it, and what is the smallest version?
From [[ideas/rag-plugin]], shelved in Q1. Revisit trigger: now that ingestion ships, the smallest version is a /rag command over one project. Worth a spike.
click to reveal
Everywhere you work

A desktop app, a phone in your pocket, capture without deciding

A native desktop app with tabs, split panes, and a global capture hotkey. A phone app with offline capture, voice notes, and on-device meeting recording that transcribes onto a page. A browser extension that saves any article as clean text.

Use it well: capture without filing. The inbox's whole point is that sorting is a five-minute review later, on your schedule, not a decision in the moment.
Live: switch the desktop tabs; try Capture and Record on the phone
Project X mail terminal
Project X · outline
Architecture [[fs.path]]
Ingest pipeline sync notes
Open questions · 3 collapsed
terminal · ~/segnet
# split-pane terminal, rooted at the repo
segnet $ git status
On branch main · nothing to commit
segnet $ claude "add the eval slice"
subspace · mobile
Quick capture
follow up on the SOC2 redline #acme |
#acmeinbox#Q3#[[Project X]]
Routes to the [[acme]] page inbox. Offline? It queues and flushes when you reconnect.
Meeting
recording · you and the room on separate channels
meCan we get the audit window in the appendix?
themYes, March 14, I will send a redline today.
Plain files, all the way down

Your whole graph is a folder of Markdown

Subspace continuously mirrors every page to Markdown on disk (OKF sync). Point Claude Code, a script, or a teammate's editor at the folder and let it work. Edits on disk merge back into the graph three-way, per bullet, so your in-app work and an external agent's changes both survive.

Why it matters: you can put other agents to work on the same knowledge base, with no lock-in format and no API to wire up. The file is the contract, and git is your history.
Use it well: run a coding agent in a terminal rooted at the mirror. It edits Markdown; Subspace folds the changes back node by node while you keep working in the app.
Live: run an external agent on the file mirror
files / ~/Subspace/okf
synced
# the whole graph, mirrored as Markdown on disk
okf $ ls
projects/ crm/ agents/ research-wiki/
okf $ claude "add a risks section to Project X"

Everything above, per person, plus a graph you share.

A team workspace is one graph with two parts: a private part that is yours alone (your inbox, your captures, your drafts) and a shared part the team works in together. So every person gets all the For Individuals benefits, and on top of that the record becomes collective: it accretes as a side effect of the work instead of rotting in a wiki nobody updates.

One graph, two parts

Private where it should be, shared where it counts

Your inbox and your half-formed notes stay yours. The account pages, the decisions, the meeting record live in the shared graph, linkable from both. Nobody has to choose between a personal tool and a team tool.

Why it matters: the same link that sits in your private daily note points at the shared account page, so your work and the team's record are one graph, not two copies drifting apart.
Shared and private, side by side in one graph
workspace / acme
⌘Ksynced
◆ shared · whole team
[[Acme Corp]] account
[[Rachel Kim]] · VP Eng
Meeting, Jul 09 · summary
Decision: SOC2 window in appendix
pipeline · weighted total
● private · only you
daily note, Jul 10
links → [[Acme Corp]]
your inbox · 2 captures
draft: reply to Rachel
🔒 not visible to the team
One search, one set of links. Sharing is per-directory, with access controls; the private half never leaves your view.
A client record nobody keeps

Every sender and attendee becomes a shared page

People and companies build themselves from the team's mail and calendar: company, history, decisions, remembered facts. When someone leaves, the context is on the page, not in their inbox. When someone joins, "read the account pages" is the onboarding.

Duplicates are never silently merged. A near-match becomes a confirm-or-dismiss card, so a human decides whether two records are the same person.
Use it well: link decisions to the account page as they happen. "What did we agree with Acme in March" becomes a search, not an archaeology project.
Live: resolve the merge proposal
crm / Rachel Kim
⌘Ksynced
Rachel Kim
RK
Acme Corp ↗rachel.kim@acme.testVP Eng
email history open in mail ↗
↓inAcme, revised termsCan you confirm the SOC2 timeline9:42
↑outRe: pilot scopeSounds good, I will send the redlineJul 6
Needs confirmation
Possible duplicate: merge Rachel Kim and R. Kim (acme.test)?

Both resolve to the same normalized name and the acme.test domain. Confirm merges nodes, joins aliases, and re-points backlinks in one commit. Dismiss keeps both.

See the work as a board

The same tasks, as a Kanban board

The task queue and any project page render as a board: columns are status, cards are tasks or child pages. It is a view over the same graph as the outline, so moving a card is a real, audited command, not a separate tool to keep in sync.

Why it matters: the team gets the board they expect without a second source of truth. Outline, board, and graph are three views of one page.
Use it well: scope the board to a project and it becomes the standup. Everything already links back to the accounts and decisions it came from.
Live: click a card to move it to the next column
projects / Onboard Acme
⌘Ksynced
Backlog2
Draft data-processing addendum
PN legal
Provision sandbox tenant
JM infra
In progress1
SOC2 evidence pack
RK due Fri
Review1
MSA appendix: audit window
PN from [[Rachel Kim]]
Done1
Pilot scope agreed
JM
Columns map to the queue's sections; the move is one audited command, reversible from the Done log.
Meetings become the record

Where decisions get made, and usually evaporate

Reviews and standups are where decisions actually get made. Recorded meetings become transcript and summary pages, linked from the calendar event and from every attendee. The decision reached out loud becomes a durable, linked note the whole team can find.

Use it well: add your follow-ups as bullets under the summary and they are already linked to the people and the project they belong to.
A meeting page, written as you talk
meetings / Acme, ingest pipeline sync
⌘Ksynced
Meeting, Acme ingest pipeline sync
recording · you and the room on separate channels
Attendees: [[Rachel Kim]] [[Priya Nair]]
Transcript
meCan we get the audit window in the appendix?
themYes, March 14. I will send a redline today.
On Stop, a summary is written at the top of the page and linked from each attendee's CRM page.

The operating system for your research loop.

Ask how your team answers these today:

  • "Didn't we try a boundary-aware loss last spring?" The answer lives in a departed engineer's head or a run named exp_final_v3_fixed.
  • "Why is this run in the queue?" The hypothesis it tests was never written down, so the result gets interpreted loosely, or not at all.
  • "What should the new hire read?" The real state of the program is tribal, so onboarding takes months.

These are memory, attention, and orchestration problems, not modeling problems. Everything on the Teams tab applies; the research layer sits on top. And because it is built on the plugin system, these loops are yours to configure, not a fixed product you have to accept.

The research graph · goal dashboard

Your whole research loop on one screen

Goals, then hypotheses, then runs, then observations, then concepts, with a machine-maintained profile (the current recipe derived from your real run configs). From any goal you can walk to every hypothesis raised against it, every run that tested one, and every paper that fed it. That graph is institutional memory, and it builds itself as a side effect of working.

Live: switch views, resolve a "Needs you" item
goals / segmentation-iou-val-v3
⌘Ksynced
Segmentation IoU ≥ 0.82 on val-v3 on track · 0.009 to target
repo acme-vision/segnet · tracker W&B · launcher local-runs · A100×6 · budget 20 runs/wk · owner Priya N.
Best IoU
0.811
▲ +0.015 vs baseline
Open hypotheses
4 / 6 lifetime
1 supported · 2 testing
Runs this week
11 / 20
3 today · 9 GPU-hrs left
GPU capacity
2 / 6 free
4 A100 in use
Needs your review
1
blind read overdue
IoU on val-v3 · best-so-far by week
baseline 0.796 → now 0.811 · target 0.820
0.820 target
Hypothesesproposed → accepted → testing → resolved
2
proposed
1
accepted
2
testing
1
supported
1
refuted
H-07
Small-object precision is low because crop augmentation discards them
▲ 2 support1 neutral
testing
H-09
Boundary-aware loss lifts IoU on thin structures
▲ 1 support▼ 1 contra· mixed
testing
H-11
Class-balanced sampling fixes rare-class recall
queued · 4×A100 · waiting on capacity
accepted
Recent runsevery run linked to the hypothesis it tests
RunHypothesisIoUΔWhenReading
segnet-2451H-09 boundary-loss v20.804+0.0082hsupports
segnet-2449H-07 keep-small-crops0.811+0.0156hyour read
segnet-2447H-09 boundary-loss v10.792−0.0041dneutral
segnet-2440H-04 mixup0.781−0.0155drefutes
Needs you4 gated
Interpret segnet-2449 · blind
your reading before the AI's · +0.015 IoU
Dispatch coding task: boundary-loss v2 cleanup
→ coding agent on segnet · returns a PR
2 new hypotheses proposed
from the 2h heartbeat · accept to add to pool
Launch run: H-11 class-balanced
4×A100 · budget 11/20 ✓ · waiting capacity
Backlog & capacityA100×6
Cluster · 4 in use, 2 free
runrunrunrunfreefree
1H-11 class-balanced sampling4×A100
2H-07 keep-small-crops v2 · from PR #2182×A100
Literatureuntrusted · proposal-only
Boundary-Aware Feature Propagation for Semantic Segmentation
arXiv:2506.14822 · → H-09 · 2h
Scale-Adaptive Crop Sampling for Dense Prediction
arXiv:2505.09117 · → H-07 · 1d
Orchestrator · last heartbeat 2h ago · next in ~4h · proposed 3 items this cycle, 0 executed without approval. Full chain goal → hypothesis → task → PR → run → observation stays inspectable.
Loop 1 · every run gets read

Your interpretation goes first, blind

When a run finishes, an AI analyst reads it against your open hypotheses and drafts observations. Then, deliberately, the AI's reading stays hidden until you commit your own. The merged interpretation is what enters the record.

Why it matters: a plausible AI take that arrives first anchors everyone who reads it. This protocol keeps your team's judgment trained and primary, while guaranteeing every run gets interpreted the same day, not just the exciting ones.
Live: write a line, then commit to reveal the AI draft
runs / segnet-2449
⌘Ksynced
segnet-2449 finished
testing [[H-07 keep-small-crops]] · goal segmentation-iou-val-v3
IoU · val-v3
0.811
▲ +0.015
Small-object AP
0.63
▲ +0.08
Boundary F1
0.71
▲ +0.01
Val loss
0.142
▼ −0.006
✍︎ Your reading, before the AI'sAI draft hidden · 2 observations

You can see the metrics above. Write what you think this run shows for H-07, then reveal and merge the analyst's draft.

merged interpretation enters the record on both names
🔒 analyst draft · unlocks after you commit
Run strongly supports H-07: small-object AP rises 0.08 while overall IoU gains 0.015, and the confusion matrix shows recovered recall on the three smallest size buckets. Recommend promoting keep-small-crops to the default augmentation.
Merged observation filed → your read (win concentrated in small dense objects, not thin structures) plus the analyst's (recovered recall on the smallest buckets). Next step queued: slice val-v3 by object size before promoting.
Loop 2 · a research heartbeat

It proposes; you dispose

On your schedule, per goal, an orchestrator reads everything new, observations, hypothesis status, ingested papers, meeting decisions, and proposes: new hypotheses, coding tasks that come back as PRs, and runs queued with their hypothesis attached.

Every proposal arrives with its evidence linked, so approving is an informed decision, not a rubber stamp. Nothing executes without one, and a hard budget check is enforced in code.
Use it well: autonomy is opt-in per gate. As trust builds, auto-approve the routine and keep interrupting the consequential.
Live: accept, dispatch, or deny each card
task-queue / segmentation-iou-val-v3
⌘Ksynced
Task queue 3 proposals from the 14:20 heartbeat
new hypothesisRare-class recall is capped by label noise, not sampling

Three runs varying class weights (2451, 2447, 2438) moved rare-class recall < 0.01 despite 3× reweighting, a ceiling more consistent with noisy labels than sampling. Enters as a draft.

coding taskImplement boundary-aware loss v2 (edge-weight normalization)

segnet-2447 underperformed because edge weights were not normalized per-image; arXiv:2506.14822 §3.2 gives the correction. Dispatches a coding agent on segnet and returns a PR.

launch runQueue H-11 class-balanced sampling · 4×A100

From approved PR #221. Tests H-11 against the current best (segnet-2449, 0.811). Est. 5h wall-clock.

✓ budget 11/20 · hard cap in code
Autonomy is opt-in per gate: auto-approve the routine, keep interrupting the consequential.
Make the loop your own

Your process, not our opinion of it

The page types, the loops, the gates, the connectors are plugins on open contracts. Prefer a two-stage review? A different budget rule? A launcher we have not built? Reshape it, or write your own, without forking the app.

Why it matters: every ML team's process is a little different. A fixed product forces yours to match it. Here the orchestration is the product, and it is yours to bend.
The loop, defined as a plugin you can edit
plugins / autoresearch
⌘Ksynced
heartbeat workflow editable
schedule every 2h, per goal · change the cadence on one line
gate launch-run · swap the budget rule for your own
review protocol blind-first · or add a second reviewer
Installed on your data volume, versioned with the graph, upgraded without a redeploy.
Where this is going

A graph of your own, connected to everyone else's

Every person and every team runs their own graph. The future is federation: mount parts of another graph you have access to, your employer's, a tool you use that hosts one, and reason across them as if they were yours. Talk to another graph's tools over MCP, and expose your own, with access controls and approvals on every boundary.

mounted · read mounted · read mcp · gated + approved your graph notes · comms · agents employer shared docs · runbooks a tool hosts its own graph another agent calls your MCP tools
mounted graph (read, scoped) MCP call (gated, approved) a tool that hosts a graph

Mount, don't copy

Bring parts of another graph into your view with scoped, read access. Your employer's runbooks and a tool's data sit next to your own notes, linkable and searchable, without a sync job or a second copy to drift.

Talk to other graphs

Every graph can expose tools over MCP. Your agents call another graph's tools, and it calls yours, so automation spans organizations without anyone shipping a bespoke integration.

Controls on every boundary

You decide what you expose, to whom, and what needs approval before it runs. The same gates that protect a single run protect a shared one: read is scoped, writes are approved, everything is logged.