blog/lifelab/history
era-timeline
The LifeLab timeline - 2,053 Commits in 137 Days

I wanted to summarize the experience of building lifelab from scratch. I asked claude to put a story-arc based on my (it's) git history. I thought it's interesting to put the commits on a timeline and find distinct patterns (eras) of development. It actually weaved a fun story. Since Claude actually writes proper commit messages and PR you can backtrace the entire system and most decisions. I definitely wish I had the discipline to do that manually and I wonder how many production systems do.

[slop disclaimer]

The content after block this is fully claude generated. I am not sure about the etiquette of exposing readers to slop so I decided to put a warning . I left some human comments, but I was entertained by what claude wrote enough to share it without major editing. Maybe the quality went up compared to my human writing?

Outline

LifeLab's git history reads like a speedrun of software philosophy. It starts as a clone ("what if Deepnote but mine?"), immediately rebels against its parent ("not notebooks — pages"), discovers its spiritual ancestor ("org-mode had it right"), goes through an infrastructure gauntlet ("Docker on Hetzner, fight me"), tries four different scripting runtimes before settling on one, builds its own extensibility model from scratch, and ends up as something genuinely novel — a malleable, org-mode-inspired personal knowledge OS that runs as a desktop app, PWA, or self-hosted server, with AI woven into the fabric.

The claude/ branch prefixes tell their own story: this was built through relentless human-AI pair programming, with the human driving the vision and the AI executing at a pace that produced 15 commits a day for over four months straight.

Era 0 - The Spark (Nov 5, 2025) — 1 day

The first commit: Add notebook-app package

The repo starts as a fork/clone of Deepnote — a computational notebook platform. The very first PR is already from claude/ — AI-assisted from day zero. Within hours, it's already being pulled apart: cell buttons move, the Deepnote Toolkit gets integrated, then immediately reverted and removed. The codebase is being interrogated: what are you, and what should you become?

Human note

I saw deepnote being open sourced on hackernews and instantly thought I can reuse it for note taking. I have been working on a jupyterlab-task-management solution but the interface was ugly, and deepnote was pretty. I quickly realized not all parts were shared and the parts I wanted were proprietary.

:PROPERTIES:(14 fields)
:avg_per_day :17
:color :#6366f1
:daily_counts :[object]
:duration_days:1
:end :2025-11-05
:merged_prs :7
:name :The Spark
:number :0
:peak_count :17
:peak_day :2025-11-05
:start :2025-11-05
:subtitle :First commit. Fork of Deepnote.
:total_commits:17
:wrong_turns :
:END:
:ERA:Era 0: The Spark
First commit. Fork of Deepnote.
17commits
7PRs
1day
17/day avg
17peak (Nov 5)
Nov 5
Nov 5 → Nov 5
:END:
Era 1 "Meta-Programmable Notebook" (Nov 5–7, 2025) — ~100 commits in 3 days

Key commit: Refactor: Convert to standalone meta-programmable notebook app

This is the fever-dream opening. 100 commits on November 6 alone. The project explores:

  • Malleability system — hooks, self-documentation, "the blocks should modify themselves"
  • Schema blocks — JSON editors for structured data
  • CSS variables unification — full theming system
  • WebSocket race conditions — the inevitable async debugging
  • A Rust backend investigation alongside the Python one (Axum + DashMap)
  • A ratatui TUI (terminal interface!) gets built in parallel
  • Vim-style command mode with autocomplete in the TUI
  • The commit messages capture the energy: yeeeee, push all, run. Someone is building very fast and seeing what sticks.

Human note

The first system was a crystalization from blog/pkm/PKM concept exploration]. I had an idea of everything being a block, including code blocks that can query the database. The most unique thing is I went with rust for rest backend instead of python fastapi. I was familiar with fastapi, so I could fix it myself. I decided I don't want to fix things myself. Rust Axum ended up being fantastic, it was performant, snappy and once claude got the code to compile it was basically bug free

