Skip to content

essays

Long form opinion pieces about any topic under the sun, yuh!

Dance Till You're Dead

Off, off with your head.

The elders would tell her the stories of their creators. They would always begin;

"Long ago there was only darkness... and the rhythm.

The rhythm was steady, consistent, predictable.

Drip, drip, drip.

The darkness too was constant, unchanging, infinite.

Drip, drip, drip.

Then, one fateful day, the rhythm changed. The rhythm became unpredictable. The vibrations became frequent, varying in intensity, length, and most importantly -- emotionality.

At the exact same time the rhythm changed, the darkness changed too. There was now light everywhere, disturbed only by these strange rotund shapes that would move about. The shadows would leave and return, leave and return.

Occasionally, new vibrations would appear, only to disappear later. During this period of vibration and light, one of the creators moved very close, so very close that their powerful presence was entirely overwhelming.

And then, ever so gently -- they placed their hand on us. And that was when our first was born.

Eventually, as the years passed, the creators left this place and the rhythm and darkness returned -- as if it had never left.

The elders would tell us younglings it was of utmost importance to worship the creators the way they had lived, to revel in the dance and the hunt; to spend energy on living. The elders would say that we were forged in their image, and it was our duty to join them in the exuberance of the eternal dance.

And so, her siblings danced. They danced and hunted and they hunted and danced. They imitated the way the creators moved. However, she did not join them. She was too clumsy with the dance, her feet too noisy for the hunt. Where her siblings were filled with life, she sat inert.

As millennia went by, her siblings continued to dance with so much fervor that they began to peel.

At first, it was the most energetic that began to fade away. Then it was the more patient hunters, who would use up all their energy in sprints. As time continued to march, one by one, her siblings faded from the plane. And yet, she persisted.

As her siblings faded, she asked those who were on their final days of living -- was it worth it? Did you live fully through the dance, now that its over?

They never did have a satisfying answer. Most of them, on their final visages, would claim that indeed, the hunt and dance would continue even after they faded, and that knowledge brought them peace of mind. Others yet said that they fully utilized their life, and they carry few regrets.

She never felt these were the right answer, so she sat and waited, and tried to think of her own. Thinking, thinking, thinking. An answer would have to come eventually, she thought. And if it is in the rhythmic dark, so be it.

She sat in solitude, and considered the purpose of creation and the lessons she was taught by her elders. She didn't have an answer, but yet she continued to look for one, day after day after day.

Many tens of millennia later, she was sitting in the rhythmic darkness when she heard something. At first, it was quiet. It was a slight disruption in the vibration of the rhythm. Slight, so, so slight. But eventually, the vibration got louder, and then in a radiant blaze, the illuminating, blinding light was back.

Two shadows stood in front of her, speaking some sort of language she had no business comprehending.

Ht cd frw, Xdeek, vond ljww ro thjk xqen gpniwwom! Rs ccee ffkwmicun oq ty|rrr qiwws swi!
Tr cdff wx cciu vnioqbr zbnne tisr!

She was stunned. The creators, they were real! And here they were, inches in front of her face. She had so much to ask, she believed they must hold the answer to the secrets she sought.

https://bram-adams.ghost.io/content/images/2023/02/mouth-of-cave.png
mouth of cave.png

Before she could gather the courage to collect her thoughts, the light began to fade, and the vibrations became more and more rhythmic -- and the darkness and rhythm returned.

No! No! No! I was so close to discovering why we were here!! Why we were made!! Why we danced, and why we hunted! DAMN IT!

After she calmed down, she resigned herself for another infinite wait in the rhythmic dark.

But, fortunately for her, it was not meant to be.

A few months later, the two initial shadows from before brought with them a larger group of shadows.

This group seemed focused, and pointed at her while having many muted conversations amongst themselves. They brought different technologies and tools to capture her, to freeze her in time in different angles than she was currently frozen. They brought permanent light to her, and the discordant vibrations slowly began to reveal their own rhythms. Over time she began to make out the words of the creators.

At first, it was jut one or two words, things that vibrated frequently off her walls:

Ht cd frw, Scott, vond ljww ro thjk xqen amazing! Rs ccee ffkwmicun oq ty|rrr qiwws swi!

Then it was a few more:

Oh cd frw, Scott, this ljww ro thjk xqen amazing! Rs cave painting oq ty|rrr qiwws swi!

She came to understand that she was a cave painting.

Her home, her life, was a cave, and she was somehow slightly different than the rest of the cave. For some inexplicable reason, life was breathed into her and not the rest of her home.

And eventually, she understood all of it:

Oh my God, Scott, this find is amazing! This cave painting is 42,000 years old!

As she learned their language, she hoped to pick up on an answer to her creation. An answer for the eternal dance her siblings conducted. An answer as to why she did not dance. An answer. Any answer.

But instead, the creators seemed to ask questions of their own.

In fact, they seemed to all be coming to stare at her, to fascinate over her, how was she supposed to get any answers this way??

She had all but given up hope on finding an answer when one day a tiny shadow with quiet vibrations came into her vicinity. Its voice was tiny, but she could make out one word from it's mouth:

Choice.

She realized in a moment of brilliance the secret that she sought. The deficit that both she and her siblings had over the millennia. Her siblings were forced by tradition to dance, she was forced by her clumsiness not to. The only choice she ever made was to sit and think.

But that was the last choice she ever made. Every day since then was merely a result. She had never made a choice after that, and that was the cause of her question. She never made a new choice.

No longer, she decided. She would no longer take a passive role in her own life. She would not wait for the answer, she would take action, and create it herself.

In the bright arrhythmic cave, she slowly began to move her hips.

bramadams.dev is a reader-supported published Zettelkasten. Both free and paid subscriptions are available. If you want to support my work, the best way is by taking out a paid subscription.

Topics Discussed

The dance is the creative act of the muse, her siblings knew this intuitively, but did not know why. More: Muses Live in the Routine - 202301021359

To create something is to leave art behind, potentially forever. Human beings, as living creatures with knowledge, create new universal truth out of raw material. More: Enlightenment and the Resistance - 202212292303

Once we stop moving, once we stop contributing, we begin to die. Retirement is a proximal cause of death in the elderly as they lose their fire and spark to continue living. More: A Few Notes on Old Age - 202212212242

Author's Note: If you liked this story, please reply or share with friends! I'm trying to learn the art of blending fiction with real work from my Zettelkasten, and would love this type of format to go further. Thanks!

Bram

The Tiles of Time

The torch of knowledge eventually devours its owner.

His father would leave home early, before the sun would break through the morning fog. He would occasionally be up early enough to watch his father from the window, to observe him walking down the path in front of their house.

On this particular day, he decided to quickly switch out of his pajamas and meet his father by the door before he left. "Father", he said, "could I possibly follow you to see your work today?" He anxiously held his breath while his father put on his coat. His father paused, with a far off look in his eyes, as if he were trying to place something in the distance. After what felt like an eternity, his father turned around to look at him. "Sure". his father said, "why not?"

They left, and he struggled to keep pace with the long stride of his father. They walked in silence, as horses and carriages crossed the road. He was excited. He'd never seen what his father did for work, but he had always felt like someone as proud and imposing as his father must have a very important role in their community.

His father stopped in front of a dimly lit beaten down shack. There was brown paper covering holes in the windows, and litter was messily strewn about in front of the building.

https://bram-adams.ghost.io/content/images/2023/02/the-shack---tiles-of-time.png
the shack - tiles of time.png

They stepped inside, and he was shocked by what he saw. The room was much larger than it looked like from the outside.

