LifeLab · nonlinear workspace

Summon — Direction C, refined

The quiet gutter affordance you liked, built out around the hard part: every block is summonable, so the page stays calm and the search does the work. No provenance chrome — a summoned block already carries its :tags:, so it just lands native. Keyboard-first throughout: an Emacs × TiddlyWiki hybrid, not a web app — every verb is a chord.

Calm at rest

No "+ include" line. A gutter + appears only under the cursor — the page reads as empty as your Home.

Two-stage scope

Search the small page namespace first, then drills into that page's headlines. page › headline keeps a huge set pickable.

Smart & constrained

Across everything: semantic + headline rank, recency and current-page proximity — a short list, not 1,000 rows.

Lands native

No "from Y" marker. The block keeps its tags; tags are the context. Nothing fences it off from your own captures.

1REVEAL & MODE

One line — add by default, Mod+K s to summon

Hover the empty line and the gutter wakes. It opens in add — type and it's a new block. Mod+K s flips the same line to summon (it's in the Mod+K family, so Tab stays free for tag-jump); the marker switches * so the mode is always visible. Alongside your Mod+K j and Mod+K x.

Home
*spiderman 2
:LOGBOOK:(2 entries, 3h 51m total)
ADD · the default
* call the dentist new block · Mod+K s → summon
Mod+K sflips add ⇄ summon · Tab stays for tag-jump
SUMMON · Mod+K s, or (( inline
dentist searching all blocks · Mod+K s → add
Entry points, no C-c, Tab untouched: type or on an empty line → add · Mod+K s toggles summon · mid-line (( escalates an add into an inline block reference, the same cite trigger used everywhere. Tab stays bound to tag-jump; the marker (* / ) always shows the mode. The line only exists under your cursor — no persistent “+ include.”
2SMART SEARCH · ALL BLOCKS

Type and the set collapses to a few

Free text searches every block — ranked by meaning, headline match, recency and proximity. Each row shows its :tags: (the context) and its page#headline address. Page hits offer to scope in.

Home
*spiderman 2
+
tone drills searching all blocks
by relevance 4 of 1,240 blocks
*
Mandarin — tone drills · language/mandarin
:study:drill:2d ago
summon ↵
*
third tone sandhi notes · language/mandarin
:study:grammar:last week
language/mandarin · page · 14 headlines
:language:
scope →
*
guitar — tone & gain settings · music/rig
:music:gear:May 3
↑↓move summon scope to page + create & cite
3SCOPED · page › headline

Pick a page, then its headlines

Hitting on a page turns it into a scope chip — now you're searching only that page's handful of headlines, not all 1,240 blocks. The two-stage resolve that makes a giant namespace feel small.

Home
*spiderman 2
+
language/mandarin × review 14 headlines in scope
headlines in language/mandarin 3 match "review"
*
weekly review log
:study:habit:yesterday
summon ↵
*
SRS review queue — HSK 4
:study:flashcards:2d ago
*
mistakes to review before exam
:study:Apr 30
clear scope summon ⌥↵jump + new headline here
4OUTCOME · lands native

It's just a block now

The summoned block drops into the stream identical to your own captures — same star, headline, logbook and its own :tags:. No "from" chip, no border, no fence. A brief tint on arrival is the only cue; then it's indistinguishable.

2026-06-20
*spiderman 2 :movies:rewatch:
:LOGBOOK:(2 entries, 3h 51m total)
*weekly review log :study:habit:
:LOGBOOK:(6 entries, 1h 12m total)

+ Click to add text…

Why no provenance chip: the block already carries :study:habit:. Its tags are its context and its home is one tap away on any tag — so a separate "from Y" marker would just be noise.
5INSERTION · where it lands

Below where you are, not at the bottom

Summon from inside the stream and the block drops in directly under the line you triggered from — next to the thought that called it — then scrolls just enough to reveal it. Appending to the end would scatter the context you were assembling.

Home
*spiderman 2
*Mandarin study :study:
:LOGBOOK:(19 entries, 4h 7m total) — summoned from here
↳ lands here
*weekly review log :study:habit: incoming
*groceries
below origin · default

Sits with the block that summoned it; surrounding flow is untouched.

append to end

Always at the bottom — separates the new block from its context.

6DEDUP · already in the river

Summon it twice, it doesn't double

If a block is already on the surface, summoning it again won't add a copy — the existing instance pulses and the view scrolls to it, and the search row reads already here ↑. The river is a set, not a log.

Home
*spiderman 2
*weekly review log :study:habit:
:LOGBOOK:(6 entries, 1h 12m total)
+
weekly review searching all blocks
by relevance 2 of 1,240 blocks
*
weekly review log · language/mandarin
already hereon this surface
jump ↑
*
monthly review — finances · money
:money:habit:Jun 1
jump to it next result + create & cite
7DISMISS · keyboard

C-c - takes it off the surface

Point on a summoned block and C-c - dismisses it — it leaves the view but never its home, and C-/ brings it back. No dialog, just the echo area. Delete is deliberately a different chord.

Home
*spiderman 2
*weekly review log :study:habit:
:LOGBOOK:(6 entries, 1h 12m total)
*Mandarin study
C-c — river verbs (which-key)
C-n / C-pnext / prev blockmove point through the river
C-c -dismiss-from-viewoff this surface; block & tags untouched
C-/undobring the last dismissed block back
C-c C-kdelete-blockdestroys it — prompts y/n (see →)
-:**-today.org(Org River) L7  ·  ⊟ summon  C-c ? keys
Dismissed “weekly review log” — still in language/mandarin.C-/ to undo · it never left its home
8DELETE · keyboard

C-c C-k asks before it destroys

On a native jot with no other home, dismissing would orphan it — so the same close instinct maps to delete-block, which stops for a y/n in the minibuffer. Provenance picks the verb; the destructive one is rare and visibly distinct.

Home
*spiderman 2 :movies:
*pick up dry cleaning
no tags · homed only on today · a throwaway jot
*Mandarin study
Why this one asks: it carries no tags and lives only here, so there is nowhere to dismiss it to — dismissing would break “every block stays reachable.” The minibuffer makes you confirm. A tagged or foreign block would have offered C-c - (dismiss) with no prompt instead.
-:**-today.org(Org River) L8  ·  delete-block  C-g abort
Delete block “pick up dry cleaning”? No other home — this destroys it.(y or n)
9UNDER THE HOOD

The search field is a block

A block is a single CodeMirror that renders its title and content differently. The summon line is that same widget with one extra completion source — the block index. So :tags:, [[pages]] and ((blocks)) aren't special cases; summon is one more. Structured tokens parse inline, exactly as in a title.

Home
BLOCK · one CodeMirror — title + content, rendered apart
*Mandarin study :study:
Reviewed tones today; third-tone sandhi still trips me up.
SUMMON · same widget, completion source = block index
:study: language/mandarin# review tokens parse inline
one instance · raw buffer: :study: language/mandarin#review
completion · block index 2 in scope
*
weekly review log
accept ↵
*
SRS review queue — HSK 4
Same instance, two outcomes: commit the line → it becomes a new block (add); accept a completion → summon that block. The picker is CodeMirror's own autocomplete pointed at the headline / embedding index — the machinery already behind :, [[ and ((. The scope chip in ·3 is literally a parsed page# token.
10OPTIMISTIC LOAD

Title now, body hydrates

Accept a completion and the block paints its title row instantly from the index hit — headline, tags and address are already in hand. The body shimmers while one round trip fetches it, then fills in. The search line is already gone; it only emitted the intent.

Home
*spiderman 2 :movies:
:LOGBOOK:(2 entries, 3h 51m total)
JUST SUMMONED · title from index, body in flight
*weekly review log :study:habit: ⟳ hydrating…
0 ms title painted from the index hit · ~120 ms body hydrates (often already prefetched on highlight)
The search instance stays stateless: apply() emits summon(id) and clears the line — the body fetch belongs to the new block, which owns its own loading state. A request token drops stale responses; a re-summon of an id already on the surface short-circuits to a pulse + scroll instead of inserting.