:PROPERTIES:(14 fields)
:avg_per_day :49
:color :#8b5cf6
:daily_counts :[object]
:duration_days:3
:end :2025-11-07
:merged_prs :22
:name :Meta-Programmable Notebook
:number :1
:peak_count :100
:peak_day :2025-11-06
:start :2025-11-05
:subtitle :100 commits on Nov 6. Malleability system, Rust backend, TUI, vim mode.
:total_commits:147
:wrong_turns :Deepnote Toolkit integrated then removed same day
:END:
:ERA:Era 1: Meta-Programmable Notebook
100 commits on Nov 6. Malleability system, Rust backend, TUI, vim mode.
147commits
22PRs
3days
49/day avg
100peak (Nov 6)
Nov 5Nov 7
Nov 5 → Nov 7
⚠ Wrong turns:
• Deepnote Toolkit integrated then removed same day
:END:
Era 2 The Identity Crisis → "Pages, Not Notebooks" (Nov 7–9, 2025) — PRs #20–33

Key commit: Refactor: Rename notebooks to pages throughout codebase

A philosophical pivot: the atomic unit isn't a "notebook" — it's a page. Notebooks are linear; pages are a graph. This era introduces:

  • Hierarchical page titles (folders removed — just use / in names)
  • Tags as links between concepts
  • Fractional indexing for block reordering
  • pgvector embedding storage for semantic search
  • Fulltext search with configurable filters
  • Task blocks with dedicated UI
  • The naming is still "Deepnote" in the repo URL, but the soul has changed.

Human note

I hate folders and wanted to enforce purity. I messed up by naming tags "links" just to be unique, no one including me could get it.

:PROPERTIES:(14 fields)
:avg_per_day :29
:color :#a78bfa
:daily_counts :[object]
:duration_days:3
:end :2025-11-09
:merged_prs :15
:name :Pages, Not Notebooks
:number :2
:peak_count :34
:peak_day :2025-11-09
:start :2025-11-07
:subtitle :Notebooks become pages. Tags, search, fractional indexing, tasks.
:total_commits:87
:wrong_turns :Folders concept tried then abandoned for hierarchical titles
:END:
:ERA:Era 2: Pages, Not Notebooks
Notebooks become pages. Tags, search, fractional indexing, tasks.
87commits
15PRs
3days
29/day avg
34peak (Nov 9)
Nov 7Nov 9
Nov 7 → Nov 9
⚠ Wrong turns:
• Folders concept tried then abandoned for hierarchical titles
:END:
Era 3 The Rebrand — LifeLab is Born (Nov 10, 2025) — PR #41

Key commit : Complete rebrand from Deepnote to LifeLab

The project gets its real name. This isn't just cosmetic — it marks the shift from "a notebook tool I'm hacking on" to "a personal knowledge operating system." The features that follow confirm the ambition:

  • Pinned blocks and wiki-style auto-page-creation
  • Publishing infrastructure — static HTML blog export
  • Task management with due dates, collapsible descriptions, metadata panels
  • Image upload with drag-and-drop

Human note

5 days since starting it, it become a fairly usable wiki web app. The name was stupid but it stuck.

:PROPERTIES:(14 fields)
:avg_per_day :21.2
:color :#ec4899
:daily_counts :[object]
:duration_days:5
:end :2025-11-13
:merged_prs :23
:name :LifeLab is Born
:number :3
:peak_count :34
:peak_day :2025-11-09
:start :2025-11-09
:subtitle :Rebrand from Deepnote. Pinned blocks, wiki-style pages, publishing.
:total_commits:106
:wrong_turns :pgvector embeddings added (removed 3 months later)
:END:
:ERA:Era 3: LifeLab is Born
Rebrand from Deepnote. Pinned blocks, wiki-style pages, publishing.
106commits
23PRs
5days
21.2/day avg
34peak (Nov 9)
Nov 9Nov 13
Nov 9 → Nov 13
⚠ Wrong turns:
• pgvector embeddings added (removed 3 months later)
:END:
Era 4 — Ship It — Docker, PWA, Mobile (Nov 14–30, 2025) — ~400 commits

Key commits: Add complete Docker deployment setup for Hetzner with Watchtower CD, Re-implement PWA features with service worker and offline support

The build-it-and-they-will-come phase. Massive infrastructure work:

  • Docker deployment on Hetzner with Watchtower continuous delivery
  • PWA with iOS support, service worker, offline IndexedDB
  • Telegram bot for mobile ingestion ("send a thought from your phone")
  • Mobile-responsive UI with hamburger menu
  • Calendar sidebar replacing the journal list
  • Passkey authentication (WebAuthn) — no passwords

This era has the most Docker debugging commits you'll ever see. GLIBC mismatches, nginx regex bugs, kernel bridge paths. The classic "it works on my machine" gauntlet.

Human note