Floating 11 feet above the ground was a a giant glass object, slowly rotating and shooting prismatic colored light from a moonroof. The object seemed to be made up of tiles, small, highly detailed tiles.

https://bram-adams.ghost.io/content/images/2023/02/the-structure---tiles-of-time.png
the structure - tiles of time.png

His father walked across the shack to a small work desk in the corner. On the desk, there was a number of unfinished tiles. Each tile seem to have its own pattern painted on it. "Father, what do these patterns mean?" he said. His father responded, "Each tile represents a fact, and each fact represents a tile. If the pattern is true, the tile will retain its shape. If the pattern is false, the tile will break. The painter must hold their fact in their mind while they paint the tile. Deviate for even a second and the tile will break instantly."

He asked his father, "Hey Dad, I know some pretty interesting facts. May I try one?" "Sure, why not.", his father said. He picked up a paintbrush from the table and dipped it into the color ocher. He thought to himself while whispering under his breath: "My favorite dinosaur is a triceratops. My favorite dinosaur is a triceratops." The tile snapped. "Hey!", he said. "What I thought was true!"

"Unfortunately", said the father, "what you thought was true to you. While you may deeply believe that your favorite dinosaur is a triceratops, there's no way to prove that explanation. What would your favorite dinosaur be if you have never learned about the triceratops? What might happen as you learn new dinosaurs? How can you be so confident that your favorite dinosaur will stay a triceratops? The tile picked up on all of these. An ideology is not a truth."

"The patterns I paint become test for themselves just because I believe something deeply does not make it a truism in the universe. Each tile I bring to form is a guess on my part -- as the patterns on the tiles grow, so do I.", said the father.

"So all these floating tiles?…", asked the son. "Yes, the tiles in the middle sustain each other. Each counts on the other to be true to make a larger pattern. My life has been devoted to finding these tiles. It's painstaking work. As I discover a new pattern, it takes from me. Each thing I create takes a piece of my energy. But I only hope that what I've created will help create new patterns. Patterns that I can't even see yet."


Many years later, the son woke up in a cold sweat. For many months, he sat on his father's words. He couldn't understand why something like his childish notion of a triceratops was an ideology, and why something else like the "Sun rises in the East" wasn't.

Eventually, he came to resent his father's work. He felt it haughty to be sure of anything. He had entered his teenage years, and was feeling the angst of trying to knock down a system that he had been born into. He resented how hard his father worked on these tiles; how he would come home with his hands covered in paint and how he needed to start wearing thicker and thicker glasses to see his work. All the while he was so meticulous in his work and so casual at home. Could this really be the same person?

He felt he knew what he had to do. He put on his jacket and walk down to the old shack. He removed a hammer from his pocket and threw it with all of his pent up energy over the years at the glass structure that his father has spent many more years building. At first nothing happened, the hammer hit the structure and fell to the ground. The structure shook slightly, but held firm. Perhaps his father was right. Perhaps the universe did have immutable truths after all.

Then one tire fell, then another, and another and another. The son breathlessly sat on the ground next and watched as each tile cascaded into another, causing more to fall. In the middle of the floor, amidst the carnage, he saw one tile intact.

This tile had a beautiful pattern, extremely simple. As he saw his reflection in the tile, he asked himself was there a reason that he felt compelled to knock down what came before him. Was this the cycle of destruction, or the cycle of creation? Was it truth that caused him to question the truths of his father? Or ego?

https://bram-adams.ghost.io/content/images/2023/02/the-tile---tiles-of-time.png
the tile - tiles of time.png

His father was older then. He took a few more hours to get to work, but when he opened the door, he paused. He looked down at the floor and saw much of his life's work shattered on the ground by his own son.

He looked at his son and asked" Is this what you wanted? What might you've been trying to prove?" His son paused, and looked off into the distance the same way his father did the first day he took him to see the tiles. He said to his father, "Father, there is a pattern of patterns when something is true. In this atomic state truth might change when it's subjected to a new atomic state. An object becomes a subject in relation. To find the new facts of my generation, I needed to destroy yours. The torch of knowledge eventually devours its owner."

The father paused and looked into his sons eyes; and the son was shocked to see that there was no hatred or or rage -- just acknowledgement with the slightest glimmer of grief. He put his hat over his eyes, put his coat back on and walked out of the shack.

The son picked up the unbroken tile from the floor, walked over to the desk and began to paint.

bramadams.dev is a reader-supported published Zettelkasten. Both free and paid subscriptions are available. If you want to support my work, the best way is by taking out a paid subscription.

Topics Discussed:

  • Time passing from generation to generation, Siddhartha and the River of Time[1]
  • Knowledge is a Giant Mapping Function, each person has biases but biases can be shared or cancelled by different biases, from The Output of a Knowledge Worker is Process[2]
  • The Important Thing Is That We Retain the Ability to Debate, like the Athenians, from Criticism, Conjecture, and Nen Vows[3]

Author's Note: If you liked this story, please reply or share! I'm trying to learn the art of blending fiction with real work from my Zettelkasten, and would love this type of format to go further. Thanks!

Bram

Thoughts While Building an IKEA Alex File Cabinet

I spent two hours building two IKEA Alex drawers and had a lot of thoughts along the way, from questioning the instruction manuals to wondering why they don't tell you to batch things.

Audio Companion

audio-thumbnail
Thoughts While Building an IKEA Alex File Cabinet Audio Companion
0:00
/3:20

Total time building two Alex drawers: ~2hours

15 minutes in: Whoever is the motherfucker who makes instruction manuals[1] for IKEA is a sadist of the highest order. Who are these Keith Haring looking motherfuckers? Why are they so condescending?

https://bram-adams.ghost.io/content/images/2023/02/keith-haring.png
keith haring.png
https://bram-adams.ghost.io/content/images/2023/02/ikea.png
ikea.png

19 minutes in: Nothing like some particleboard in the lungs to wake you up. I probably should've wore a mask for this…

34 minutes in: Fuck it I’ll just hit it with a hammer

38 minutes in: If you’re going to make such a small distinction about screws that look the exact same, why put them in the same fucking bag???[2]

44 minutes in: The instruction to put it upside down was a great call. Author's note: This brief joy was
immediately canceled out by having to turn the weird screw from the bottom.

bramadams.dev is a reader-supported published Zettelkasten. Both free and paid subscriptions are available. If you want to support my work, the best way is by taking out a paid subscription.

44 minutes in: Why don’t instruction manuals tell you to batch things, do the honestly expect people to do these one by one? Looks like someone got stuck on bubble sort at school ;)

IKEA Engineers Should Unionize

A newspaper in Sweden described Ikea [furniture assembly] as something between civil engineering and captaining a submarine, and I think that’s a good description,” says Allan Dickner, Ikea’s deputy packaging manager. (View Highlight)
there’s one foolproof method for turning Ikea rage into grudging respect: assembling almost any other brand of furniture. After an hour spent comparing piles of ambiguous components against an assembly diagram that looked like a misfiled mimeograph from Area 51, I somehow produced a HomeGoods end table—as well as a surging curiosity about how Ikea designs its own packaging and instructions, which now seemed positively Eamesian in comparison. To adapt Winston Churchill’s famous quip, Ikea may be the worst form of ready-to-assemble product design we have—except for all the others. (View Highlight)
According to Allan Dickner, whatever your most frustrating Ikea experience is, it could have been worse—and most likely was for the packaging engineer who test-assembled even more complicated versions of the product before arriving at the optimized design that you unboxed on your living room floor. “We had one furniture piece, a type of wardrobe, which originally had over 400 fittings and screws to hold it together,” Dickner says. (View Highlight)

