Published: 03/06/2026

If you just unboxed an M4 MacBook Pro and restored it from an Intel Time Machine backup, your terminal is probably a lie. You’re running a beast of a machine in an “Intel bubble,” and it’s killing your performance.

I spent the afternoon nuking the “Rosetta Ghost” and building a fully local, semantic AI content pipeline. No OpenAI credits. No SaaS subscriptions. Just raw M4 power and slick automation.

Here is exactly how to build it.


1. Purge the “Rosetta Ghost”

Before you install a single AI library, you must ensure your environment is native ARM64. If your uv or python is living in /Library/Frameworks/, it’s likely an Intel-tainted relic.

The Fix: Use Homebrew (ensure it’s in /opt/homebrew) to grab a clean, native stack.

# Check if you're translated (0 = Native)
sysctl -n sysctl.proc_translated

# Install native ARM64 Python and uv
brew install python@3.12 uv

2. The Storage Layer: LanceDB

Forget Docker or heavy database background processes. For a local knowledge brain, you want LanceDB. It’s a serverless, file-based vector store that lives right in your project folder.

import lancedb
from pathlib import Path

DB_DIR = Path("./.lancedb").resolve()
db = lancedb.connect(DB_DIR)
table = db.create_table("my_memory", data=[{"vector": [...], "text": "...", "file": "..."}])

3. Local Embeddings: FastEmbed

Don’t rent your brain from OpenAI. Use FastEmbed from the Qdrant team. It’s lightweight, runs on your CPU, and is optimized for Apple Silicon.

uv add fastembed

The Implementation:

from fastembed import TextEmbedding

model = TextEmbedding()
# This turns text into coordinates locally
embeddings = list(model.embed(["My technical thought here"]))

4. The Real-Time Indexer (The Watcher)

I don’t want to manually index my notes. I want my AI to “hear” me as I write. We built a Python watcher using watchdog that monitors my Markdown folder and updates the LanceDB index the moment I hit save.

from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

class ChangeHandler(FileSystemEventHandler):
    def on_modified(self, event):
        if event.src_path.endswith(".md"):
            index_file(event.src_path) # Your indexing logic here

observer = Observer()
observer.schedule(ChangeHandler(), path="./blog-posts", recursive=True)
observer.start()

5. The Multi-Platform Dispatch

Writing the post is only half the battle. Distribution is the “grind.” Our pipeline automates:

  1. Jekyll Formatting: Automatically injects YAML frontmatter.
  2. Substack Readiness: Uses pandoc to convert Markdown to RTF for easy pasting.
  3. Scheduled Release: Moves posts to a _queue/ folder in Git, where a GitHub Action releases them with a 3-day buffer.

The Verdict

In the “Software 3.0” era, we should be building systems that we own. My content pipeline is now faster, cheaper, and completely sovereign.

Time is short. Stop fighting web editors and start architecting your voice.


Ramblings from an ADHD brain that finally has a pipeline that moves as fast as I do.