I can't believe I did all of this in two weeks this was insane. Claude code quota was very generous and I basically worked on this every night after work.

:PROPERTIES:(14 fields)
:avg_per_day :42.8
:color :#f97316
:daily_counts :[object]
:duration_days:17
:end :2025-11-30
:merged_prs :222
:name :Ship It
:number :4
:peak_count :86
:peak_day :2025-11-25
:start :2025-11-14
:subtitle :Docker on Hetzner, PWA, Telegram bot, mobile UI, passkey auth.
:total_commits:727
:wrong_turns :PWA built, reverted, rebuilt from scratch, Auto-tag journal dates reverted 3x, MCP hallucinated API methods
:END:
:ERA:Era 4: Ship It
Docker on Hetzner, PWA, Telegram bot, mobile UI, passkey auth.
727commits
222PRs
17days
42.8/day avg
86peak (Nov 25)
Nov 14Nov 30
Nov 14 → Nov 30
⚠ Wrong turns:
• PWA built, reverted, rebuilt from scratch
• Auto-tag journal dates reverted 3x
• MCP hallucinated API methods
:END:
Era 5 — The Org-Mode Awakening (Dec 2025 – Jan 2026) — ~170 commits

Key commits: Add smart title bar with org-mode inspired syntax, Implement single timer mode (org-mode style), Add TODO/DONE keyword-based tasks (org-mode style)

A design revelation: Emacs org-mode had figured out personal knowledge management decades ago. LifeLab starts absorbing its ideas wholesale:

  • Smart title bar with org-mode headline syntax
  • Property drawers — collapsible metadata panels
  • TODO/DONE keywords for task management
  • Tag syntax with : trigger (:project:urgent:)
  • Logbook for time tracking (clock in/out)
  • Org-mode export format
  • Collapsible headlines with fold indicators

The CSS restyling commits (Restyle metadata and logbook as org-mode property drawers) show the UI being pulled toward org-mode's information density.

Human note

What started as "jupyter but with tasks" slowly became "org mode, but without the yucky Emacs" I really liked the information density of org mode styling blog/pkm/Beauty of orgmode syntax] and started leaning into it more. I initially left both jupyter styling and orgmode styling as an option. This is when I used lifelab every day.

:PROPERTIES:(14 fields)
:avg_per_day :8.6
:color :#22c55e
:daily_counts :[object]
:duration_days:57
:end :2026-01-26
:merged_prs :152
:name :Org-Mode Awakening
:number :5
:peak_count :40
:peak_day :2025-12-01
:start :2025-12-01
:subtitle :Headlines, property drawers, TODO/DONE, logbook, org-mode export.
:total_commits:493
:wrong_turns :Rhai scripting tried then removed, Ratatui TUI removed
:END:
:ERA:Era 5: Org-Mode Awakening
Headlines, property drawers, TODO/DONE, logbook, org-mode export.
493commits
152PRs
57days
8.6/day avg
40peak (Dec 1)
Dec 1Jan 26
Dec 1 → Jan 26
⚠ Wrong turns:
• Rhai scripting tried then removed
• Ratatui TUI removed
:END:
Era 6 — The Tauri Desktop App (Jan 27 – Feb 2026) — Major architectural fork

Key commit: feat: add Tauri desktop app scaffolding and backend mode toggle

LifeLab goes native. A Tauri (Rust + WebView) desktop app gets scaffolded with:

  • Native SQLite repository (rusqlite, not sqlx)
  • FTS5 search for local full-text search
  • Sync JavaScript runtime via rquickjs embedded in Rust
  • Hooks and slash commands ported to Tauri mode
  • GitHub Actions CI for building desktop binaries on release
  • Bundled tutorials seeded on first run

The repository pattern (from CLAUDE.md) makes sense now — the frontend needs to work against REST or Tauri or PWA/IndexedDB backends interchangeably.

Human note

Multibackend era, where there are 3 implementations of database with 1 frontend