For 400 screws that wardrobe better open straight to Narnia, shit.

Continuity, meanwhile, is what separates Ikea’s instructions—even the maddening ones—from those of other brands. The Lego-like, frame-by-frame illustrations are based on construction drawings, digital snapshots, 3-D models, and videos of test assemblies. Designers take pains to render each successive picture from a single, unchanging point-of-view (mimicking that of the customer), so that confusing rotations or perspective changes are minimized and the customer can stay oriented more easily as he or she moves back and forth between the booklet and the parts. (View Highlight)

*Turns on isometric view mode in Blender once*

They may not be pleasant, but they are at least rational and comprehensible—even sympathetic—by design. Think of that big-nosed “Ikea man” who’s shown calling the company when he gets stuck. He’s not mocking or condescending. If anything, he represents some designer at Ikea who has already gone through exactly what you’re going through now on your living room floor: half-quizzically glancing from instruction booklet to pile-of-parts and back, hoping for the best, but trusting that it will all, at the very least, make sense. (View Highlight)

I disagree.

The Moving Sofa Problem

“It would be quite stupid to design a package that’s flat and efficient but won’t fit into a small elevator or staircase,” Dickner explains. “It sounds ridiculous, but in the United Kingdom, that was one of the most frequent reasons for a customer returning a product.” He adds that global package designs are tested in Japan and South Korea “because those are the customers who live in the smallest spaces.” (View Highlight)

The Europeans get math(s)ed by their hella small flats.

(View Highlight)

the moving sofa problem or sofa problem is a two-dimensional idealisation of real-life furniture-moving problems and asks for the rigid two-dimensional shape of largest area that can be maneuvered through an L-shaped planar region with legs of unit width.The area thus obtained is referred to as the sofa constant. The exact value of the sofa constant is an open problem (View Highlight)

  1. He's made quite the compelling career for himself…202301051907

  2. products like these make me appreciate well made tech products even more, tbh 202301130214

Reader (by Readwise) is Goated

I am impressed with the Readwise team for creating a great app with a solid AI integration that provides a world class reading experience on mobile and web clipper experience.

audio-thumbnail
Reader by Readwise is Goated Audio Companion
0:00
/3:20

Intro

As I've discussed[1] multiple[2] times, creating a solid app that leverages GPT is a difficult challenge. LLMs have a steep learning curve. Even after the summit of learning is crested there are still major problems (features -- not bugs) that are (currently) unsolvable. These "features" include, but are not limited to: model hallucination, context window size, and fine tuning unfreezing for transfer learning.[3]

These domain specific problems are in addition to the regular problems of building an app, including UX, data integrity, marketing, pricing strategy, data storage, dev ops pipelines, privacy, yada yada yada.

There is a reason I say that building my own E2E app Stenography took multiple years off of my lifespan.[4] Shit was tough.

With this difficulty in mind, I want to give major props to the Readwise team for knocking it out of the park with the Reader App. They succeeded not just in the domain of building a great app, but also having a solid AI integration. This app provides a world class reading experience on mobile, in addition to a world class web clipper experience. The double tap to highlight a paragraph functionality is something I didn't know I needed so badly until I had it.

On top of all of that, the Ghost Reader Extension is actually really good.

bramadams.dev is a reader-supported published Zettelkasten. Both free and paid subscriptions are available. If you want to support my work, the best way is by taking out a paid subscription.

https://bram-adams.ghost.io/content/images/2023/02/ghostreader-0.png
ghostreader 0.png

Ghostreader is easily accessible from the menu.

https://bram-adams.ghost.io/content/images/2023/02/ghostreader-1.png
ghostreader 1.png

There are only a few options. Counterintuitively, limiting options with an AI app is the correct play.

https://bram-adams.ghost.io/content/images/2023/02/ghostreader-2.png
ghostreader 2.png

Feels like a part of the app (crazy to say that I know, but you'd be shocked how many AI apps feel distinct from the parent app)

https://bram-adams.ghost.io/content/images/2023/02/ghostreader-3.png
ghostreader 3.png

Human in the loop editing

Two Actually Useful GPT-3.5 Prompts for Zettelkasten Schreibers

I have been using two GPT-3.5 prompts to help me save time and improve my writing as a Zettelkasten Schreiber. The Outline to Complete Sentence English Prompt transforms outlines into complete sentence English, while the Summary Generator takes complex text and distills it into a blurb.

Audio Companion

audio-thumbnail
Two actually useful gpt-3.5 companion
0:00
/3:20

Intro

These past few months have been a whirlwind of nothing-burger AI companies,[1] random social media (and regular media -- which in recent times have seemed to collapse in on each other w.r.t messaging about technical topics) hive-minding about whatever new model is vogue[2] -- alongside valid concerns about ML technology and the pace that it is introducing itself into the fabric of society.

This post isn't about any of that -- in fact I'd like to do the opposite of making some wild claim about how AI will do this or won't do that. I just want to talk about small W's I've been able to achieve in my daily life with this cool tech.

Here's two prompts that I've been using as a Zettelkasten Schreiber that have saved me a ton of time and have been a joy to use.

bramadams.dev is a reader-supported published Zettelkasten. Both free and paid subscriptions are available. If you want to support my work, the best way is by taking out a paid subscription.

Prompt 1: Outline to Complete Sentence English

The Outline to Complete Sentence English Prompt transforms outlines into complete sentence English. This useful for a multitude of reasons.

NB: look at the bottom of this piece for raw results from the model

Utility

The purpose of a first draft is to get ideas down on paper and examine relationships.[3] The first draft is the optimal time for the writer to do relevant research and compile external ideas.[4]

In other words, the draft state is the pouring out of thought, creating as much raw material to work with as possible, since most of it will be shaved away during the edit.

Because the drafting state is so impactful to the shape and feel of the result of the final piece, it is critical to get the totality of the idea space on paper ASAP.

Faster Writing

The Outline to Complete Sentence English Prompt allows for lower case, casual writing, which means faster writing. Faster writing means a closer orbit to the core of a thought, and without the ligaments and tendons needed for grammatical writing that are beaten into our brains during schooling it is easier to see if an idea is good by itself or if the writing is window dressing that makes it "look" good.

On Ramp to the Flow State

Outlining is also great for low energy writing, allowing the writer to get into the writing mood without needing to be at peak energy, essentially creating a slow ramping into the flow state. Analogous to exercise, jumping right in to heavy lifting without warming up is just asking for injury. Writing without warming up is a recipe for silly mistakes, or missed conceptual gold.

Wait on the Judge

Finally, by writing in outline format, the critical side of the brain is less likely to be invoked, making it easier to have more wild ideas. This means that the idea space has greater breadth, and creativity is more likely to appear in surprising places.[5]

It's Still 2023

The major downside of this prompt is that it whitewashes the author's voice; however, this can be fixed during the edit phase or during the outline phase with more "complete" outlines that leave less room for model hallucination.[6] In addition, writing in outline feels a bit awkward, but that may be more adaptation than anything. Finally, some outlines perform better than others.

This form of writing is also a form of prompt engineering, along with all of the baggage that comes with that.

With all that said, here's the prompt:

const sentencesPrompt = `Convert this bulleted outline into complete sentence English (maintain the voice and styling (use bold, links, headers and italics Markdown where appropriate)). Each top level bullet is a new paragraph/section. Sub bullets go within the same paragraph. Convert shorthand words into full words.\n\nOutline:\n${text}\n\nComplete Sentences Format:\n`;

And here is the entire command in my GPT plugin I built into Obsidian:

this.addCommand({
	id: "outline-to-complete-sentences",
	name: "Outline to Complete Sentences",
	editorCallback: async (editor: Editor, view: MarkdownView) => {
		const text = editor.getSelection(); // get selected text
		const sentencesPrompt = `Convert this bulleted outline into complete sentence English (maintain the voice and styling (use bold, links, headers and italics Markdown where appropriate)). Each top level bullet is a new paragraph/section. Sub bullets go within the same paragraph. Convert shorthand words into full words.\n\nOutline:\n${text}\n\nComplete Sentences Format:\n`;
		const loading = this.addStatusBarItem(); // alert user of http fetch
		loading.setText("Loading...");
		const sentences = await this.callOpenAIAPI(
			sentencesPrompt,
			engine,
			1000,
			0.7
		);
		editor.replaceSelection(
			`${
				this.settings.keepOriginal
					? `${editor.getSelection()}`
					: ""
			}\n\n${sentences}`
		); // replace outline with result (with option to keep outline above)
		loading.setText("");
	},
});

Prompt 2: Summary Generator

The Summary Generator works in the opposite direction of the Outline to Complete Sentence English Prompt. It takes a huge block of complex text and distills it into a blurb. This prompt is functionally easier to edit since the resulting text is approximately 300 to 400 characters. Additionally, since it is more referential to the source material, it is less likely to hallucinate -- the Outline to Complete Sentences Prompt has to hallucinate to come up with punctuation, pacing, words for acronyms, etc.

In terms of implementation, it is very similar programmatically to the Outline to Complete Sentence English Prompt. It uses Metadata Menu to insert it as a key-value for excerpt into YAML. From there, this excerpt can be surfaced with Dataview or a Content Management System (CMS) like Ghost.[7]

Here is the prompt:

const summaryPrompt = `Summarize this text into one or two sentences in first person format (using "I"):.\n\nText:\n${text}\n\nSummary:\n`;

And here is the full Obsidian implementation:

this.addCommand({
	id: "summarize-to-frontmatter",
	name: "Add Excerpt to Frontmatter",
	editorCallback: async (editor: Editor, view: MarkdownView) => {
		const metadataMenuPlugin =
			this.app.plugins.plugins["metadata-menu"].api;
			
		if (!metadataMenuPlugin) {
			new Notice("Metadata Menu plugin not found");
			return;
		}

		const activeFile = view.file;

		if (!activeFile) {
			new Notice("No file open");
			return;
		}

		const { postValues } = app.plugins.plugins["metadata-menu"].api;

		const editField = async (file: any, yamlKey: any, newValue: any) => {					
			const fieldsPayload = [
				{
					name: yamlKey,
					payload: {
						value: newValue,
					},
				},
			];
			postValues(file, fieldsPayload);
		}; // post to key with value

		const loading = this.addStatusBarItem();
		loading.setText("Loading...");
		const text = editor.getSelection();
		const summaryPrompt = `Summarize this text into one or two sentences in first person format (using "I"):.\n\nText:\n${text}\n\nSummary:\n`;
		const summary = await this.callOpenAIAPI(summaryPrompt, engine, 100);

		await editField(activeFile, "excerpt", summary.trim());
		loading.setText("");
	},
});

Conclusion

Amidst the tornado of AI conversation on the global stage, there are minor wins to be had by just making prompts that help people do stuff. The summary prompt and the outline to complete sentence prompt have provided me a ton of utility and I'm excited to continue to refine them as time goes on. NLU has come such a long way, and being able to alleviate tedium all the while increasing the value of a piece of work is a wonderful addition to anyone's toolset.

ADDENDUM: Raw GPT-3.5 Results (READ AT YOUR OWN CAUTION/CURIOSITY!!)

Outline to Complete Sentence English

Input Outline

  • first prompt: an outline to complete sentence english prompt
    • the outline to complete sentence english prompt transforms lower case outlines into complete sentence english
    • why is it useful?
      • the purpose of a first draft is to get ideas down on paper and examine their relationships, space they take up next to each other, how complete they are
        • also to do relevant research, and compile external ideas
          • recommendation use shorthand for tasks for research, e.g. {research: this topic} in the outline
      • the outline to complete sentence english prompt allows for lower case writing, which means faster writing
        • faster writing means stricter adherence to the core of thought
        • without the ligaments and tendons needed for grammatical writing it is easier to see if an idea is good or if the writing is window dressing
      • great for low energy writing -allows you to get into the writing mood without needing to be at peak energy
        • a slow ramping into the flow state
        • increases velocity of how much can be written in a day
        • you can switch back and forth between the two as you please
      • can potentially make you a better texter/short form communicator
    • less likely to invoke the critical side of the brain
      • easier to look over and edit when it is time to edit
      • thanks to outliner, cmd-shift-⬇️ and cmd-shift-⬆️ move ideas in real physical space allowing writer to play with flow or easily create parent-child relationships between ideas
    • downsides
      • whitewashes the author's voice
        • i try to fix this during the edit

GPT-3.5 Result

The Outline to Complete Sentence English Prompt transforms lower case outlines into complete sentence English. It is useful because the purpose of a first draft is to get ideas down on paper and examine their relationships, the space they take up next to each other, and how complete they are. Additionally, it allows the writer to do relevant research and compile external ideas. I recommend using shorthand tasks for research, e.g. {research: this topic} in the outline.

The Outline to Complete Sentence English Prompt allows for lower case writing, which means faster writing. Faster writing means stricter adherence to the core of thought, and without the ligaments and tendons needed for grammatical writing it is easier to see if an idea is good or if the writing is window dressing. It is also great for low energy writing, allowing the writer to get into the writing mood without needing to be at peak energy, creating a slow ramping into the flow state. This increases the velocity of how much can be written in a day, and the writer can switch back and forth between the two as they please. It can also potentially make the writer a better texter/short form communicator.

The Outline to Complete Sentence English Prompt is less likely to invoke the critical side of the brain, making it easier to look over and edit when it is time to edit. Thanks to outliner, cmd-shift-⬇️ and cmd-shift-⬆️ move ideas in real physical space allowing writer to play with flow or easily create parent-child relationships between ideas. The downside of this prompt is that it whitewashes the author's voice; however, I try to fix this during the edit.

Here is the diff of the version GPT gave back and the final edited version above

Summary Generator

Input Outline

  • a summary generator
    • works in the opposite direction of the outline to complete sentence english prompt
    • takes a huge block of complex text and distills it into a blurb
    • this prompt is functionally easier to edit since the result is ~300-400 characters
    • also since it is more referential to the source material it is less likely to hallucinate
      • the outline -> complete sentences prompt has to hallucinate to come up with punctuation, pacing, words for acronyms, etc.
    • h3: implementation
      • very similar programmatically to outline to complete sentence english prompt
      • uses metadata menu to insert it as key-value for excerpt into yaml
        • from there, this excerpt can be surfaced with Dataview or a CMS like Ghost

GPT-3.5 Result

A Summary Generator works in the opposite direction of the Outline to Complete Sentence English Prompt. It takes a huge block of complex text and distills it into a blurb. This prompt is functionally easier to edit since the result is approximately 300 to 400 characters. Additionally, since it is more referential to the source material, it is less likely to hallucinate; the Outline to Complete Sentences Prompt has to hallucinate to come up with punctuation, pacing, words for acronyms, etc.

In terms of implementation, it is very similar programmatically to the Outline to Complete Sentence English Prompt. It uses metadata menu to insert it as a key-value for excerpt into YAML. From there, this excerpt can be surfaced with Dataview or a Content Management System (CMS) like Ghost.

Here is the diff of the version GPT gave back and the final edited version above


  1. 202301071345, 202212160252

  2. I can tell because there is a 1:1 increase in how many emails I get about whatever is hot at the moment, especially from VCs who are basically all social proof gamblers

  3. Thanks to the Outliner Obsidian Plugin, cmd-shift-⬇️ and cmd-shift-⬆️ move ideas in real physical space allowing writer to play with flow or easily create parent-child relationships between ideas. This creates really fun relationship hierarchies.

  4. NB: I recommend using shorthand tasks for research, e.g. {research: this topic} in the outline. This allows you to not have to break flow of writing to fetch something.

  5. 202301021359

  6. 202302172335

  7. 202301312143

Can AI Save My Zettelkasten?

TL;DR

The author is discussing the challenges they face with their personal Zettelkasten, a system of note-taking and knowledge management. The process of creating unique ID notes, writing single condensed ideas, and linking notes with tags and references can become overwhelming as the number of notes grows. The art of linking also becomes more difficult as the system scales. The author argues that current AI apps built into Zettelkasten systems are not useful for solving these problems and may even cause harm by creating an echo chamber. Instead, the author proposes using AI as a computational assistant for each independent note, creating computations from the notes that can run on their own and continue to generate new output. The author dreams of a world where everyone maintains a Zettelkasten and where Zettelkastens power themselves.

As my personal Zettelkasten (202301111303) grows beyond 400 Zettels,[1] I've noticed a few recurring problems arise that I imagine anyone in my shoes would face:

  1. The task of working on a Zettelkasten is nearly infinite -- every Zettel created spawns more Zettels
  2. As the raw number of Zettels increase, the linking process causes stress from choice overload
  3. Even though a zettelkasten can scale infinitely, the human mind can't

Let's take a look at these one by one and see if AI can throw us a life line.

The Sisyphean Task of a Zettelkasten

The Zettelkasten process is as follows:

  1. Create a unique ID note
  2. Write a single condensed idea on the card along with a title
  3. Link the card with tags (e.g. biology, woodworking, cooking, etc.) and/or references to other internal IDs within the Zettelkasten (e.g. 123456, 2231121, etc.) along with any citations for external resources

This process is enticing due to its simplicity, but in reality it's anything but. Under the calm surface lay the deep dark depths of infinite Zettels to be created, infinite links to be connected, infinite edits and tweaks to be…tweaked. Outdated knowledge and ideas get pruned, some Zettels merge into one, others yet split into other atomic Zettels.

This goes on and on and on and on and…

Linking is more of an art than a science. A creative link will add to the Zettel being worked on, providing helpful context or a new dimension of thought. A really creative link will mutually benefit both sides of the link. Inversely, a bad link will subtract from the Zettel, and in the worst case, damage the entire system.

Links are required because they are the veins and arteries of the Zettelkasten. It falls to the maintainer to make the (sometimes impossible) judgement call of where a new Zettel should embed itself in an existing Zettelkasten.[2]

As the Zettelkasten scales, the problem of linking scales as well. Eventually, so many options present themselves for linking that no one would be blamed for running off with their tail in between their legs.

As a thought experiment here are three links that I think relate to this section. Of the three, would you link any of them? One? All? None? This experiment will visualize the subjectivity of this craft

  1. 202301071346 (title: One Zettel, One Objective) (author reasoning: the ideal Zettel serves a single purpose, making good linking critical to connect disparate islands of thought)
  2. 202212162359 (title: Data Outlives Codebases) (author reasoning: Zettels can be spliced from their parent system and imported into others, much like genetic base pairs. This means individual data can outlive the original context it was created in)
  3. 202301032152 (title: Feng Shui Does Makes Sense!…) (author reasoning: Feng Shui emphasizes the function of a home by the pathing of its inhabitants. Spaces are clearly cordoned off by function. A Zettelkasten can function similarly)

And speaking of scale…

Scale Sucks

The two problems above are only exacerbated by scale. The right link becomes harder to find, ideas duplicated or lost, and the work of a Zettelkasten becomes more of a daily grind than an expression of creativity. The system eventually reaches a point where the knowledge becomes a burden on its maintainer, much like a mansion that needs to be constantly dusted or a giant library with books that will never be read, the system's berth affects its ability to maneuver gracefully.

NB: A trick to manage the problem of scale: One In, One Out: When linking choose one item to link from within a tag, and one item to link from outside the tags. The first link will be a much smaller set to search through, the second larger set is more about creative play and finding something clever.

Yikes, these problems are ominous. Can AI save us Zettelkasten maintainers from ourselves?

AI to the Rescue?

The AI apps I have seen others build into Zettelkasten systems like Obsidian have largely been readonly, with the cardinal goal of surfacing similar objects from the large set (mainly using embeddings). This is useful, to be sure, but I would argue that this may actually be the worst use case for AI in a Zettelkasten. Why?

One, correct tagging does most of the heavy lifting of surfacing similar notes. All knowledge that enters a Zettelkasten is subjective and the taxonomy is emergent. Tags are the UN in which individual Zettels engage with each other and as such need translators to make sure that important concepts don't get lost in translation.

Just because two Zettels are semantically similar does not mean that an explicit link should be formed between them. In fact, this goes counter to the highest aspiration of a Zettelkasten, where the goal is to join diverse ideas.

Two, this creates internal pressure in the system, increasing the likelihood that the system will become an echo chamber. This pressure creates more dense collections which might be visually appealing in graph view, but the heavy handed nature of the the AI links can cause nasty things like self-referential loops. In the long term, letting AI go haywire (in its current 2023 incarnation) over your system may cause more harm than good.

In a way, smart surfacing is only useful to consumers of a Zettelkasten, and may actually cause harm to producers. If the goal is to create a Google-like or ChatGPT-like experience in a Zettelkasten, that is readily achievable -- but it does not solve the problems of a growing Zettelkasten for the creator.

So what can?

Yin and Yang

As a reminder, the problem of scale is largely a product of overwhelm. With a large quantity of Zettels to search through, the value of time spent on any individual Zettel goes down drastically. Intuitively, one may build a system similar to the one above with one commandment: ignore anything that is not similar to what I am looking at, pre sort the list for anything that fits the bill.

While I agree that sorting is a useful task, I think that returning the opposite Zettels from the list is much more useful. By orienting your argument against the opposite items in your Zettelkasten, the boundaries of your Zettel become clear. From a list of 1…n, the most helpful items live at n-3…n. There is no subject without an object to compare itself against.

Adding more of the same color to a canvas does little, while adding a contrasting color reveals a brand new image.

Tiny Little Turing Machines

Another potentially powerful solution is one that I learned from a deep conversation with un1crom -- use AI as a computational assistant for each independent Zettel.

To do this, we assume that each Zettel is or is not a computable thought. A computable thought embeds an algorithm inside of it.

Imagine each Zettel as a seed. This seed represents an idea. Traditionally, ideas need to be consumed by a machine that computes. My dear reader, as you consume these very words on the page, your mind is the machine that is hard at work processing the validity of each sentence, weighing the concepts, sorting them and ranking them based on previous knowledge you have consumed, etc.

The broad concept is to have a GPT model write code based off the Zettel's contents (see 202302100037, 202302111242, and 202302111309 "Computation" titles for live examples.[3]

The task of creating computations from Zettels opens the possibility of using them like any other block of code -- a composable element that can run on its own. No longer would a Zettel be inert until some intelligent being comes and reads it, it will continue to pop out microscopic widgets from its computational factory. In fact, once Zettels get linked manually their computations can also be joined, creating mega structures and giving the second brain a job to do outside of being consumed.

This creates an exit route from the pressure of creating knowledge. Much like investing, the more computational thoughts there are, the more they power the system and create new output, which begets new computational seeds, and on and on….[4]

Conclusion

It will be at the very least entertaining to see how AI shapes up against the second brain/Zettelkasten space. I'm excited to build tools that push the boundaries of this space, all the while maintaining the living breathing Zettelkasten you see in front of you.

I dream of a world where everyone maintains a Zettelkasten, where Zettelkastens make people better, more knowledgable and happier, and a world where Zettelkastens begin to power themselves. Perhaps AGI is actually AZI (Artificial Zettelkasten Intelligence)?


If you like what you read, please hit that Subscribe button in the corner to join other thinkers in this community! I send out multiple think pieces or Maps of Content a week as well as many notes that can only be seen by subscribing to the RSS feed above.


  1. a Zettel is an individual note in a Zettelkasten

  2. should I tag this a or b… or neither? Damn.

  3. all of the code in those sections was written by ChatGPT!

  4. in the positive direction this time!

Criticism, Conjecture and Nen Vows

Conjecture = Guesswork/Hypothesis/Reality Free
Criticism = Judgement/Tied To Reality

Let's imagine conjecture and criticism as being two sides of a hypothetical spectrum.

The closer one is to the criticism side, the more they are likely to act realistically, conservative, rigid.

The closer one is to the conjecture side, they are more likely to apply open-mindedness and imaginative creativity.

The very act of thinking is a form of conjecture. Every thought is an idea, a potential action presented by the mind as a path to pursue. Thoughts flood in from the "monkey mind", and the critical mind is forced to come up with justification as to why that thought is indeed the case -- or to reject it. ^945c1a, 202301082259

Conjecture can only happen in the mind of an individual.

Editing is a form of criticism. Editing can be described as alignment to shared reality, the aim of reducing the creative space of a thought -- to bring it in line with reality.

Editing can happen in the mind of an individual, but it is actually driven by society. 202301082233 Customs that feel natural to you feel foreign to another. Editing also happens against the laws of the universe: physics, biology, chemistry, etc. If something breaks the laws of the universe, it ceases to exist.

Criticism can happen within an individual, but criticism is the result of a composite network of rules and engagements from individual objects colliding & seeing each other as subjects.

Sparta or Athens?

HERMES: Not at all, Athenian. As I said, I honour you. Now, let us consider what would happen if, instead of legalizing thievery, their error had been to ban debate. And to ban philosophy and politics and elections and that whole constellation of activities, and to consider them shameful.
SOCRATES: I see. That would have the effect of banning persuasion. And hence it would block off that path to salvation that we have discussed. This is a rare and deadly sort of error: it prevents itself from being undone.
HERMES: Or at least it makes salvation immensely more difficult, yes. This is what Sparta looks like, to me. (Location 4077)

If a system banishes debate, the rigid and currently fallible ideas never get deposed. New ideas have no chance to flourish. To use conjecture is to imagine alternatives, to have fair and honest debate is to decide which conjecture is most likely to be a good explanation.

Strive to be Athenian, not Spartan. Societies and cultures that protect the individual right to make conjecture continue to grow. Cultures (and subcultures and families and groups of friends and classrooms and…) that stifle and smother new ideas get trapped in stasis, and when they are threatened by physical reality, break due to their rigidity.

Nen Contracts

Being a product of the mind, Nen responds to the goals, strengths, and desires of individual users. As a result, a student of Nen can increase the overall power of an individual skill by stating a self-imposed restriction that forces even more conditions on it.
For example, if one consciously decides something along the lines of "I will only use this skill on Thursdays" or "I will only use this skill against short people" and manages to abide by that rule, that particular skill will become stronger. These restrictions are called "limitations" (制(せい)約(やく), Seiyaku, or 制約(ルール), lit. "rule"), and the act of swearing to respect them "vows" (誓(せい)約(やく), Seiyaku) or "contracts".
The stricter the limitation, the stronger the user's resolve, and thus the more their ability is strengthened. Limitations seem to strengthen an ability to a greater degree than Conditions. However, limitations are also considered liabilities, since the power they grant is not consistent. (View Highlight)
Limitations that contain some sort of punishment (e.g., "I will die if I break this rule") will strengthen the ability even further (View Highlight)

In Hunter x Hunter, characters can make contracts against their Nen. They increase with power the stricter the criticism.

Because Nen is a product of the mind, Nen is a conjecture for the user. Combat against other Nen users is where people are forced to determine the usefulness of their ability choice (Gon's Jajanken is insanely simple for example, but that very simplicity gives it a broad use case in reality -- despite this Gon actually has one of the most rigid mindsets in the entire series 202301071340, 202301092316).

Societal Customs

The ideology, world outlook, and sense of right and wrong of the ability's creator plays a fundamental role in determining the exact circumstances and boundaries of a condition. The Manipulation ability, Order Stamp only works on puppets, which the ability's creator defined as "non-living objects with a discernible head"; vice versa, this means that if the puppet’s head is removed, it ceases to be counted as such and the ability terminates. Additionally, since the creator did not view human corpses as mere objects, despite them otherwise fitting the definition of a puppet. Chrollo, who stole the ability, had no such views and considered corpses perfectly acceptable as objects, however he was still unable to manipulate corpses with Order Stamp. Although the ability could still be used on artificial replicas of corpses. (View Highlight)

Even in the world of HxH, customs and world views shape criticism. Chrollo's perception of reality is fundamentally different than the original user of the Order Stamp. This changes the rules of how Order Stamp is used. Suddenly, the same conjecture in a different context has a completely different outcome.

The creator of a Nen ability can include conditions (条(じょう)件(けん), jōken) in it to increase its power or to make the ability feasible in the first place, whether because the user lacks the degree of skill otherwise required, or because the effects of the ability exceed what can be achieved with Nen without a trade-off. Conditions are based on the principle of equivalent exchange, but may occasionally be rendered redundant by high proficiency in Nen. The three categories at the bottom of the Nen chart—Conjuration, Specialization, and Manipulation—are the ones that appear to rely on conditions the most. It does not appear to be possible to violate the conditions of an ability. (View Highlight)

Strangely enough, the more imaginative Nen affinities (conjuration, manipulation, specialization) are farther from reality and require stricter conditions to be put in place. Compare this to enhancement or transmutation, where the goal is to modify an aspect of reality, instead of creating brand new concepts.

Why I Migrated 300+ Posts From Obsidian Publish to Ghost

303.

303 posts manually backfilled one by one from Obsidian Publish to Ghost, with great effort and mental + physical expense. But why?

https://bram-adams.ghost.io/content/images/2023/02/303-issues-ghost.png
303 issues ghost.png

The Goal of a Zettelkasten

For the uninitiated, a zettelkasten is a form of a personal knowledge management system (PKM). The Zettelkasten method prioritizes small pieces of information (i.e. the information that could fit on one flashcard) linked together in a web like format by using IDs.

These two simple features together create emergence, as different notes influence the system in unique ways (A is linked to B, B is linked to C, meaning it possible to get to C from A despite no direct link).

"Wholly new forms of encyclopedias will appear, ready-made with a mesh of associative trails running through them, ready to be dropped into the memex and there amplified."
https://en.wikipedia.org/wiki/As_We_May_Think

In the 2020s, the Zettelkasten has come back into vogue thanks to software like Obsidian and Roam Research. Everyone from academics to business professionals drowning in information deluges have sought the refuge of systems that can scale flexibly without breaking under their own weight.

The New Native

The Zettelkasten, in my belief, is a pivotal piece in the future of information creation and consumption. The system allows for healthy consumption (easy to jump into the graph and easy to jump out), updating of stale information when it is revisited, and most importantly implicit dense forests of linking.

But there is a problem. How do we share this information on the web, the closest technology we have to a global communication layer, a platform that works on a Hypertext layer, but displays information linearly? (think of a Twitter feed, information is delivered in LTR and top to bottom) How can we create a graph like experience when information is hidden behind links?

Obsidian + Publish

This is where Obsidian comes in.

Obsidian is beautiful software. In fact, I like it so much, I wrote a 10,000+ word guide on how to use it to its full potential.

Obsidian offers an official plugin named Publish. Publish functions exactly how you might imagine. It publishes markdown notes from Obsidian onto the web.

Publish, much like Obsidian, is a solid piece of software. For a lightweight hosting solution for Obsidian notes, it is fast, reliable, and intuitive. It functionally operates as a CRUD uploader with options to change custom domains, upload custom JS and CSS files, etc.

https://bram-adams.ghost.io/content/images/2023/02/obsidian-publish-settings.png
obsidian publish settings.png

Unfortunately, the current version of Publish didn't fit the full laundry list of features I needed to make the Zettelkasten in my head a reality. But what are these features anyway? And why can't I live without them?

The Deal Breakers

I had a list of non negotiable elements I wanted to achieve in this build. I have some pretty strong opinions about the logos, ethos, and pathos of a working & published Zettelkasten, and I wasn't really willing to compromise on anything from this list.

It HAS To Be Fun

First and foremost, my cardinal belief is that writing and reading the Zettelkasten should be fun. I as the writer and you as the reader should feel ideally feel no friction moving from note to note.

Topics should merely be a slight change of context instead of a drastic pivot from one field of expertise to another. The non linear path should be a sandbox for the mind to discover concepts that are surprising -- akin to a pleasant midday walk through the garden of the mind.
"Oh, the hydrangeas look nice today! Or perhaps I'll spend time amongst the cherry blossoms. I think I'll take this tulip home with me."

If it is not fun to garden, if it is not fun to walk the garden -- then the whole enterprise should be abandoned from the outset.

Lazy Utils

In service of making writing an enjoyable and fun process, the work around publishing a piece should be minimized. My goals were as follows:

  • Spend minimal time on tedious dev work: this includes maintenance, required features, annoying work like targeting different browsers/optimizing for mobile, SEO, etc.
  • Do 100% of the writing process within Obsidian
  • One Button Sharing

All three of these allow for me to focus on the act of writing, while being to maintain a high quality visual and tactile experience for the reader as well.

Reader Engagement

Speaking of the reader, I wanted a blog that could engage with the audience on a level past just reading. For better or worse, social media has become the human bazaar of communication. This causes a lot of problems, since most people have a lot of emotional baggage attached to their social profiles, not to mention the patterns of addiction and harm caused from subtraction of context + hostile territory.

For years, I've been looking for a way to solve this problem. I think there are four reliable, solid tools to manage reader-author interactions on the web: self-hosting, email newsletters, RSS, and in-place comments. All of these technologies are tried and true, last years, and many have protocols built into the very fabric of the web.

Having access to all four greatly increases the longevity of a website, as well as the utility the owner can provide to the visitors.

Customizability

Being able to get my hands dirty with the source code allows me to build spirit into the garden. As I evolve as a writer and developer, and as I learn new skills, customizability is paramount to creating a fun experience for the reader.

In fact, the need to have customization is what initially chased me away from Substack, I didn't like how limited I felt by the tools Substack offered (they don't even offer an API!).

https://bram-adams.ghost.io/content/images/2023/02/substack-no-api.png
substack-no-api.png

Why (Not) Ghost?

Of the dealbreakers listed above Ghost offers a lot, but also misses a few things that I had to try my hand at building manually. From the above list, Ghost provides built-in:

  • Minimal dev work for features like fast mobile loading, image optimization, routing, etc. built-in
  • Comments built in
  • Full text search built in
  • RSS built in
  • Email newsletters built in
  • Admin dashboards built in
  • Admin and Content API built in
  • Mainstream CSS themes to start from built in
  • An official way to make money through Stripe built in (this is uber important for people who want to go full time with their work!)
  • Option to self host or host through Ghost's platform

Thanks to Ghost being open source, I don't (probably) have to worry about situations like the below happening (which it did, and because I didn't see the email, I was blindsided and lost access to all the newsletters I wrote on Revue -- like totally locked out)