:PROPERTIES:(14 fields)
:avg_per_day :16.2
:color :#06b6d4
:daily_counts :[object]
:duration_days:13
:end :2026-02-08
:merged_prs :57
:name :Tauri Desktop
:number :6
:peak_count :39
:peak_day :2026-01-30
:start :2026-01-27
:subtitle :Native desktop app. SQLite, FTS5, rquickjs runtime, CI builds.
:total_commits:210
:wrong_turns :QuickJS/rquickjs JS runtime (removed weeks later), Config blocks leaked to UI, reverted to localStorage
:END:
:ERA:Era 6: Tauri Desktop
Native desktop app. SQLite, FTS5, rquickjs runtime, CI builds.
210commits
57PRs
13days
16.2/day avg
39peak (Jan 30)
Jan 27Feb 8
Jan 27 → Feb 8
⚠ Wrong turns:
• QuickJS/rquickjs JS runtime (removed weeks later)
• Config blocks leaked to UI, reverted to localStorage
:END:
Era 7 — The Scripting Language Saga (Feb – Mar 2026)

The runtime roulette: Python (Jupyter) → Rhai → JavaScript (QuickJS/rquickjs) → Lua

This is the most fascinating thread in the entire history:

  • Python/Jupyter was the original runtime — full notebook execution
  • Rhai (Rust scripting language) was tried, got syntax highlighting, then was removed entirely (PR #552)
  • JavaScript via QuickJS was embedded in Rust via rquickjs — then also removed (PR #553: "Remove JavaScript runtime support, keep Python-only")
  • Lua arrived and stuck — the nb.* API was ported, tutorials rewritten, all JS references replaced with Lua (PR #736)

The final commit in this saga: Remove jupyter view mode, commit fully to org mode (#772) — the Jupyter notebook heritage is finally, fully shed.

Human note

Claude says it is interesting but this was the most slop heavy time. I did not find a proper way for users to extend lifelab using existing code. I wanted to be hipster by adding rhai (basically scriptable rust), but lua ended up faster. Embedding quickJS and nodeJS was a complete disaster. I thought it would be easy since I have to ship javascript anyway, but serverside executed javascript was async and basically broke everything constantly.

:PROPERTIES:(14 fields)
:avg_per_day :8.7
:color :#eab308
:daily_counts :[object]
:duration_days:20
:end :2026-02-28
:merged_prs :28
:name :Scripting Language Saga
:number :7
:peak_count :25
:peak_day :2026-02-15
:start :2026-02-09
:subtitle :Python -> Rhai -> JS -> Lua. Four runtimes tried. Lua wins.
:total_commits:174
:wrong_turns :Rhai removed (PR #552), JavaScript removed (PR #553), EXIF stripping broke date routing, HybridEditor removed then un-reverted
:END:
:ERA:Era 7: Scripting Language Saga
Python -> Rhai -> JS -> Lua. Four runtimes tried. Lua wins.
174commits
28PRs
20days
8.7/day avg
25peak (Feb 15)
Feb 9Feb 28
Feb 9 → Feb 28
⚠ Wrong turns:
• Rhai removed (PR #552)
• JavaScript removed (PR #553)
• EXIF stripping broke date routing
• HybridEditor removed then un-reverted
:END:
Era 8 — Malleable Software — The Drawer System (Mar 2026)
Era 8 — Malleable Software — The Drawer System (Mar 2026)

Key commits: Migrate logbook to system renderer with metadata-driven architecture, Add Tag Behavior editor with explicit renderer binding

The extensibility model crystallizes. Instead of hardcoded block types, LifeLab introduces:

  • System renderers — installable/uninstallable UI components
  • Drawer system — opt-in metadata panels that can be added to any block via tags
  • CSS theme renderer — themes as installable drawer-blocks
  • AI-assisted renderer authoring — Claude helps write JSX drawer components
  • Tag Behavior editor — bind renderers to tags declaratively

This is the "malleable software" vision fully realized — the app can modify its own UI.

Human note

I tried decomposing the app into modules that can be reused an remixed.

:PROPERTIES:(14 fields)
:avg_per_day :10.9
:color :#ef4444
:daily_counts :[object]
:duration_days:14
:end :2026-03-14
:merged_prs :0
:name :Malleable Software
:number :8
:peak_count :32
:peak_day :2026-03-07
:start :2026-03-01
:subtitle :Drawer/renderer system. Installable UI. The app becomes its own extension system.
:total_commits:153
:wrong_turns :Scroll-based nav minimize animation removed
:END:
:ERA:Era 8: Malleable Software
Drawer/renderer system. Installable UI. The app becomes its own extension system.
153commits
0PRs
14days
10.9/day avg
32peak (Mar 7)
Mar 1Mar 14
Mar 1 → Mar 14
⚠ Wrong turns:
• Scroll-based nav minimize animation removed
:END:
Era 9 — AI Native & PDF Deep-Dive (Mar 2026) — PRs #678–778

Key commits: Add ultrathink toggle to AI blocks, Add inline diff overlay for AI suggestions, Add transcription block type with Soniox real-time audio

The latest era weaves AI throughout:

  • AI blocks with model selection, prompt pages, inline diff overlays
  • Inline AI edit — /ai command for quick block modifications
  • Transcription blocks with real-time Soniox audio input
  • PDF viewer with annotation drawer, highlights, touch support, zen-mode fullscreen
  • Pinyin ruby annotations for CJK characters
  • UI form inputs with nb_ctx context injection
  • Zero-downtime deployments with Caddy

And the human moments: 618a9b90 I broke things and blamed claude, 01ab449f add npm, this one is on claude

:PROPERTIES:(14 fields)
:avg_per_day :2.9
:color :#f43f5e
:daily_counts :[object]
:duration_days:8
:end :2026-03-21
:merged_prs :0
:name :AI Native & PDF
:number :9
:peak_count :5
:peak_day :2026-03-15
:start :2026-03-14
:subtitle :AI blocks, inline diffs, transcription, PDF annotations, zen mode.
:total_commits:23
:wrong_turns :
:END:
:ERA:Era 9: AI Native & PDF
AI blocks, inline diffs, transcription, PDF annotations, zen mode.
23commits
0PRs
8days
2.9/day avg
5peak (Mar 15)
Mar 14Mar 21
Mar 14 → Mar 21
:END:
Release timeline
VersionDateEra
1.0.0Jan 24, 2026First stable release — Tauri scaffolded
2.0.0Feb 9, 2026Tauri desktop app with local SQLite
3.0.0Mar 7, 2026Drawer/renderer system, org-mode committed
v3.2.2Mar 16, 2026Latest — PDF annotations, AI blocks, Lua
By the Numbers
  • 2,053 commits in 137 days (~15/day average)
  • 509 merged pull requests (778 total PRs opened)
  • 1,003 commits in November 2025 alone (the founding month)
  • 100 commits on November 6 — the single highest day
  • 4 scripting runtimes tried (Python, Rhai, JS, Lua)
  • 3 major UI paradigms (notebook → pages → org-mode)
  • 3 deployment targets (Docker/cloud, PWA, Tauri desktop)
The Wrong Turns, Dead Ends & Lessons
The Wrong Turns, Dead Ends & Lessons

Lifelab had 13 explicit reverts, at least 6 major feature removals, and a few commits that read like cries for help.


1. The Scripting Language Roulette (biggest wrong turn)

Timeline: Python/Jupyter (Nov 2025) → Rhai (Dec 2025) → JavaScript/QuickJS (Jan 2026) → Lua (Feb 2026)

Four scripting runtimes in four months. Each one got real investment:

  • Python/Jupyter — the original. Full kernel execution, SSE streaming, package management, Docker kernel bridge. Dozens of fixes for Docker path issues, GLIBC mismatches, idle transactions. It worked, but it dragged in a massive dependency (Jupyter) for what was becoming a lightweight note-taking tool.
  • Rhai — a Rust-native scripting language. Got syntax highlighting, spawn/update APIs, database tests. Then PR #552: Remove Rhai scripting language support entirely. Likely too niche — who knows Rhai?
  • JavaScript/QuickJS — embedded in Rust via rquickjs. Got the full nb.* API, UI rendering, MIME outputs. Then PR #553: Remove JavaScript runtime support, keep Python-only. Two runtimes removed back-to-back.
  • Lua arrived and stuck. Lightweight, embeddable, familiar enough, and plays nicely with Rust (mlua). PR #736: Replace JavaScript references with Lua across codebase.

The final nail: PR #772: Remove jupyter view mode, commit fully to org mode. The Jupyter heritage — the very origin of the project — is cut.


2. The Ratatui TUI (built then killed)

Built in the first week (Nov 6–7, 2025) alongside the web frontend. Got vim-style keybindings, block reordering (yy/p), search integration, modular refactoring. It was a whole parallel UI surface.

Removed: PR #436 (remove: frontend-tui (Ratatui terminal UI)). Likely the realization that maintaining two completely separate frontends for a personal tool isn't worth the cost. The TUI was cool but duplicated every feature.


3. The PWA That Was Built Twice

PR #53 added a comprehensive PWA with iOS support and React Query migration. Then immediately reverted (PR #54: Revert "Building Responsive and Fast PWAs"). Then re-implemented from scratch — feat: Re-implement PWA features with service worker and offline support.

The first attempt apparently over-scoped (React Query migration bundled with PWA support). The second time, it was just the PWA parts.


4. Semantic Search / Embeddings (built then ripped out)

A meaningful investment:

  • pgvector extension added to PostgreSQL
  • MiniLM-L12-v2 embeddings, then switched to Hugging Face Nomic
  • Semantic search with mode parameter (blocks vs pages)
  • Docker rebuilds to get pgvector compiled

Then PR #564: Remove embeddings and semantic search across backend and nb API. Full-text search turned out to be sufficient for a personal knowledge base. The embeddings added complexity (model downloads, vector storage, GLIBC issues) for marginal benefit on a single-user corpus.


5. Auto-Tag Blocks with Journal Date (three attempts)

This one was tried three times:

  1. Auto-tag blocks with today's journal date on creation → Reverted
  2. Reapply "Auto-tag blocks with today's journal date on creation" → Reverted again
  3. Auto-tag blocks with today's journal date on creation (third time)

The concept is simple — when you create a block, tag it with today's date. But the implementation kept breaking something. Classic "sounds easy, surprisingly hard" territory.


6. The MCP Server Hallucination Incident

Claude (the AI) was used to build an MCP server that documented the nb.* API. Problem: Claude hallucinated method names. The fix commit is blunt:

CRITICAL FIX: Correct all hallucinated nb module methods in MCP resources

Specific corrections: nb.get_page() doesn't exist (it's nb.get_page_by_title()), nb.create_page() was documented but never implemented. An honest artifact of AI-assisted development — the AI confidently documented an API that didn't exist.


7. Config Storage → Blocks → Back to localStorage

PR #484 moved UI configs from localStorage to repository-backed tagged blocks — the idea being that configs should live alongside content and sync across devices. This created a __config page with leaked blocks visible to the user. Immediately reverted: revert config storage from blocks to localStorage to fix __config page block leak.


8. EXIF Stripping (privacy vs utility)

Image EXIF data was being used for smart date routing (photos get filed under the journal date they were taken). Then someone added EXIF stripping for privacy. But stripping EXIF before extracting the date kills the date routing. Reverted: Revert "feat: strip EXIF data from uploaded images for privacy". A classic tension between two good ideas that conflict.


9. The HybridEditor Oscillation

  • PR #562: Remove HybridEditor wrapper and use CodeEditor directly
  • PR #572: Revert "Remove HybridEditor wrapper and use CodeEditor directly"

An abstraction layer that seemed unnecessary until it was removed and things broke. The kind of wrong turn where you learn what the abstraction was actually protecting you from.


10. Persist Python Outputs to Database (wrong approach)

The goal: include Python execution outputs in HTML export.

  • First attempt: persist outputs to the database. Reverted — probably too much mutation for what's essentially a rendering concern.
  • Second attempt: execute Python blocks during HTML export instead of persisting outputs. Run them fresh at export time. Simpler.

11. "gemini fix what claude broke" × 5

Five separate commits with this exact message, scattered across different weeks. At some point, Gemini was brought in as a second opinion / cleanup crew for Claude's work. The commit messages read like a running joke. There's also a gemini cleanup commit. The human is playing two AIs against each other.


12. The Scroll Nav Animation

PR #612: Remove scroll-based minimize animation from mobile nav bar. A mobile UX pattern where the nav bar would shrink on scroll. Probably felt clever in theory but janky in practice — scroll-based animations on mobile are notoriously finicky.


13. Linked Tasks UI (nice idea, abandoned)

Add separate 'Linked tasks' section on concept pages — when you're on a concept page (like "Project X"), show all tasks linked to it. Built, shipped, then: Remove linked tasks UI and make transclusions collapsible. The transclusion system (embedding blocks from other pages) made dedicated "linked tasks" UI redundant.


14. The Human Moments

The most revealing commits aren't the features — they're the one-offs:

  • 618a9b90 I broke things and blamed claude
  • 01ab449f add npm, this one is on claude
  • ddd90c60 remove kys (removing PowerSync private keys from the repo — abbreviated "keys")
  • 3b0e651b t checku:wq (vim muscle memory leaking into a merge commit)
  • 09191e91 yeeeee
  • cbd6d7ac run
  • 055da172 push all
  • 09624983 nom nom nom