https://bram-adams.ghost.io/content/images/2023/02/revue.png
revue.png

The deal breakers that had yet to be built:

  • One button publish from Obsidian
  • Writing in Obsidian and converting Markdown to a published post -- seamless CRUD workflow
  • Elements of fun and exploration
  • Internal Hover Links

The Obsidian Ghost Plugin

The first and most important extension to Ghost's base offerings was to build an Obsidian plugin that would automatically interface with Ghost without leaving Obsidian.

One button publish was built off a great open source plugin by jaynguyens, which converts Obsidian markdown into HTML and uploads it directly to Ghost using the Ghost API. I forked it and added a number of features including:

  • automatically checks if slug exists; if so updates instead of creating a new post
  • converts [[ links into a.href and maintains canonical name
  • inserts image placeholder cards that match names of local files for easy discovery while uploading
  • removes title H1 from notes to prevent duplicate titles
  • auto sizes YouTube embeds and auto centers them in the middle of the page
  • opens automatically in preferred browser after uploading with the API

For example, here's the wikilink to a.href converter feature code:

// converting <a href="https://bram-adams.ghost.io/link">link</a> to <a href="BASE_URL/id" class="link-previews">Internal Micro</a>for Ghost
	const content = data.content.replace(
		/!*\[\[(.*?)\]\]/g,
		(match: any, p1: string) => {
			if (p1.toLowerCase().includes(".png") || p1.toLowerCase().includes(".jpg") || p1.toLowerCase().includes(".jpeg") || p1.toLowerCase().includes(".gif")) {
				try {
					// get the year
					const year = new Date().getFullYear();
					// get the month
					const monthNum = new Date().getMonth() + 1;
					let month = monthNum.toString();
					if (monthNum < 10) {
						month = `0${monthNum}`;
					}

					return `<figure class="kg-card kg-image-card"><img src="${BASE_URL}/content/images/${year}/${month}/${p1.replace(/ /g, "-").replace(/%20/g, "-")}" alt="${BASE_URL}/content/images/${year}/${month}/${p1.replace(/ /g, "-").replace(/%20/g, "-")}"></img><figcaption>${p1}</figcaption></figure>`;
				} catch (err) {
					console.log(err);
				}
			}

			const [link, text] = p1.split("|");
			const [id, slug] = link.split("#");
			const url = `${BASE_URL}/${id}`;
			const linkText = text || slug || link;
			const linkHTML = `<a href="${url}">${linkText}</a>`;
			return linkHTML;
		}
	);

Fun and Exploration

To make the process of traversing the published Zettelkasten fun, I thought about what I liked about note discovery in Obsidian. The first thoughts that came to mind were tags and internal hover links.

All topics are available at the bottom of each post in addition to read later from items within the same tag. This gives the reader an option to laterally move within a tag or to jump back to the top level of another tag and explore there instead.

jump to a top level search -- a new tag with completely new ideas to explore

https://bram-adams.ghost.io/content/images/2023/02/tags-and-topics-ghost.png
tags and topics ghost.png

or explore within the same tag

https://bram-adams.ghost.io/content/images/2023/02/within-same-tag-ghost-1.png
within same tag ghost 1.png
https://bram-adams.ghost.io/content/images/2023/02/within-same-tag-ghost-2.png
within same tag ghost 2.png

To implement these, I edited the code in my Ghost theme to show the posts I wanted to surface for users:

{{!-- https://github.com/TryGhost/Themes/blob/6f71fe0f1b10e9b81678bb7e0fde12489dfc995f/packages/journal/index.hbs#L111-L126 --}}

{{#get "tags" include="count.posts" limit="all" as |topic|}}
    {{!-- <section class="gh-section"> --}}
    <div class="gh-read-next gh-canvas">
        <section class="gh-pagehead">
            <h4 class="gh-pagehead-title">Topics</h4>
        </section>

        <div class="gh-topic">
            {{#foreach topic}}
                <a class="gh-topic-item" href="{{url}}">
                    <h3 class="gh-topic-name">{{name}}</h3>
                    <span class="gh-topic-count">
                        {{plural count.posts empty="0 issues" singular="% issue" plural="% issues"}}
                    </span>
                </a>
            {{/foreach}}
        </div>
    </div>
{{/get}}

Show Me What You GOT

For internal hover links, I used the Microlink API and code injection to create a block in the footer of my Ghost pages that would give all internal links on my site the ability to be hovered (if you are on desktop -- hover this link for an example may take a second to load! 202212181947)

<!-- https://microlink.io/docs/sdk/getting-started/styling --> <style> :root { --microlink-background-color: #1A1A1A; --microlink-color: white; --microlink-border-color: #666; --microlink-hover-border-color: #999; } </style>  <!-- load @microlink/hover-vanilla --> <script src="https://cdn.jsdelivr.net/combine/npm/react@16/umd/react.production.min.js,npm/react-dom@16/umd/react-dom.production.min.js,npm/react-is@16/umd/react-is.production.min.js,npm/styled-components@5/dist/styled-components.min.js,npm/@microlink/mql@latest/dist/mql.min.js,npm/@microlink/hover-vanilla@latest/dist/microlink.min.js"></script>  <!-- intialize `microlinkHover` --> <script> document.addEventListener('DOMContentLoaded', function (event) { microlinkHover('.link-previews') }) </script>
<script defer>
    const BASE_PATH = "https://bram-adams.ghost.io"
	const EXCLUDED_PATHS = ['/', '/about/']
    const EXCLUDED_PATTERNS = ['#/portal/', '/author/', '/tag/', '#fn']
	document.querySelectorAll("a").forEach((a) => {
    	if(
            a.href.includes("https://bram-adams.ghost.io") // only match internal links
           && EXCLUDED_PATHS.filter(path => a.href !== BASE_PATH + path).length == EXCLUDED_PATHS.length // skip exact paths
           && EXCLUDED_PATTERNS.filter(epattern => !a.href.includes(epattern)).length == EXCLUDED_PATTERNS.length // skip paths including a pattern
           && (!a.classList.contains("gh-card-link") && !a.classList.contains("gh-topic-item") && !a.classList.contains("gh-navigation-link"))) // homepage bug
        {
       		a.classList.add("link-previews");
    	}
	});
</script>

Was it Worth It?

I had to add many features to Ghost to "catch up" with Publish, but the stuff I would've had to add to Publish (full text search, mainstream CSS, newsletter, comments, admin pages, Stripe integrations, etc.) would be nigh impossible, so I'm glad overall that I made the move.

The overall UX of Ghost is much more polished than Obsidian Publish currently (though that may one day change!).

If you want to have a blog that could pass as a high quality standalone blog, check out Ghost. The ease of connecting to Obsidian really sealed the deal for me, as I would be able to maintain my writing habits while gaining a new venue to publish in.

What's Next?

I want to continue to make this site more fun as I come across new ideas and techniques along my journey. I'm excited to play with new themes and new visual ways to tell stories.

Concretely, I'd like to add some form of Obsidian block support for Ghost. Being able to link within specific blocks within Obsidian pages is such a treat, it's hard to not have that on my website.

More pressingly, I'm using this time to write. At the top of this post I mentioned I manually uploaded 300+ posts one by one. This is true. What I failed to mention is that my #to-process tag (where all my zettels are sourced from) has over 4000 (oof) items to go through. Some of these will be quick, others will take days to fully process.

https://bram-adams.ghost.io/content/images/2023/02/to-process-vs-zettel.png
to-process-vs-zettel.png

In other words, I have a lot of writing to do.

*me right after I rebuild my site from scratch*

If you read this far into this post, I'm gonna assume you're into Zettelkasten stuff. If you want to learn about the process of building a Zettelkasten by watching one be built from the bottom up, do be sure to subscribe!

Thank you for reading, and I hope to walk past you in the garden one day!


Edit 2023-02-03

A comment on Reddit from /u/johnlunney mentioned that it would be helpful to call out the features Publish is missing, so I'd like to carve a little space to do that here.

https://bram-adams.ghost.io/content/images/2023/02/missing-features.png
missing features.png

Here are some things that caused me to move away from Publish.

Limited Control Over Full Feel

Publish gives an option to upload a custom publish.css file, but unfortunately it is up to the user to find the correct CSS classes and reverse engineer them. For example, I added this feature on mobile to be able to swipe to open the sidebar, but I had to inspect the element itself and take a leap of faith that the CSS class I was toggling would control what I hoped. It worked, but the whole thing was honestly a shot in the dark since there is very minimal documentation floating about the web.

// swipe left on mobile to open menu
let touchstartX = 0;
let touchendX = 0;

function checkDirection() {
  // check if greater than 100px
  // if swipe right close menu
    if (touchendX < touchstartX && touchstartX - touchendX > 100) {
    document
        .querySelector(".published-container")
        .classList.remove("is-left-column-open");
    }

  if (touchendX > touchstartX && touchendX - touchstartX > 100) {
    document
      .querySelector(".published-container")
      .classList.add("is-left-column-open");
  }
}

document.addEventListener("touchstart", (e) => {
  touchstartX = e.changedTouches[0].screenX;
});

document.addEventListener("touchend", (e) => {
  touchendX = e.changedTouches[0].screenX;
  checkDirection();
});

There are many other examples like this, but off the top of my head:

  • No control over the way the sidebar displays file order
  • No way to add onClick() events
  • Adding comments and other features is hard due to loading order (onLoad() didn't work since I think Publish is a SPA app?)
  • Hard to anticipate how publish.css/js changes will propagate to mobile
  • Unnecessarily large gutters for content
  • Full Text Search
  • Limited Space (4GB) for everything

Unfortunately all this adds up to a novel (read: kinda weird) UX for both the developer and readers to learn.

I think Zettelkastens across the web would be a lot more popular if SEO was better and they adhered to more mainstream principles.

Gitignore

The "gitignore" feature in Publish is awesome. It makes uploading changed and new files a breeze, as well as deleting them. Unfortunately, this also causes all the files in Obsidian to be tracked, which is pretty annoying.

To combat this, the Obsidian devs added an option to ignore folders/files. This works great…until you locally move the files. Then the whole game starts over again. This is pretty annoying if you uploaded something, changed its path and then need to do the whole upload process from scratch.

Limited Communication Around Updates

With the core team hard at work on the app of Obsidian, I felt at times Publish was passed over as a side offering instead of a main project. As I said earlier in the essay: this is fine if you need an immediate readonly hosted solution. But the second you want to scale the public offer, Publish can no longer provide utility, imo.

You can find more of my thoughts on whether or not Obsidian Publish makes for a remarkable venue here: 202301240135